Ver Fonte

Improved quotly

TheHamkerCat há 5 anos atrás
pai
commit
74a85af7fc
55 ficheiros alterados com 442 adições e 817 exclusões
  1. 6 10
      sample_config.py
  2. 2 6
      wbb/__init__.py
  3. 10 34
      wbb/__main__.py
  4. 2 5
      wbb/core/decorators/errors.py
  5. 5 15
      wbb/core/decorators/permissions.py
  6. 1 5
      wbb/core/sections.py
  7. 4 13
      wbb/core/types/InlineQueryResult.py
  8. 1 3
      wbb/modules/__init__.py
  9. 39 90
      wbb/modules/admin.py
  10. 1 3
      wbb/modules/admin_misc.py
  11. 1 2
      wbb/modules/alive.py
  12. 1 3
      wbb/modules/anonymize.py
  13. 2 6
      wbb/modules/autocorrect.py
  14. 7 21
      wbb/modules/blacklist.py
  15. 5 15
      wbb/modules/blacklist_chat.py
  16. 5 11
      wbb/modules/chatbot.py
  17. 1 3
      wbb/modules/couple.py
  18. 1 3
      wbb/modules/crypto.py
  19. 2 5
      wbb/modules/devs.py
  20. 1 2
      wbb/modules/download_upload.py
  21. 5 15
      wbb/modules/filters.py
  22. 5 11
      wbb/modules/flood.py
  23. 5 12
      wbb/modules/global_stats.py
  24. 40 44
      wbb/modules/greetings.py
  25. 7 15
      wbb/modules/info.py
  26. 2 6
      wbb/modules/inline.py
  27. 10 24
      wbb/modules/karma.py
  28. 2 6
      wbb/modules/locks.py
  29. 9 19
      wbb/modules/misc.py
  30. 3 9
      wbb/modules/music.py
  31. 10 27
      wbb/modules/notes.py
  32. 80 0
      wbb/modules/parse_preview.py
  33. 4 12
      wbb/modules/paste.py
  34. 7 24
      wbb/modules/pipes.py
  35. 11 31
      wbb/modules/pmpermit.py
  36. 12 16
      wbb/modules/purge_me.py
  37. 9 10
      wbb/modules/quotly.py
  38. 4 11
      wbb/modules/regex.py
  39. 1 4
      wbb/modules/repo.py
  40. 3 9
      wbb/modules/reverse.py
  41. 11 30
      wbb/modules/rice.py
  42. 4 8
      wbb/modules/rss.py
  43. 18 44
      wbb/modules/stickers.py
  44. 3 6
      wbb/modules/sudo.py
  45. 7 16
      wbb/modules/sudoers.py
  46. 3 5
      wbb/modules/taglogger.py
  47. 4 9
      wbb/modules/userbot.py
  48. 1 3
      wbb/modules/webss.py
  49. 24 17
      wbb/utils/dbfunctions.py
  50. 1 3
      wbb/utils/downloader.py
  51. 3 10
      wbb/utils/functions.py
  52. 3 9
      wbb/utils/http.py
  53. 27 76
      wbb/utils/inlinefuncs.py
  54. 5 15
      wbb/utils/misc.py
  55. 2 6
      wbb/utils/stickerset.py

+ 6 - 10
sample_config.py

@@ -2,27 +2,23 @@ from dotenv import load_dotenv
 
 load_dotenv("config.env")
 
-HEROKU = True  # NOTE Make it false if you're not deploying on heroku or docker.
+HEROKU = (
+    True  # NOTE Make it false if you're not deploying on heroku or docker.
+)
 
 if HEROKU:
     from os import environ
 
     BOT_TOKEN = environ.get("BOT_TOKEN", None)
     API_ID = int(environ.get("API_ID", 6))
-    API_HASH = environ.get(
-        "API_HASH", "eb06d4abfb49dc3eeb1aeb98ae0f581e"
-    )
+    API_HASH = environ.get("API_HASH", "eb06d4abfb49dc3eeb1aeb98ae0f581e")
     SESSION_STRING = environ.get("SESSION_STRING", None)
     USERBOT_PREFIX = environ.get("USERBOT_PREFIX", ".")
-    SUDO_USERS_ID = [
-        int(x) for x in environ.get("SUDO_USERS_ID", "").split()
-    ]
+    SUDO_USERS_ID = [int(x) for x in environ.get("SUDO_USERS_ID", "").split()]
     LOG_GROUP_ID = int(environ.get("LOG_GROUP_ID", None))
     GBAN_LOG_GROUP_ID = int(environ.get("GBAN_LOG_GROUP_ID", None))
     MESSAGE_DUMP_CHAT = int(environ.get("MESSAGE_DUMP_CHAT", None))
-    WELCOME_DELAY_KICK_SEC = int(
-        environ.get("WELCOME_DELAY_KICK_SEC", None)
-    )
+    WELCOME_DELAY_KICK_SEC = int(environ.get("WELCOME_DELAY_KICK_SEC", None))
     MONGO_URL = environ.get("MONGO_URL", None)
     ARQ_API_URL = environ.get("ARQ_API_URL", None)
     ARQ_API_KEY = environ.get("ARQ_API_KEY", None)

+ 2 - 6
wbb/__init__.py

@@ -92,9 +92,7 @@ aiohttpsession = ClientSession()
 
 arq = ARQ(ARQ_API_URL, ARQ_API_KEY, aiohttpsession)
 
-app = Client(
-    "wbb", bot_token=BOT_TOKEN, api_id=API_ID, api_hash=API_HASH
-)
+app = Client("wbb", bot_token=BOT_TOKEN, api_id=API_ID, api_hash=API_HASH)
 
 print("[INFO]: STARTING BOT CLIENT")
 app.start()
@@ -124,6 +122,4 @@ if USERBOT_ID not in SUDOERS:
 async def eor(msg: Message, **kwargs):
     func = msg.edit_text if msg.from_user.is_self else msg.reply
     spec = getfullargspec(func.__wrapped__).args
-    return await func(
-        **{k: v for k, v in kwargs.items() if k in spec}
-    )
+    return await func(**{k: v for k, v in kwargs.items() if k in spec})

+ 10 - 34
wbb/__main__.py

@@ -44,9 +44,7 @@ HELPABLE = {}
 async def start_bot():
 
     for module in ALL_MODULES:
-        imported_module = importlib.import_module(
-            "wbb.modules." + module
-        )
+        imported_module = importlib.import_module("wbb.modules." + module)
         if (
             hasattr(imported_module, "__MODULE__")
             and imported_module.__MODULE__
@@ -56,9 +54,7 @@ async def start_bot():
                 hasattr(imported_module, "__HELP__")
                 and imported_module.__HELP__
             ):
-                HELPABLE[
-                    imported_module.__MODULE__.lower()
-                ] = imported_module
+                HELPABLE[imported_module.__MODULE__.lower()] = imported_module
     bot_modules = ""
     j = 1
     for i in ALL_MODULES:
@@ -68,19 +64,11 @@ async def start_bot():
         else:
             bot_modules += "|{:<15}".format(i)
         j += 1
-    print(
-        "+===============================================================+"
-    )
-    print(
-        "|                              WBB                              |"
-    )
-    print(
-        "+===============+===============+===============+===============+"
-    )
+    print("+===============================================================+")
+    print("|                              WBB                              |")
+    print("+===============+===============+===============+===============+")
     print(bot_modules)
-    print(
-        "+===============+===============+===============+===============+"
-    )
+    print("+===============+===============+===============+===============+")
     print(f"[INFO]: BOT STARTED AS {BOT_NAME}!")
     print(f"[INFO]: USERBOT STARTED AS {USERBOT_NAME}!")
 
@@ -179,9 +167,7 @@ async def help_command(_, message):
 
 async def help_parser(name, keyboard=None):
     if not keyboard:
-        keyboard = InlineKeyboardMarkup(
-            paginate_modules(0, HELPABLE, "help")
-        )
+        keyboard = InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help"))
     return (
         """Hello {first_name}, My name is {bot_name}.
 I'm a group management bot with some useful features.
@@ -197,9 +183,7 @@ Also you can ask anything in Support Group.
 
 @app.on_callback_query(filters.regex("bot_commands"))
 async def commands_callbacc(_, CallbackQuery):
-    text, keyboard = await help_parser(
-        CallbackQuery.from_user.mention
-    )
+    text, keyboard = await help_parser(CallbackQuery.from_user.mention)
     await app.send_message(
         CallbackQuery.message.chat.id,
         text=text,
@@ -212,9 +196,7 @@ async def commands_callbacc(_, CallbackQuery):
 @app.on_callback_query(filters.regex("stats_callback"))
 async def stats_callbacc(_, CallbackQuery):
     text = await bot_sys_stats()
-    await app.answer_callback_query(
-        CallbackQuery.id, text, show_alert=True
-    )
+    await app.answer_callback_query(CallbackQuery.id, text, show_alert=True)
 
 
 @app.on_callback_query(filters.regex(r"help_(.*?)"))
@@ -247,13 +229,7 @@ General command are:
         await query.message.edit(
             text=text,
             reply_markup=InlineKeyboardMarkup(
-                [
-                    [
-                        InlineKeyboardButton(
-                            "back", callback_data="help_back"
-                        )
-                    ]
-                ]
+                [[InlineKeyboardButton("back", callback_data="help_back")]]
             ),
             disable_web_page_preview=True,
         )

+ 2 - 5
wbb/core/decorators/errors.py

@@ -4,8 +4,7 @@ import sys
 import traceback
 from functools import wraps
 
-from pyrogram.errors.exceptions.forbidden_403 import \
-    ChatWriteForbidden
+from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
 
 from wbb import LOG_GROUP_ID, app
 
@@ -46,9 +45,7 @@ def capture_err(func):
             )
             error_feedback = split_limits(
                 "**ERROR** | `{}` | `{}`\n\n```{}```\n\n```{}```\n".format(
-                    0
-                    if not message.from_user
-                    else message.from_user.id,
+                    0 if not message.from_user else message.from_user.id,
                     0 if not message.chat else message.chat.id,
                     message.text or message.caption,
                     "".join(errors),

+ 5 - 15
wbb/core/decorators/permissions.py

@@ -24,17 +24,14 @@ SOFTWARE.
 from functools import wraps
 from traceback import format_exc as err
 
-from pyrogram.errors.exceptions.forbidden_403 import \
-    ChatWriteForbidden
+from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
 from pyrogram.types import Message
 
 from wbb import SUDOERS, app
 from wbb.modules.admin import member_permissions
 
 
-async def authorised(
-    func, subFunc2, client, message, *args, **kwargs
-):
+async def authorised(func, subFunc2, client, message, *args, **kwargs):
     chatID = message.chat.id
     try:
         await func(client, message, *args, **kwargs)
@@ -79,19 +76,12 @@ def adminsOnly(permission):
                         *args,
                         **kwargs,
                     )
-                return await unauthorised(
-                    message, permission, subFunc2
-                )
+                return await unauthorised(message, permission, subFunc2)
             # For admins and sudo users
             userID = message.from_user.id
             permissions = await member_permissions(chatID, userID)
-            if (
-                userID not in SUDOERS
-                and permission not in permissions
-            ):
-                return await unauthorised(
-                    message, permission, subFunc2
-                )
+            if userID not in SUDOERS and permission not in permissions:
+                return await unauthorised(message, permission, subFunc2)
             return await authorised(
                 func, subFunc2, client, message, *args, **kwargs
             )

+ 1 - 5
wbb/core/sections.py

@@ -45,10 +45,6 @@ def section(
         text += (
             indent * w
             + bold(key)
-            + (
-                (value[0] + n)
-                if isinstance(value, list)
-                else mono(value)
-            )
+            + ((value[0] + n) if isinstance(value, list) else mono(value))
         )
     return text

+ 4 - 13
wbb/core/types/InlineQueryResult.py

@@ -25,8 +25,7 @@ from typing import List, Optional, Union
 
 import pyrogram
 from pyrogram import raw, types, utils
-from pyrogram.file_id import (DOCUMENT_TYPES, PHOTO_TYPES, FileId,
-                              FileType)
+from pyrogram.file_id import DOCUMENT_TYPES, PHOTO_TYPES, FileId, FileType
 from pyrogram.types import InlineQueryResult
 
 
@@ -98,9 +97,7 @@ class InlineQueryResultAudio(InlineQueryResult):
         reply_markup: "types.InlineKeyboardMarkup" = None,
         input_message_content: "types.InputMessageContent" = None,
     ):
-        super().__init__(
-            "audio", id, input_message_content, reply_markup
-        )
+        super().__init__("audio", id, input_message_content, reply_markup)
 
         self.audio_url = audio_url
         self.thumb_url = thumb_url
@@ -175,7 +172,6 @@ class InlineQueryResultAudio(InlineQueryResult):
         )
 
 
-
 #  CREDITS:
 #       THE CODE BELOW THIS LINE IS WRITTEN BY https://github.com/Mahesh0253. [https://t.me/DeletedUser420]
 #       https://github.com/Mahesh0253/pyrogram/blob/inline/pyrogram/types/inline_mode/inline_query_result_cached_document.py
@@ -232,9 +228,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
         reply_markup: "types.InlineKeyboardMarkup" = None,
         input_message_content: "types.InputMessageContent" = None,
     ):
-        super().__init__(
-            "file", id, input_message_content, reply_markup
-        )
+        super().__init__("file", id, input_message_content, reply_markup)
 
         self.file_id = file_id
         self.title = title
@@ -292,10 +286,7 @@ def get_input_file_from_file_id(
 
     file_type = decoded.file_type
 
-    if (
-        expected_file_type is not None
-        and file_type != expected_file_type
-    ):
+    if expected_file_type is not None and file_type != expected_file_type:
         raise ValueError(
             f'Expected: "{expected_file_type}", got "{file_type}" file_id instead'
         )

+ 1 - 3
wbb/modules/__init__.py

@@ -55,9 +55,7 @@ def __list_all_modules():
             to_load = all_modules
 
         if MOD_NOLOAD:
-            return [
-                item for item in to_load if item not in MOD_NOLOAD
-            ]
+            return [item for item in to_load if item not in MOD_NOLOAD]
 
         return to_load
 

+ 39 - 90
wbb/modules/admin.py

@@ -31,8 +31,7 @@ from wbb.core.decorators.errors import capture_err
 from wbb.core.keyboard import ikb
 from wbb.utils.dbfunctions import (add_warn, get_warn, int_to_alpha,
                                    remove_warns, save_filter)
-from wbb.utils.functions import (extract_user,
-                                 extract_user_and_reason,
+from wbb.utils.functions import (extract_user, extract_user_and_reason,
                                  time_converter)
 
 __MODULE__ = "Admin"
@@ -132,26 +131,19 @@ async def current_chat_permissions(chat_id):
 
 
 async def list_members(group_id):
-    return [
-        member.user.id
-        async for member in app.iter_chat_members(group_id)
-    ]
+    return [member.user.id async for member in app.iter_chat_members(group_id)]
 
 
 # Purge Messages
 
 
-@app.on_message(
-    filters.command("purge") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("purge") & ~filters.edited & ~filters.private)
 @adminsOnly("can_delete_messages")
 async def purgeFunc(_, message: Message):
     await message.delete()
 
     if not message.reply_to_message:
-        return await message.reply_text(
-            "Reply to a message to purge from."
-        )
+        return await message.reply_text("Reply to a message to purge from.")
 
     chat_id = message.chat.id
     message_ids = []
@@ -186,9 +178,7 @@ async def purgeFunc(_, message: Message):
 
 
 @app.on_message(
-    filters.command(["kick", "dkick"])
-    & ~filters.edited
-    & ~filters.private
+    filters.command(["kick", "dkick"]) & ~filters.edited & ~filters.private
 )
 @adminsOnly("can_restrict_members")
 async def kickFunc(_, message: Message):
@@ -200,9 +190,7 @@ async def kickFunc(_, message: Message):
             "I can't kick myself, i can leave if you want."
         )
     if user_id in SUDOERS:
-        return await message.reply_text(
-            "You Wanna Kick The Elevated One?"
-        )
+        return await message.reply_text("You Wanna Kick The Elevated One?")
     if user_id in (await list_admins(message.chat.id)):
         return await message.reply_text(
             "I can't kick an admin, You know the rules, so do i."
@@ -262,9 +250,7 @@ async def banFunc(_, message: Message):
             msg += f"**Reason:** {temp_reason}"
         try:
             if len(time_value[:-1]) < 3:
-                await message.chat.kick_member(
-                    user_id, until_date=temp_ban
-                )
+                await message.chat.kick_member(user_id, until_date=temp_ban)
                 await message.reply_text(msg)
             else:
                 await message.reply_text("You can't use more than 99")
@@ -280,9 +266,7 @@ async def banFunc(_, message: Message):
 # Unban members
 
 
-@app.on_message(
-    filters.command("unban") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("unban") & ~filters.edited & ~filters.private)
 @adminsOnly("can_restrict_members")
 async def unbanFunc(_, message: Message):
     # we don't need reasons for unban, also, we
@@ -304,15 +288,11 @@ async def unbanFunc(_, message: Message):
 # Delete messages
 
 
-@app.on_message(
-    filters.command("del") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("del") & ~filters.edited & ~filters.private)
 @adminsOnly("can_delete_messages")
 async def deleteFunc(_, message: Message):
     if not message.reply_to_message:
-        return await message.reply_text(
-            "Reply To A Message To Delete It"
-        )
+        return await message.reply_text("Reply To A Message To Delete It")
     await message.reply_to_message.delete()
     await message.delete()
 
@@ -321,7 +301,9 @@ async def deleteFunc(_, message: Message):
 
 
 @app.on_message(
-    filters.command(["promote", "fullpromote"]) & ~filters.edited & ~filters.private
+    filters.command(["promote", "fullpromote"])
+    & ~filters.edited
+    & ~filters.private
 )
 @adminsOnly("can_promote_members")
 async def promoteFunc(_, message: Message):
@@ -332,21 +314,19 @@ async def promoteFunc(_, message: Message):
     if user_id == BOT_ID:
         return await message.reply_text("I can't promote myself.")
     if not bot.can_promote_members:
-        return await message.reply_text(
-            "I don't have enough permissions"
-        )
+        return await message.reply_text("I don't have enough permissions")
     if message.command[0][0] == "f":
         await message.chat.promote_member(
-        user_id=user_id,
-        can_change_info=bot.can_change_info,
-        can_invite_users=bot.can_invite_users,
-        can_delete_messages=bot.can_delete_messages,
-        can_restrict_members=bot.can_restrict_members,
-        can_pin_messages=bot.can_pin_messages,
-        can_promote_members=bot.can_promote_members,  
-        can_manage_chat=bot.can_manage_chat,
-        can_manage_voice_chats=bot.can_manage_voice_chats,
-    )
+            user_id=user_id,
+            can_change_info=bot.can_change_info,
+            can_invite_users=bot.can_invite_users,
+            can_delete_messages=bot.can_delete_messages,
+            can_restrict_members=bot.can_restrict_members,
+            can_pin_messages=bot.can_pin_messages,
+            can_promote_members=bot.can_promote_members,
+            can_manage_chat=bot.can_manage_chat,
+            can_manage_voice_chats=bot.can_manage_voice_chats,
+        )
         return await message.reply_text("Promoted! With All Rights")
 
     await message.chat.promote_member(
@@ -366,9 +346,7 @@ async def promoteFunc(_, message: Message):
 # Demote Member
 
 
-@app.on_message(
-    filters.command("demote") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("demote") & ~filters.edited & ~filters.private)
 @adminsOnly("can_promote_members")
 async def demote(_, message: Message):
     user_id = await extract_user(message)
@@ -401,15 +379,11 @@ async def demote(_, message: Message):
 # Pin Messages
 
 
-@app.on_message(
-    filters.command("pin") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("pin") & ~filters.edited & ~filters.private)
 @adminsOnly("can_pin_messages")
 async def pin(_, message: Message):
     if not message.reply_to_message:
-        return await message.reply_text(
-            "Reply to a message to pin it."
-        )
+        return await message.reply_text("Reply to a message to pin it.")
     r = message.reply_to_message
     await r.pin(disable_notification=True)
     await message.reply(
@@ -425,9 +399,7 @@ async def pin(_, message: Message):
 
 
 @app.on_message(
-    filters.command(["mute", "tmute"])
-    & ~filters.edited
-    & ~filters.private
+    filters.command(["mute", "tmute"]) & ~filters.edited & ~filters.private
 )
 @adminsOnly("can_restrict_members")
 async def mute(_, message: Message):
@@ -444,9 +416,7 @@ async def mute(_, message: Message):
         return await message.reply_text(
             "I can't mute an admin, You know the rules, so do i."
         )
-    await message.chat.restrict_member(
-        user_id, permissions=ChatPermissions()
-    )
+    await message.chat.restrict_member(user_id, permissions=ChatPermissions())
     mention = (await app.get_users(user_id)).mention
     keyboard = ikb({"🚨   Unmute   🚨": f"unmute_{user_id}"})
     msg = (
@@ -476,18 +446,14 @@ async def mute(_, message: Message):
         return
     if reason:
         msg += f"**Reason:** {reason}"
-    await message.chat.restrict_member(
-        user_id, permissions=ChatPermissions()
-    )
+    await message.chat.restrict_member(user_id, permissions=ChatPermissions())
     await message.reply_text(msg, reply_markup=keyboard)
 
 
 # Unmute members
 
 
-@app.on_message(
-    filters.command("unmute") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("unmute") & ~filters.edited & ~filters.private)
 @adminsOnly("can_restrict_members")
 async def unmute(_, message: Message):
     user_id = await extract_user(message)
@@ -516,19 +482,13 @@ async def ban_deleted_accounts(_, message: Message):
             except Exception:
                 pass
             banned_users += 1
-        await message.reply_text(
-            f"Banned {banned_users} Deleted Accounts"
-        )
+        await message.reply_text(f"Banned {banned_users} Deleted Accounts")
     else:
-        await message.reply_text(
-            "There are no deleted accounts in this chat"
-        )
+        await message.reply_text("There are no deleted accounts in this chat")
 
 
 @app.on_message(
-    filters.command(["warn", "dwarn"])
-    & ~filters.edited
-    & ~filters.private
+    filters.command(["warn", "dwarn"]) & ~filters.edited & ~filters.private
 )
 @adminsOnly("can_restrict_members")
 async def warn_user(_, message: Message):
@@ -633,44 +593,33 @@ async def remove_warnings(_, message: Message):
 # Warns
 
 
-@app.on_message(
-    filters.command("warns") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("warns") & ~filters.edited & ~filters.private)
 @capture_err
 async def check_warns(_, message: Message):
     user_id = await extract_user(message)
     if not user_id:
         return await message.reply_text("I can't find that user.")
-    warns = await get_warn(
-        message.chat.id, await int_to_alpha(user_id)
-    )
+    warns = await get_warn(message.chat.id, await int_to_alpha(user_id))
     mention = (await app.get_users(user_id)).mention
     if warns:
         warns = warns["warns"]
     else:
         return await message.reply_text(f"{mention} has no warnings.")
-    return await message.reply_text(
-        f"{mention} has {warns}/3 warnings."
-    )
+    return await message.reply_text(f"{mention} has {warns}/3 warnings.")
 
 
 # Report
 
 
 @app.on_message(
-    (
-        filters.command("report")
-        | filters.command("admins", prefixes="@")
-    )
+    (filters.command("report") | filters.command("admins", prefixes="@"))
     & ~filters.edited
     & ~filters.private
 )
 @capture_err
 async def report_user(_, message):
     if not message.reply_to_message:
-        return await message.reply_text(
-            "Reply to a message to report user."
-        )
+        return await message.reply_text("Reply to a message to report user.")
     list_of_admins = await list_admins(message.chat.id)
     user_mention = message.reply_to_message.from_user.mention
     text = f"Reported {user_mention} to admins."

+ 1 - 3
wbb/modules/admin_misc.py

@@ -40,9 +40,7 @@ __HELP__ = """
 @adminsOnly("can_change_info")
 async def set_chat_title(_, message):
     if len(message.command) < 2:
-        return await message.reply_text(
-            "**Usage:**\n/set_chat_title NEW NAME"
-        )
+        return await message.reply_text("**Usage:**\n/set_chat_title NEW NAME")
     old_title = message.chat.title
     new_title = message.text.split(None, 1)[1]
     await message.chat.set_title(new_title)

+ 1 - 2
wbb/modules/alive.py

@@ -28,8 +28,7 @@ from wbb import BOT_ID, SUDOERS, USERBOT_PREFIX, app2
 
 
 @app2.on_message(
-    filters.command("alive", prefixes=USERBOT_PREFIX)
-    & filters.user(SUDOERS)
+    filters.command("alive", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
 )
 async def alive_command_func(_, message):
     await message.delete()

+ 1 - 3
wbb/modules/anonymize.py

@@ -75,9 +75,7 @@ async def impersonate(_, message: Message):
     user_id = await extract_user(message)
 
     if not user_id:
-        return await eor(
-            message, text="Can't impersonate an anonymous user."
-        )
+        return await eor(message, text="Can't impersonate an anonymous user.")
     if user_id == USERBOT_ID:
         return eor(message, text="Can't impersonate myself.")
 

+ 2 - 6
wbb/modules/autocorrect.py

@@ -17,9 +17,7 @@ async def autocorrect_bot(_, message: Message):
     if not data.ok:
         return await message.reply_text("Something wrong happened.")
     result = data.result
-    await message.reply_text(
-        result.corrected if result.corrected else "Empty"
-    )
+    await message.reply_text(result.corrected if result.corrected else "Empty")
 
 
 IS_ENABLED = False
@@ -41,9 +39,7 @@ async def autocorrect_ubot_toggle(_, message: Message):
         IS_ENABLED = False
         await message.edit("Disabled!")
     else:
-        return await message.edit(
-            "Wrong argument, Pass (ENABLE|DISABLE)."
-        )
+        return await message.edit("Wrong argument, Pass (ENABLE|DISABLE).")
 
 
 @app2.on_message(

+ 7 - 21
wbb/modules/blacklist.py

@@ -49,9 +49,7 @@ __HELP__ = """
 @adminsOnly("can_restrict_members")
 async def save_filters(_, message):
     if len(message.command) < 2:
-        return await message.reply_text(
-            "Usage:\n/blacklist [WORD|SENTENCE]"
-        )
+        return await message.reply_text("Usage:\n/blacklist [WORD|SENTENCE]")
     word = message.text.split(None, 1)[1].strip()
     if not word:
         return await message.reply_text(
@@ -63,17 +61,13 @@ async def save_filters(_, message):
 
 
 @app.on_message(
-    filters.command("blacklisted")
-    & ~filters.edited
-    & ~filters.private
+    filters.command("blacklisted") & ~filters.edited & ~filters.private
 )
 @capture_err
 async def get_filterss(_, message):
     data = await get_blacklisted_words(message.chat.id)
     if not data:
-        await message.reply_text(
-            "**No blacklisted words in this chat.**"
-        )
+        await message.reply_text("**No blacklisted words in this chat.**")
     else:
         msg = f"List of blacklisted words in {message.chat.title}\n"
         for word in data:
@@ -87,14 +81,10 @@ async def get_filterss(_, message):
 @adminsOnly("can_restrict_members")
 async def del_filter(_, message):
     if len(message.command) < 2:
-        return await message.reply_text(
-            "Usage:\n/whitelist [WORD|SENTENCE]"
-        )
+        return await message.reply_text("Usage:\n/whitelist [WORD|SENTENCE]")
     word = message.text.split(None, 1)[1].strip()
     if not word:
-        return await message.reply_text(
-            "Usage:\n/whitelist [WORD|SENTENCE]"
-        )
+        return await message.reply_text("Usage:\n/whitelist [WORD|SENTENCE]")
     chat_id = message.chat.id
     deleted = await delete_blacklist_filter(chat_id, word)
     if deleted:
@@ -102,9 +92,7 @@ async def del_filter(_, message):
     await message.reply_text("**No such blacklist filter.**")
 
 
-@app.on_message(
-    filters.text & ~filters.private, group=blacklist_filters_group
-)
+@app.on_message(filters.text & ~filters.private, group=blacklist_filters_group)
 @capture_err
 async def blacklist_filters_re(_, message):
     text = message.text.lower().strip()
@@ -123,9 +111,7 @@ async def blacklist_filters_re(_, message):
             if user.id in await list_admins(chat_id):
                 return
             try:
-                await message.chat.restrict_member(
-                    user.id, ChatPermissions()
-                )
+                await message.chat.restrict_member(user.id, ChatPermissions())
             except Exception:
                 return
             await app.send_message(

+ 5 - 15
wbb/modules/blacklist_chat.py

@@ -19,9 +19,7 @@ in which you don't want it to be in.
 """
 
 
-@app.on_message(
-    filters.command("blacklist_chat") & filters.user(SUDOERS)
-)
+@app.on_message(filters.command("blacklist_chat") & filters.user(SUDOERS))
 @capture_err
 async def blacklist_chat_func(_, message: Message):
     if len(message.command) != 2:
@@ -30,9 +28,7 @@ async def blacklist_chat_func(_, message: Message):
         )
     chat_id = int(message.text.strip().split()[1])
     if chat_id in await blacklisted_chats():
-        return await message.reply_text(
-            "Chat is already blacklisted."
-        )
+        return await message.reply_text("Chat is already blacklisted.")
     blacklisted = await blacklist_chat(chat_id)
     if blacklisted:
         return await message.reply_text(
@@ -41,9 +37,7 @@ async def blacklist_chat_func(_, message: Message):
     await message.reply_text("Something wrong happened, check logs.")
 
 
-@app.on_message(
-    filters.command("whitelist_chat") & filters.user(SUDOERS)
-)
+@app.on_message(filters.command("whitelist_chat") & filters.user(SUDOERS))
 @capture_err
 async def whitelist_chat_func(_, message: Message):
     if len(message.command) != 2:
@@ -52,9 +46,7 @@ async def whitelist_chat_func(_, message: Message):
         )
     chat_id = int(message.text.strip().split()[1])
     if chat_id not in await blacklisted_chats():
-        return await message.reply_text(
-            "Chat is already whitelisted."
-        )
+        return await message.reply_text("Chat is already whitelisted.")
     whitelisted = await whitelist_chat(chat_id)
     if whitelisted:
         return await message.reply_text(
@@ -63,9 +55,7 @@ async def whitelist_chat_func(_, message: Message):
     await message.reply_text("Something wrong happened, check logs.")
 
 
-@app.on_message(
-    filters.command("blacklisted_chats") & filters.user(SUDOERS)
-)
+@app.on_message(filters.command("blacklisted_chats") & filters.user(SUDOERS))
 @capture_err
 async def blacklisted_chats_func(_, message: Message):
     text = ""

+ 5 - 11
wbb/modules/chatbot.py

@@ -26,8 +26,8 @@ from asyncio import gather, sleep
 from pyrogram import filters
 from pyrogram.types import Message
 
-from wbb import (BOT_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX,
-                 USERBOT_USERNAME, app, app2, arq, eor)
+from wbb import (BOT_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX, USERBOT_USERNAME,
+                 app, app2, arq, eor)
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.filter_groups import chatbot_group
 
@@ -57,9 +57,7 @@ async def chat_bot_toggle(db, message: Message):
             return await eor(message, text="Chatbot Disabled!")
         await eor(message, text="ChatBot Is Already Disabled.")
     else:
-        await eor(
-            message, text="**Usage:**\n/chatbot [ENABLE|DISABLE]"
-        )
+        await eor(message, text="**Usage:**\n/chatbot [ENABLE|DISABLE]")
 
 
 # Enabled | Disable Chatbot
@@ -69,9 +67,7 @@ async def chat_bot_toggle(db, message: Message):
 @capture_err
 async def chatbot_status(_, message: Message):
     if len(message.command) != 2:
-        return await eor(
-            message, text="**Usage:**\n/chatbot [ENABLE|DISABLE]"
-        )
+        return await eor(message, text="**Usage:**\n/chatbot [ENABLE|DISABLE]")
     await chat_bot_toggle(active_chats_bot, message)
 
 
@@ -122,9 +118,7 @@ async def chatbot_talk(_, message: Message):
 @capture_err
 async def chatbot_status_ubot(_, message: Message):
     if len(message.text.split()) != 2:
-        return await eor(
-            message, text="**Usage:**\n.chatbot [ENABLE|DISABLE]"
-        )
+        return await eor(message, text="**Usage:**\n.chatbot [ENABLE|DISABLE]")
     await chat_bot_toggle(active_chats_ubot, message)
 
 

+ 1 - 3
wbb/modules/couple.py

@@ -61,9 +61,7 @@ tomorrow = str(dt_tom())
 @capture_err
 async def couple(_, message):
     if message.chat.type == "private":
-        return await message.reply_text(
-            "This command only works in groups."
-        )
+        return await message.reply_text("This command only works in groups.")
     try:
         chat_id = message.chat.id
         is_selected = await get_couple(chat_id, today)

+ 1 - 3
wbb/modules/crypto.py

@@ -22,9 +22,7 @@ async def crypto(_, message):
     currency = message.text.split(None, 1)[1].lower()
 
     btn = ikb(
-        {
-            "Available Currencies": "https://plotcryptoprice.herokuapp.com"
-        },
+        {"Available Currencies": "https://plotcryptoprice.herokuapp.com"},
     )
 
     m = await message.reply("`Processing...`")

+ 2 - 5
wbb/modules/devs.py

@@ -14,8 +14,7 @@ from io import StringIO
 from time import time
 
 from pyrogram import filters
-from pyrogram.types import (InlineKeyboardButton,
-                            InlineKeyboardMarkup, Message)
+from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
 
 from wbb import SUDOERS, app, eor
 
@@ -125,9 +124,7 @@ async def shellrunner(_, message: Message):
         code = text.split("\n")
         output = ""
         for x in code:
-            shell = re.split(
-                """ (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x
-            )
+            shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x)
             try:
                 process = subprocess.Popen(
                     shell,

+ 1 - 2
wbb/modules/download_upload.py

@@ -107,8 +107,7 @@ async def download_func(_, message: Message):
 
 
 @app2.on_message(
-    filters.user(SUDOERS)
-    & filters.command("upload", prefixes=USERBOT_PREFIX)
+    filters.user(SUDOERS) & filters.command("upload", prefixes=USERBOT_PREFIX)
 )
 async def upload_func(_, message: Message):
     if len(message.text.split()) != 2:

+ 5 - 15
wbb/modules/filters.py

@@ -43,9 +43,7 @@ __HELP__ = """/filters To Get All The Filters In The Chat.
 You can use markdown or html to save text too."""
 
 
-@app.on_message(
-    filters.command("filter") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("filter") & ~filters.edited & ~filters.private)
 @adminsOnly("can_change_info")
 async def save_filters(_, message):
     if len(message.command) < 2 or not message.reply_to_message:
@@ -83,9 +81,7 @@ async def save_filters(_, message):
 async def get_filterss(_, message):
     _filters = await get_filters_names(message.chat.id)
     if not _filters:
-        return await message.reply_text(
-            "**No filters in this chat.**"
-        )
+        return await message.reply_text("**No filters in this chat.**")
     _filters.sort()
     msg = f"List of filters in {message.chat.title}\n"
     for _filter in _filters:
@@ -93,20 +89,14 @@ async def get_filterss(_, message):
     await message.reply_text(msg)
 
 
-@app.on_message(
-    filters.command("stop") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("stop") & ~filters.edited & ~filters.private)
 @adminsOnly("can_change_info")
 async def del_filter(_, message):
     if len(message.command) < 2:
-        return await message.reply_text(
-            "**Usage:**\n__/stop [FILTER_NAME]__"
-        )
+        return await message.reply_text("**Usage:**\n__/stop [FILTER_NAME]__")
     name = message.text.split(None, 1)[1].strip()
     if not name:
-        return await message.reply_text(
-            "**Usage:**\n__/stop [FILTER_NAME]__"
-        )
+        return await message.reply_text("**Usage:**\n__/stop [FILTER_NAME]__")
     chat_id = message.chat.id
     deleted = await delete_filter(chat_id, name)
     if deleted:

+ 5 - 11
wbb/modules/flood.py

@@ -26,8 +26,8 @@ from time import time
 
 from pyrogram import filters
 from pyrogram.types import (CallbackQuery, ChatPermissions,
-                            InlineKeyboardButton,
-                            InlineKeyboardMarkup, Message)
+                            InlineKeyboardButton, InlineKeyboardMarkup,
+                            Message)
 
 from wbb import SUDOERS, app
 from wbb.core.decorators.errors import capture_err
@@ -132,9 +132,7 @@ async def flood_control_func(_, message: Message):
 @app.on_callback_query(filters.regex("unmute_"))
 async def flood_callback_func(_, cq: CallbackQuery):
     from_user = cq.from_user
-    permissions = await member_permissions(
-        cq.message.chat.id, from_user.id
-    )
+    permissions = await member_permissions(cq.message.chat.id, from_user.id)
     permission = "can_restrict_members"
     if permission not in permissions:
         return await cq.answer(
@@ -154,9 +152,7 @@ async def flood_callback_func(_, cq: CallbackQuery):
 @adminsOnly("can_change_info")
 async def flood_toggle(_, message: Message):
     if len(message.command) != 2:
-        return await message.reply_text(
-            "Usage: /flood [ENABLE|DISABLE]"
-        )
+        return await message.reply_text("Usage: /flood [ENABLE|DISABLE]")
     status = message.text.split(None, 1)[1].strip()
     status = status.lower()
     chat_id = message.chat.id
@@ -167,6 +163,4 @@ async def flood_toggle(_, message: Message):
         await flood_off(chat_id)
         await message.reply_text("Disabled Flood Checker.")
     else:
-        await message.reply_text(
-            "Unknown Suffix, Use /flood [ENABLE|DISABLE]"
-        )
+        await message.reply_text("Unknown Suffix, Use /flood [ENABLE|DISABLE]")

+ 5 - 12
wbb/modules/global_stats.py

@@ -32,24 +32,19 @@ from wbb.modules import ALL_MODULES
 from wbb.utils.dbfunctions import (get_blacklist_filters_count,
                                    get_filters_count, get_gbans_count,
                                    get_karmas_count, get_notes_count,
-                                   get_rss_feeds_count,
-                                   get_served_chats, get_served_users,
-                                   get_warns_count,
+                                   get_rss_feeds_count, get_served_chats,
+                                   get_served_users, get_warns_count,
                                    remove_served_chat)
 from wbb.utils.http import get
 from wbb.utils.inlinefuncs import keywords_list
 
 
 @app.on_message(
-    filters.command("clean_db")
-    & filters.user(SUDOERS)
-    & ~filters.edited
+    filters.command("clean_db") & filters.user(SUDOERS) & ~filters.edited
 )
 @capture_err
 async def clean_db(_, message):
-    served_chats = [
-        int(i["chat_id"]) for i in (await get_served_chats())
-    ]
+    served_chats = [int(i["chat_id"]) for i in (await get_served_chats())]
     m = await message.reply(
         f"__**Cleaning database, Might take around {len(served_chats)*2} seconds.**__",
     )
@@ -68,9 +63,7 @@ async def clean_db(_, message):
 
 
 @app.on_message(
-    filters.command("gstats")
-    & filters.user(SUDOERS)
-    & ~filters.edited
+    filters.command("gstats") & filters.user(SUDOERS) & ~filters.edited
 )
 @capture_err
 async def global_stats(_, message):

+ 40 - 44
wbb/modules/greetings.py

@@ -28,24 +28,22 @@ from datetime import datetime
 from random import shuffle
 
 from pyrogram import filters
-from pyrogram.errors.exceptions.bad_request_400 import (
-    ChatAdminRequired, UserNotParticipant)
-from pyrogram.types import (Chat, ChatPermissions,
-                            InlineKeyboardButton,
+from pyrogram.errors.exceptions.bad_request_400 import (ChatAdminRequired,
+                                                        UserNotParticipant)
+from pyrogram.types import (Chat, ChatPermissions, InlineKeyboardButton,
                             InlineKeyboardMarkup, Message, User)
 
 from wbb import SUDOERS, WELCOME_DELAY_KICK_SEC, app
 from wbb.core.decorators.errors import capture_err
 from wbb.core.decorators.permissions import adminsOnly
 from wbb.core.keyboard import ikb
-from wbb.utils.dbfunctions import (captcha_off, captcha_on,
-                                   del_welcome, get_captcha_cache,
-                                   get_welcome, is_captcha_on,
-                                   is_gbanned_user, set_welcome,
-                                   update_captcha_cache)
+from wbb.utils.dbfunctions import (captcha_off, captcha_on, del_welcome,
+                                   get_captcha_cache, get_welcome,
+                                   has_solved_captcha_once, is_captcha_on,
+                                   is_gbanned_user, save_captcha_solved,
+                                   set_welcome, update_captcha_cache)
 from wbb.utils.filter_groups import welcome_captcha_group
-from wbb.utils.functions import (extract_text_and_keyb,
-                                 generate_captcha)
+from wbb.utils.functions import extract_text_and_keyb, generate_captcha
 
 __MODULE__ = "Greetings"
 __HELP__ = """
@@ -95,18 +93,20 @@ loop.create_task(get_initial_captcha_cache())
 @capture_err
 async def welcome(_, message: Message):
     global answers_dicc
-    
+
     # Get cached answers from mongodb in case of bot's been restarted or crashed.
     answers_dicc = await get_captcha_cache()
-    
+
     # Mute new member and send message with button
     if not await is_captcha_on(message.chat.id):
         return
-    
+
     for member in message.new_chat_members:
         try:
+
             if member.id in SUDOERS:
-                continue  # ignore sudos
+                continue  # ignore sudo users
+
             if await is_gbanned_user(member.id):
                 await message.chat.kick_member(member.id)
                 await message.reply_text(
@@ -115,14 +115,20 @@ async def welcome(_, message: Message):
                     + " for this ban in support chat."
                 )
                 continue
+
             if member.is_bot:
                 continue  # ignore bots
-            await message.chat.restrict_member(
-                member.id, ChatPermissions()
-            )
+
+            # Ignore user if he has already solved captcha in this group
+            # someday
+            if await has_solved_captcha_once(message.chat.id, member.id):
+                continue
+
+            await message.chat.restrict_member(member.id, ChatPermissions())
             text = (
                 f"{(member.mention())} Are you human?\n"
-                f"Solve this captcha in {WELCOME_DELAY_KICK_SEC} seconds and 4 attempts or you'll be kicked."
+                f"Solve this captcha in {WELCOME_DELAY_KICK_SEC} "
+                "seconds and 4 attempts or you'll be kicked."
             )
         except ChatAdminRequired:
             return
@@ -181,7 +187,7 @@ async def welcome(_, message: Message):
             quote=True,
         )
         os.remove(captcha_image)
-        
+
         # Save captcha answers etc in mongodb in case bot gets crashed or restarted.
         await update_captcha_cache(answers_dicc)
 
@@ -204,9 +210,7 @@ async def send_welcome_message(chat: Chat, user_id: int):
     if "{chat}" in text:
         text = text.replace("{chat}", chat.title)
     if "{name}" in text:
-        text = text.replace(
-            "{name}", (await app.get_users(user_id)).mention
-        )
+        text = text.replace("{name}", (await app.get_users(user_id)).mention)
 
     await app.send_message(
         chat.id,
@@ -250,13 +254,9 @@ async def callback_query_welcome_button(_, callback_query):
                 attempts = iii["attempts"]
                 if attempts >= 3:
                     answers_dicc.remove(iii)
-                    await button_message.chat.kick_member(
-                        pending_user_id
-                    )
+                    await button_message.chat.kick_member(pending_user_id)
                     await asyncio.sleep(1)
-                    await button_message.chat.unban_member(
-                        pending_user_id
-                    )
+                    await button_message.chat.unban_member(pending_user_id)
                     await button_message.delete()
                     await update_captcha_cache(answers_dicc)
                     return
@@ -287,9 +287,13 @@ async def callback_query_welcome_button(_, callback_query):
                 answers_dicc.remove(ii)
                 await update_captcha_cache(answers_dicc)
 
-    return await send_welcome_message(
-        callback_query.message.chat, pending_user_id
-    )
+    chat = callback_query.message.chat
+
+    # Save this verification in db, so we don't have to
+    # send captcha to this user when he joins again.
+    await save_captcha_solved(chat.id, pending_user_id)
+
+    return await send_welcome_message(chat, pending_user_id)
 
 
 async def kick_restricted_after_delay(
@@ -310,9 +314,7 @@ async def kick_restricted_after_delay(
             if i["user_id"] == user_id:
                 answers_dicc.remove(i)
                 await update_captcha_cache(answers_dicc)
-    await _ban_restricted_user_until_date(
-        group_chat, user_id, duration=delay
-    )
+    await _ban_restricted_user_until_date(group_chat, user_id, duration=delay)
 
 
 async def _ban_restricted_user_until_date(
@@ -322,9 +324,7 @@ async def _ban_restricted_user_until_date(
         member = await group_chat.get_member(user_id)
         if member.status == "restricted":
             until_date = int(datetime.utcnow().timestamp() + duration)
-            await group_chat.kick_member(
-                user_id, until_date=until_date
-            )
+            await group_chat.kick_member(user_id, until_date=until_date)
     except UserNotParticipant:
         pass
 
@@ -365,13 +365,9 @@ async def set_welcome_func(_, message):
     chat_id = message.chat.id
     raw_text = message.reply_to_message.text.markdown
     if not (extract_text_and_keyb(ikb, raw_text)):
-        return await message.reply_text(
-            "Wrong formating, check help section."
-        )
+        return await message.reply_text("Wrong formating, check help section.")
     await set_welcome(chat_id, raw_text)
-    await message.reply_text(
-        "Welcome message has been successfully set."
-    )
+    await message.reply_text("Welcome message has been successfully set.")
 
 
 @app.on_message(filters.command("del_welcome") & ~filters.private)

+ 7 - 15
wbb/modules/info.py

@@ -55,7 +55,7 @@ async def get_user_info(user, already=False):
         "ID": user_id,
         "DC": dc_id,
         "Name": [first_name],
-        "Username": [("@" + username) if username else None],
+        "Username": [("@" + username) if username else "Null"],
         "Mention": [mention],
         "Sudo": is_sudo,
         "Karma": karma,
@@ -76,7 +76,7 @@ async def get_chat_info(chat, already=False):
     description = chat.description
     members = chat.members_count
     is_restricted = chat.is_restricted
-    link = f"[Link](t.me/{username})" if username else None
+    link = f"[Link](t.me/{username})" if username else "Null"
     dc_id = chat.dc_id
     photo_id = chat.photo.big_file_id if chat.photo else None
     body = {
@@ -84,7 +84,7 @@ async def get_chat_info(chat, already=False):
         "DC": dc_id,
         "Type": type_,
         "Name": [title],
-        "Username": [("@" + username) if username else None],
+        "Username": [("@" + username) if username else "Null"],
         "Mention": [link],
         "Members": members,
         "Scam": is_scam,
@@ -112,14 +112,10 @@ async def info_func(_, message: Message):
         return await m.edit(str(e))
 
     if not photo_id:
-        return await m.edit(
-            info_caption, disable_web_page_preview=True
-        )
+        return await m.edit(info_caption, disable_web_page_preview=True)
     photo = await app.download_media(photo_id)
 
-    await message.reply_photo(
-        photo, caption=info_caption, quote=False
-    )
+    await message.reply_photo(photo, caption=info_caption, quote=False)
     await m.delete()
     os.remove(photo)
 
@@ -141,14 +137,10 @@ async def chat_info_func(_, message: Message):
 
         info_caption, photo_id = await get_chat_info(chat)
         if not photo_id:
-            return await m.edit(
-                info_caption, disable_web_page_preview=True
-            )
+            return await m.edit(info_caption, disable_web_page_preview=True)
 
         photo = await app.download_media(photo_id)
-        await message.reply_photo(
-            photo, caption=info_caption, quote=False
-        )
+        await message.reply_photo(photo, caption=info_caption, quote=False)
 
         await m.delete()
         os.remove(photo)

+ 2 - 6
wbb/modules/inline.py

@@ -131,9 +131,7 @@ async def inline_query_handler(client, query):
                 )
             tex = text.split(None, 1)[1].strip()
             answerss = await youtube_func(answers, tex)
-            await client.answer_inline_query(
-                query.id, results=answerss
-            )
+            await client.answer_inline_query(query.id, results=answerss)
 
         elif text.split()[0] == "lyrics":
             if len(text.split()) < 2:
@@ -145,9 +143,7 @@ async def inline_query_handler(client, query):
                 )
             tex = text.split(None, 1)[1].strip()
             answerss = await lyrics_func(answers, tex)
-            await client.answer_inline_query(
-                query.id, results=answerss
-            )
+            await client.answer_inline_query(query.id, results=answerss)
 
         elif text.split()[0] == "search":
             if len(text.split()) < 2:

+ 10 - 24
wbb/modules/karma.py

@@ -29,12 +29,10 @@ from wbb import app
 from wbb.core.decorators.errors import capture_err
 from wbb.core.decorators.permissions import adminsOnly
 from wbb.core.sections import section
-from wbb.utils.dbfunctions import (alpha_to_int, get_karma,
-                                   get_karmas, int_to_alpha,
-                                   is_karma_on, karma_off, karma_on,
-                                   update_karma)
-from wbb.utils.filter_groups import (karma_negative_group,
-                                     karma_positive_group)
+from wbb.utils.dbfunctions import (alpha_to_int, get_karma, get_karmas,
+                                   int_to_alpha, is_karma_on, karma_off,
+                                   karma_on, update_karma)
+from wbb.utils.filter_groups import karma_negative_group, karma_positive_group
 from wbb.utils.functions import get_user_id_and_usernames
 
 __MODULE__ = "Karma"
@@ -73,22 +71,16 @@ async def upvote(_, message):
     chat_id = message.chat.id
     user_id = message.reply_to_message.from_user.id
     user_mention = message.reply_to_message.from_user.mention
-    current_karma = await get_karma(
-        chat_id, await int_to_alpha(user_id)
-    )
+    current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
     if current_karma:
         current_karma = current_karma["karma"]
         karma = current_karma + 1
         new_karma = {"karma": karma}
-        await update_karma(
-            chat_id, await int_to_alpha(user_id), new_karma
-        )
+        await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
     else:
         karma = 1
         new_karma = {"karma": karma}
-        await update_karma(
-            chat_id, await int_to_alpha(user_id), new_karma
-        )
+        await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
     await message.reply_text(
         f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
     )
@@ -119,22 +111,16 @@ async def downvote(_, message):
     chat_id = message.chat.id
     user_id = message.reply_to_message.from_user.id
     user_mention = message.reply_to_message.from_user.mention
-    current_karma = await get_karma(
-        chat_id, await int_to_alpha(user_id)
-    )
+    current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
     if current_karma:
         current_karma = current_karma["karma"]
         karma = current_karma - 1
         new_karma = {"karma": karma}
-        await update_karma(
-            chat_id, await int_to_alpha(user_id), new_karma
-        )
+        await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
     else:
         karma = 1
         new_karma = {"karma": karma}
-        await update_karma(
-            chat_id, await int_to_alpha(user_id), new_karma
-        )
+        await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
     await message.reply_text(
         f"Decremented Karma Of {user_mention} By 1 \nTotal Points: {karma}"
     )

+ 2 - 6
wbb/modules/locks.py

@@ -46,9 +46,7 @@ Example:
     /lock all
 """
 
-incorrect_parameters = (
-    "Incorrect Parameters, Check Locks Section In Help."
-)
+incorrect_parameters = "Incorrect Parameters, Check Locks Section In Help."
 # Using disable_preview as a switch for url checker
 # That way we won't need an additional db to check
 # If url lock is enabled/disabled for a chat
@@ -91,9 +89,7 @@ async def tg_lock(message, permissions: list, perm: str, lock: bool):
     await message.reply_text(("Locked." if lock else "Unlocked."))
 
 
-@app.on_message(
-    filters.command(["lock", "unlock"]) & ~filters.private
-)
+@app.on_message(filters.command(["lock", "unlock"]) & ~filters.private)
 @adminsOnly("can_restrict_members")
 async def locks_func(_, message):
     if len(message.command) != 2:

+ 9 - 19
wbb/modules/misc.py

@@ -107,9 +107,7 @@ async def asq(_, message):
 
 @app.on_message(filters.command("commit") & ~filters.edited)
 async def commit(_, message):
-    await message.reply_text(
-        await get("http://whatthecommit.com/index.txt")
-    )
+    await message.reply_text(await get("http://whatthecommit.com/index.txt"))
 
 
 @app.on_message(filters.command("RTFM", "#"))
@@ -124,9 +122,7 @@ async def rtfm(_, message):
 
 @app.on_message(filters.command("runs") & ~filters.edited)
 async def runs(_, message):
-    await message.reply_text(
-        (await random_line("wbb/utils/runs.txt"))
-    )
+    await message.reply_text((await random_line("wbb/utils/runs.txt")))
 
 
 @app.on_message(filters.command("id"))
@@ -143,12 +139,12 @@ async def getid(_, message):
             user_id = (await app.get_users(split)).id
             text += f"**[User ID:](tg://user?id={user_id})** `{user_id}`\n"
         except Exception:
-            return await message.reply_text(
-                "This user doesn't exist."
-            )
+            return await message.reply_text("This user doesn't exist.")
     text += f"**[Chat ID:](https://t.me/{chat.username})** `{chat.id}`\n\n"
     if not getattr(reply, "empty", True):
-        text += f"**[Replied Message ID:]({reply.link})** `{reply.message_id}`\n"
+        text += (
+            f"**[Replied Message ID:]({reply.link})** `{reply.message_id}`\n"
+        )
         text += f"**[Replied User ID:](tg://user?id={reply.from_user.id})** `{reply.from_user.id}`"
     await message.reply_text(
         text, disable_web_page_preview=True, parse_mode="md"
@@ -172,9 +168,7 @@ async def random(_, message):
             )
             await message.reply_text(f"`{password}`")
         else:
-            await message.reply_text(
-                "Specify A Length Between 1-1000"
-            )
+            await message.reply_text("Specify A Length Between 1-1000")
     except ValueError:
         await message.reply_text(
             "Strings Won't Work!, Pass A Positive Integer Less Than 1000"
@@ -198,9 +192,7 @@ async def tr(_, message):
     reply = message.reply_to_message
     text = reply.text or reply.caption
     if not text:
-        return await message.reply_text(
-            "Reply to a text to translate it"
-        )
+        return await message.reply_text("Reply to a text to translate it")
     result = await arq.translate(text, lang)
     if not result.ok:
         return await message.reply_text(result.result)
@@ -233,9 +225,7 @@ async def json_fetch(_, message):
 @capture_err
 async def take_ss(_, message):
     if len(message.command) != 2:
-        return await message.reply_text(
-            "Give A Url To Fetch Screenshot."
-        )
+        return await message.reply_text("Give A Url To Fetch Screenshot.")
     url = message.text.split(None, 1)[1]
     m = await message.reply_text("**Uploading**")
     try:

+ 3 - 9
wbb/modules/music.py

@@ -79,9 +79,7 @@ def download_youtube_audio(url: str):
             audio_file = audio_file_opus
         thumbnail_url = info_dict["thumbnail"]
         thumbnail_file = (
-            basename
-            + "."
-            + get_file_extension_from_url(thumbnail_url)
+            basename + "." + get_file_extension_from_url(thumbnail_url)
         )
         title = info_dict["title"]
         performer = info_dict["uploader"]
@@ -94,9 +92,7 @@ def download_youtube_audio(url: str):
 async def music(_, message):
     global is_downloading
     if len(message.command) != 2:
-        return await message.reply_text(
-            "/ytmusic needs a link as argument"
-        )
+        return await message.reply_text("/ytmusic needs a link as argument")
     url = message.text.split(None, 1)[1]
     if is_downloading:
         return await message.reply_text(
@@ -153,9 +149,7 @@ async def download_song(url):
 async def jssong(_, message):
     global is_downloading
     if len(message.command) < 2:
-        return await message.reply_text(
-            "/saavn requires an argument."
-        )
+        return await message.reply_text("/saavn requires an argument.")
     if is_downloading:
         return await message.reply_text(
             "Another download is in progress, try again after sometime."

+ 10 - 27
wbb/modules/notes.py

@@ -29,8 +29,8 @@ from wbb import app
 from wbb.core.decorators.errors import capture_err
 from wbb.core.decorators.permissions import adminsOnly
 from wbb.core.keyboard import ikb
-from wbb.utils.dbfunctions import (delete_note, get_note,
-                                   get_note_names, save_note)
+from wbb.utils.dbfunctions import (delete_note, get_note, get_note_names,
+                                   save_note)
 from wbb.utils.functions import extract_text_and_keyb
 
 __MODULE__ = "Notes"
@@ -40,9 +40,7 @@ __HELP__ = """/notes To Get All The Notes In The Chat.
 /delete [NOTE_NAME] To Delete A Note."""
 
 
-@app.on_message(
-    filters.command("save") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("save") & ~filters.edited & ~filters.private)
 @adminsOnly("can_change_info")
 async def save_notee(_, message):
     if len(message.command) < 2 or not message.reply_to_message:
@@ -60,9 +58,7 @@ async def save_notee(_, message):
     else:
         name = message.text.split(None, 1)[1].strip()
         if not name:
-            return await message.reply_text(
-                "**Usage**\n__/save [NOTE_NAME]__"
-            )
+            return await message.reply_text("**Usage**\n__/save [NOTE_NAME]__")
         _type = "text" if message.reply_to_message.text else "sticker"
         note = {
             "type": _type,
@@ -74,9 +70,7 @@ async def save_notee(_, message):
         await message.reply_text(f"__**Saved note {name}.**__")
 
 
-@app.on_message(
-    filters.command("notes") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("notes") & ~filters.edited & ~filters.private)
 @capture_err
 async def get_notes(_, message):
     _notes = await get_note_names(message.chat.id)
@@ -91,10 +85,7 @@ async def get_notes(_, message):
 
 
 @app.on_message(
-    filters.regex(r"^#.+")
-    & filters.text
-    & ~filters.edited
-    & ~filters.private
+    filters.regex(r"^#.+") & filters.text & ~filters.edited & ~filters.private
 )
 @capture_err
 async def get_one_note(_, message):
@@ -120,25 +111,17 @@ async def get_one_note(_, message):
         await message.reply_sticker(_note["data"])
 
 
-@app.on_message(
-    filters.command("delete") & ~filters.edited & ~filters.private
-)
+@app.on_message(filters.command("delete") & ~filters.edited & ~filters.private)
 @adminsOnly("can_change_info")
 async def del_note(_, message):
     if len(message.command) < 2:
-        return await message.reply_text(
-            "**Usage**\n__/delete [NOTE_NAME]__"
-        )
+        return await message.reply_text("**Usage**\n__/delete [NOTE_NAME]__")
     name = message.text.split(None, 1)[1].strip()
     if not name:
-        return await message.reply_text(
-            "**Usage**\n__/delete [NOTE_NAME]__"
-        )
+        return await message.reply_text("**Usage**\n__/delete [NOTE_NAME]__")
     chat_id = message.chat.id
     deleted = await delete_note(chat_id, name)
     if deleted:
-        await message.reply_text(
-            f"**Deleted note {name} successfully.**"
-        )
+        await message.reply_text(f"**Deleted note {name} successfully.**")
     else:
         await message.reply_text("**No such note.**")

+ 80 - 0
wbb/modules/parse_preview.py

@@ -0,0 +1,80 @@
+from asyncio import sleep
+
+from pyrogram import filters
+from pyrogram.types import Message
+
+from wbb import SUDOERS, USERBOT_PREFIX, app2, eor
+from wbb.core.sections import section
+
+
+@app2.on_message(
+    filters.command("parse_preview", prefixes=USERBOT_PREFIX)
+    & filters.user(SUDOERS),
+)
+async def parse(_, message: Message):
+    r = message.reply_to_message
+    has_wpp = False
+
+    m_ = await eor(message, text="Parsing...")
+    if not r:
+        return await m_.edit("Reply to a message with a webpage")
+
+    if not r.web_page:
+        text = r.text or r.caption
+        if text:
+            m = await app2.send_message("me", text)
+            await sleep(1)
+            await m.delete()
+            if m.web_page:
+                r = m
+                has_wpp = True
+    else:
+        has_wpp = True
+
+    if not has_wpp:
+        return await m_.edit(
+            "Replied message has no webpage preview.",
+        )
+
+    wpp = r.web_page
+
+    body = {
+        "Title": [wpp.title or "Null"],
+        "Description": [
+            (wpp.description[:50] + "...") if wpp.description else "Null"
+        ],
+        "URL": [wpp.display_url or "Null"],
+        "Author": [wpp.author or "Null"],
+        "Site Name": [wpp.site_name or "Null"],
+        "Type": wpp.type or "Null",
+    }
+
+    text = section("Preview", body)
+
+    t = wpp.type
+
+    if t == "photo":
+        media = wpp.photo
+        func = app2.send_photo
+    elif t == "audio":
+        media = wpp.audio
+        func = app2.send_audio
+    elif t == "video":
+        media = wpp.video
+        func = app2.send_video
+    elif t == "document":
+        media = wpp.document
+        func = app2.send_document
+    else:
+        media = None
+        func = None
+
+    if media and func:
+        await m_.delete()
+        return await func(
+            m_.chat.id,
+            media.file_id,
+            caption=text,
+        )
+
+    await m_.edit(text, disable_web_page_preview=True)

+ 4 - 12
wbb/modules/paste.py

@@ -34,9 +34,7 @@ from wbb.utils.pastebin import paste
 
 __MODULE__ = "Paste"
 __HELP__ = "/paste - To Paste Replied Text Or Document To A Pastebin"
-pattern = re.compile(
-    r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$"
-)
+pattern = re.compile(r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$")
 
 
 @app.on_message(filters.command("paste") & ~filters.edited)
@@ -47,9 +45,7 @@ async def paste_func(_, message):
     r = message.reply_to_message
 
     if not r.text and not r.document:
-        return await message.reply(
-            "Only text and documents are supported."
-        )
+        return await message.reply("Only text and documents are supported.")
 
     m = await message.reply("Pasting...")
 
@@ -57,9 +53,7 @@ async def paste_func(_, message):
         content = str(r.text)
     elif r.document:
         if r.document.file_size > 40000:
-            return await m.edit(
-                "You can only paste files smaller than 40KB."
-            )
+            return await m.edit("You can only paste files smaller than 40KB.")
         if not pattern.search(r.document.mime_type):
             return await m.edit("Only text files can be pasted.")
         doc = await message.reply_to_message.download()
@@ -70,9 +64,7 @@ async def paste_func(_, message):
     link = await paste(content)
     kb = ikb({"Paste Link": link})
     try:
-        await message.reply_photo(
-            photo=link, quote=False, reply_markup=kb
-        )
+        await message.reply_photo(photo=link, quote=False, reply_markup=kb)
     except Exception:
         await message.reply("Here's your paste", reply_markup=kb)
     await m.delete()

+ 7 - 24
wbb/modules/pipes.py

@@ -81,11 +81,7 @@ async def pipes_worker_userbot(_, message: Message):
             m, temp = await asyncio.gather(
                 app.listen(USERBOT_ID), message.copy(BOT_ID)
             )
-            caption = (
-                f"{temp.caption}{caption}"
-                if temp.caption
-                else caption
-            )
+            caption = f"{temp.caption}{caption}" if temp.caption else caption
 
             await app.copy_message(
                 to_chat_id,
@@ -96,14 +92,10 @@ async def pipes_worker_userbot(_, message: Message):
             await asyncio.sleep(2)
             return await temp.delete()
 
-        await app.send_message(
-            to_chat_id, text=message.text + caption
-        )
+        await app.send_message(to_chat_id, text=message.text + caption)
 
 
-@app.on_message(
-    filters.command("activate_pipe") & filters.user(SUDOERS)
-)
+@app.on_message(filters.command("activate_pipe") & filters.user(SUDOERS))
 @capture_err
 async def activate_pipe_func(_, message: Message):
     global pipes_list_bot, pipes_list_userbot
@@ -123,9 +115,7 @@ async def activate_pipe_func(_, message: Message):
         return await message.reply("Wrong fetcher, see help menu.")
 
     if from_chat in pipes_list_bot or from_chat in pipes_list_userbot:
-        return await message.reply_text(
-            "This pipe is already active."
-        )
+        return await message.reply_text("This pipe is already active.")
 
     dict_ = pipes_list_bot
     if fetcher == "userbot":
@@ -135,25 +125,18 @@ async def activate_pipe_func(_, message: Message):
     await message.reply_text("Activated pipe.")
 
 
-@app.on_message(
-    filters.command("deactivate_pipe") & filters.user(SUDOERS)
-)
+@app.on_message(filters.command("deactivate_pipe") & filters.user(SUDOERS))
 @capture_err
 async def deactivate_pipe_func(_, message: Message):
     global pipes_list_bot, pipes_list_userbot
 
     if len(message.command) != 2:
-        await message.reply_text(
-            "**Usage:**\n/deactivate_pipe [FROM_CHAT_ID]"
-        )
+        await message.reply_text("**Usage:**\n/deactivate_pipe [FROM_CHAT_ID]")
         return
     text = message.text.strip().split()
     from_chat = int(text[1])
 
-    if (
-        from_chat not in pipes_list_bot
-        and from_chat not in pipes_list_userbot
-    ):
+    if from_chat not in pipes_list_bot and from_chat not in pipes_list_userbot:
         await message.reply_text("This pipe is already inactive.")
 
     dict_ = pipes_list_bot

+ 11 - 31
wbb/modules/pmpermit.py

@@ -25,11 +25,9 @@ SOFTWARE.
 from pyrogram import filters
 from pyrogram.raw.functions.messages import DeleteHistory
 
-from wbb import (BOT_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX, app,
-                 app2, eor)
+from wbb import BOT_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX, app, app2, eor
 from wbb.core.decorators.errors import capture_err
-from wbb.utils.dbfunctions import (approve_pmpermit,
-                                   disapprove_pmpermit,
+from wbb.utils.dbfunctions import (approve_pmpermit, disapprove_pmpermit,
                                    is_pmpermit_approved)
 
 flood = {}
@@ -58,13 +56,9 @@ async def pmpermit_func(_, message):
     else:
         flood[str(user_id)] = 1
     if flood[str(user_id)] > 5:
-        await message.reply_text(
-            "SPAM DETECTED, BLOCKED USER AUTOMATICALLY!"
-        )
+        await message.reply_text("SPAM DETECTED, BLOCKED USER AUTOMATICALLY!")
         return await app2.block_user(user_id)
-    results = await app2.get_inline_bot_results(
-        BOT_ID, f"pmpermit {user_id}"
-    )
+    results = await app2.get_inline_bot_results(BOT_ID, f"pmpermit {user_id}")
     await app2.send_inline_bot_result(
         user_id,
         results.query_id,
@@ -81,14 +75,10 @@ async def pmpermit_func(_, message):
 @capture_err
 async def pm_approve(_, message):
     if not message.reply_to_message:
-        return await eor(
-            message, text="Reply to a user's message to approve."
-        )
+        return await eor(message, text="Reply to a user's message to approve.")
     user_id = message.reply_to_message.from_user.id
     if await is_pmpermit_approved(user_id):
-        return await eor(
-            message, text="User is already approved to pm"
-        )
+        return await eor(message, text="User is already approved to pm")
     await approve_pmpermit(user_id)
     await eor(message, text="User is approved to pm")
 
@@ -100,9 +90,7 @@ async def pm_approve(_, message):
 )
 async def pm_disapprove(_, message):
     if not message.reply_to_message:
-        return await eor(
-            message, text="Reply to a user's message to approve."
-        )
+        return await eor(message, text="Reply to a user's message to approve.")
     user_id = message.reply_to_message.from_user.id
     if not await is_pmpermit_approved(user_id):
         await eor(message, text="User is already disapproved to pm")
@@ -125,9 +113,7 @@ async def pm_disapprove(_, message):
 @capture_err
 async def block_user_func(_, message):
     if not message.reply_to_message:
-        return await eor(
-            message, text="Reply to a user's message to block."
-        )
+        return await eor(message, text="Reply to a user's message to block.")
     user_id = message.reply_to_message.from_user.id
     # Blocking user after editing the message so that other person can get the update.
     await eor(message, text="Successfully blocked the user")
@@ -141,9 +127,7 @@ async def block_user_func(_, message):
 )
 async def unblock_user_func(_, message):
     if not message.reply_to_message:
-        return await eor(
-            message, text="Reply to a user's message to unblock."
-        )
+        return await eor(message, text="Reply to a user's message to unblock.")
     user_id = message.reply_to_message.from_user.id
     await app2.unblock_user(user_id)
     await eor(message, text="Successfully Unblocked the user")
@@ -192,9 +176,7 @@ async def pmpermit_cq(_, cq):
         async for m in app2.iter_history(user_id, limit=6):
             if m.reply_markup:
                 await m.delete()
-        await app2.send_message(
-            user_id, "Blocked, Go scam someone else."
-        )
+        await app2.send_message(user_id, "Blocked, Go scam someone else.")
         await app2.block_user(user_id)
         await cq.answer()
 
@@ -205,9 +187,7 @@ async def pmpermit_cq(_, cq):
         else:
             flood2[str(user_id)] = 1
         if flood2[str(user_id)] > 5:
-            await app2.send_message(
-                user_id, "SPAM DETECTED, USER BLOCKED."
-            )
+            await app2.send_message(user_id, "SPAM DETECTED, USER BLOCKED.")
             return await app2.block_user(user_id)
         await app2.send_message(
             user_id,

+ 12 - 16
wbb/modules/purge_me.py

@@ -25,7 +25,7 @@ SOFTWARE.
 from pyrogram import filters
 from pyrogram.types import Message
 
-from wbb import USERBOT_ID, USERBOT_PREFIX, app2
+from wbb import USERBOT_ID, USERBOT_PREFIX, app2, eor
 
 # Yeah i know this should've been in userbot.py,
 # But i wrote it here for some obvious reasons.
@@ -88,42 +88,38 @@ __HELP__ = """
     & filters.user(USERBOT_ID)
 )
 async def purge_me_func(_, message: Message):
-    await message.delete()
-
     if len(message.command) != 2:
-        return
+        return await message.delete()
 
     n = message.text.split(None, 1)[1].strip()
     if not n.isnumeric():
-        return
+        return await eor(message, text="Invalid Args")
 
     n = int(n)
+
     if n < 1:
-        return
+        return await eor(message, text="Need a number >=1")
 
     chat_id = message.chat.id
 
     message_ids = [
         m.message_id
         async for m in app2.search_messages(
-            chat_id, from_user=USERBOT_ID
+            chat_id,
+            from_user=int(USERBOT_ID),
+            limit=n,
         )
-    ][
-        :n
-    ]  # NOTE Don't use limit param here
+    ]
 
-    if len(message_ids) == 0:
-        return
+    if not message_ids:
+        return await eor(message, text="No messages found.")
 
     # A list containing lists of 100 message chunks
     # because we can't delete more than 100 messages at once,
     # we have to do it in chunks of 100, i'll choose 99 just
     # to be safe.
     to_delete = [
-        (
-            message_ids[i : i + 99]
-            for i in range(0, len(message_ids), 99)
-        )
+        message_ids[i : i + 99] for i in range(0, len(message_ids), 99)
     ]
 
     for hundred_messages_or_less in to_delete:

+ 9 - 10
wbb/modules/quotly.py

@@ -55,7 +55,7 @@ def getArg(message: Message) -> str:
     return arg
 
 
-def isArgInt(message: Message) -> bool:
+def isArgInt(message: Message) -> list:
     count = getArg(message)
     try:
         count = int(count)
@@ -65,16 +65,13 @@ def isArgInt(message: Message) -> bool:
 
 
 @app2.on_message(
-    filters.command("q", prefixes=USERBOT_PREFIX)
-    & filters.user(SUDOERS)
+    filters.command("q", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
 )
 @app.on_message(filters.command("q") & ~filters.private)
 @capture_err
 async def quotly_func(client, message: Message):
     if not message.reply_to_message:
-        return await message.reply_text(
-            "Reply to a message to quote it."
-        )
+        return await message.reply_text("Reply to a message to quote it.")
     if not message.reply_to_message.text:
         return await message.reply_text(
             "Replied message has no text, can't quote it."
@@ -91,18 +88,21 @@ async def quotly_func(client, message: Message):
 
             count = arg[1]
 
+            # Fetching 5 extra messages so tha twe can ignore media
+            # messages and still end up with correct offset
             messages = [
                 i
                 for i in await client.get_messages(
                     message.chat.id,
                     range(
                         message.reply_to_message.message_id,
-                        message.reply_to_message.message_id + count,
+                        message.reply_to_message.message_id + (count + 5),
                     ),
                     replies=0,
                 )
-                if not i.empty
+                if not i.empty and not i.media
             ]
+            messages = messages[:count]
         else:
             if getArg(message) != "r":
                 return await m.edit(
@@ -115,10 +115,9 @@ async def quotly_func(client, message: Message):
             )
             messages = [reply_message]
     else:
-        await m.edit(
+        return await m.edit(
             "Incorrect argument, check quotly module in help section."
         )
-        return
     try:
         if not message:
             return await m.edit("Something went wrong.")

+ 4 - 11
wbb/modules/regex.py

@@ -36,8 +36,7 @@ async def sed(_, message):
 
         if not repl:
             return await message.reply_text(
-                "You're trying to replace... "
-                "nothing with something?"
+                "You're trying to replace... " "nothing with something?"
             )
 
         try:
@@ -46,9 +45,7 @@ async def sed(_, message):
                 return await message.reply_text("Nice try -_-")
 
             if "i" in flags and "g" in flags:
-                text = re.sub(
-                    repl, repl_with, to_fix, flags=re.I
-                ).strip()
+                text = re.sub(repl, repl_with, to_fix, flags=re.I).strip()
             elif "i" in flags:
                 text = re.sub(
                     repl, repl_with, to_fix, count=1, flags=re.I
@@ -56,9 +53,7 @@ async def sed(_, message):
             elif "g" in flags:
                 text = re.sub(repl, repl_with, to_fix).strip()
             else:
-                text = re.sub(
-                    repl, repl_with, to_fix, count=1
-                ).strip()
+                text = re.sub(repl, repl_with, to_fix, count=1).strip()
         except sre_constants.error:
             return
 
@@ -111,9 +106,7 @@ def separate_sed(sed_string):
                 and counter + 1 < len(sed_string)
                 and sed_string[counter + 1] == delim
             ):
-                sed_string = (
-                    sed_string[:counter] + sed_string[counter + 1 :]
-                )
+                sed_string = sed_string[:counter] + sed_string[counter + 1 :]
 
             elif sed_string[counter] == delim:
                 replace_with = sed_string[start:counter]

+ 1 - 4
wbb/modules/repo.py

@@ -28,10 +28,7 @@ from wbb.core.decorators.errors import capture_err
 from wbb.utils.http import get
 
 __MODULE__ = "Repo"
-__HELP__ = (
-    "/repo - To Get My Github Repository Link "
-    "And Support Group Link"
-)
+__HELP__ = "/repo - To Get My Github Repository Link " "And Support Group Link"
 
 
 @app.on_message(filters.command("repo") & ~filters.edited)

+ 3 - 9
wbb/modules/reverse.py

@@ -66,9 +66,7 @@ async def reverse_image_search(_, message: Message):
     file_id = get_file_id_from_message(reply)
     if not file_id:
         return await m.edit("Can't reverse that")
-    image = await app.download_media(
-        file_id, f"{randint(1000, 10000)}.jpg"
-    )
+    image = await app.download_media(file_id, f"{randint(1000, 10000)}.jpg")
     async with aiofiles.open(image, "rb") as f:
         if image:
             search_url = "http://www.google.com/searchbyimage/upload"
@@ -83,9 +81,7 @@ async def reverse_image_search(_, message: Message):
                 )
 
             loop = get_running_loop()
-            response = await loop.run_in_executor(
-                None, post_non_blocking
-            )
+            response = await loop.run_in_executor(None, post_non_blocking)
             location = response.headers.get("Location")
             os.remove(image)
         else:
@@ -131,9 +127,7 @@ async def reverse_image_search(_, message: Message):
                 media.append(img)
 
         # Cache images, so we can use file_ids
-        tasks = [
-            app.send_photo(MESSAGE_DUMP_CHAT, img) for img in media
-        ]
+        tasks = [app.send_photo(MESSAGE_DUMP_CHAT, img) for img in media]
         messages = await gather(*tasks)
 
         await message.reply_media_group(

+ 11 - 30
wbb/modules/rice.py

@@ -22,9 +22,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 from pyrogram import filters
-from pyrogram.types import (InlineKeyboardButton,
-                            InlineKeyboardMarkup, InputMediaPhoto,
-                            InputMediaVideo, Message)
+from pyrogram.types import (InlineKeyboardButton, InlineKeyboardMarkup,
+                            InputMediaPhoto, InputMediaVideo, Message)
 
 from wbb import app
 from wbb.core.decorators.errors import capture_err
@@ -56,9 +55,7 @@ async def rice(_, message: Message):
                     InlineKeyboardButton(
                         "Approve (Forward)", callback_data="forward"
                     ),
-                    InlineKeyboardButton(
-                        "Ignore", callback_data="ignore"
-                    ),
+                    InlineKeyboardButton("Ignore", callback_data="ignore"),
                 ]
             ]
         ),
@@ -79,29 +76,21 @@ async def callback_query_forward_rice(_, callback_query):
     await callback_query.answer("Successfully approved")
     m_op = callback_query.message.reply_to_message
     u_op = m_op.from_user
-    arg_caption = (
-        f"{m_op.caption}\nOP: [{u_op.first_name}]({m_op.link})"
-    )
+    arg_caption = f"{m_op.caption}\nOP: [{u_op.first_name}]({m_op.link})"
     if m_op.media_group_id:
         message_id = m_op.message_id
-        media_group = await app.get_media_group(
-            RICE_GROUP, message_id
-        )
+        media_group = await app.get_media_group(RICE_GROUP, message_id)
         arg_media = []
         for m in media_group:
             if m.photo and m.caption:
                 arg_media.append(
-                    InputMediaPhoto(
-                        m.photo.file_id, caption=arg_caption
-                    )
+                    InputMediaPhoto(m.photo.file_id, caption=arg_caption)
                 )
             elif m.photo:
                 arg_media.append(InputMediaPhoto(m.photo.file_id))
             elif m.video and m.caption:
                 arg_media.append(
-                    InputMediaVideo(
-                        m.video.file_id, caption=arg_caption
-                    )
+                    InputMediaVideo(m.video.file_id, caption=arg_caption)
                 )
             elif m.video:
                 arg_media.append(InputMediaVideo(m.video.file_id))
@@ -123,21 +112,13 @@ async def callback_query_forward_rice(_, callback_query):
 async def callback_query_ignore_rice(_, callback_query):
     c_group = callback_query.message.chat
     u_disprover = callback_query.from_user
-    disprover_status = (
-        await c_group.get_member(u_disprover.id)
-    ).status
+    disprover_status = (await c_group.get_member(u_disprover.id)).status
     m_op = callback_query.message.reply_to_message
     u_op = m_op.from_user
     if u_disprover.id == u_op.id:
-        await callback_query.answer(
-            "Ok, this rice won't be forwarded"
-        )
+        await callback_query.answer("Ok, this rice won't be forwarded")
     elif disprover_status in ("creator", "administrator"):
-        await m_op.reply_text(
-            f"{u_disprover.mention} ignored this rice"
-        )
+        await m_op.reply_text(f"{u_disprover.mention} ignored this rice")
     else:
-        return await callback_query.answer(
-            "Only admin or OP could ignore it"
-        )
+        return await callback_query.answer("Only admin or OP could ignore it")
     await callback_query.message.delete()

+ 4 - 8
wbb/modules/rss.py

@@ -5,11 +5,9 @@ from pyrogram.types import Message
 
 from wbb import RSS_DELAY, app
 from wbb.core.decorators.errors import capture_err
-from wbb.utils.dbfunctions import (add_rss_feed, get_rss_feeds,
-                                   is_rss_active, remove_rss_feed,
-                                   update_rss_feed)
-from wbb.utils.functions import (get_http_status_code,
-                                 get_urls_from_text)
+from wbb.utils.dbfunctions import (add_rss_feed, get_rss_feeds, is_rss_active,
+                                   remove_rss_feed, update_rss_feed)
+from wbb.utils.functions import get_http_status_code, get_urls_from_text
 from wbb.utils.rss import Feed
 
 __MODULE__ = "RSS"
@@ -82,9 +80,7 @@ async def add_feed_func(_, m: Message):
 
     chat_id = m.chat.id
     if await is_rss_active(chat_id):
-        return await m.reply(
-            "[ERROR]: You already have an RSS feed enabled."
-        )
+        return await m.reply("[ERROR]: You already have an RSS feed enabled.")
     try:
         await m.reply(feed.parsed(), disable_web_page_preview=True)
     except Exception:

+ 18 - 44
wbb/modules/stickers.py

@@ -28,20 +28,16 @@ from traceback import format_exc
 
 from pyrogram import filters
 from pyrogram.errors import (PeerIdInvalid, ShortnameOccupyFailed,
-                             StickerEmojiInvalid,
-                             StickerPngDimensions, StickerPngNopng,
-                             UserIsBlocked)
-from pyrogram.types import (InlineKeyboardButton,
-                            InlineKeyboardMarkup, Message)
+                             StickerEmojiInvalid, StickerPngDimensions,
+                             StickerPngNopng, UserIsBlocked)
+from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
 
 from wbb import BOT_USERNAME, SUDOERS, USERBOT_PREFIX, app, app2, eor
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.files import (get_document_from_file_id,
-                             resize_file_to_sticker_size,
-                             upload_document)
+                             resize_file_to_sticker_size, upload_document)
 from wbb.utils.stickerset import (add_sticker_to_set, create_sticker,
-                                  create_sticker_set,
-                                  get_sticker_set_by_name)
+                                  create_sticker_set, get_sticker_set_by_name)
 
 __MODULE__ = "Stickers"
 __HELP__ = """
@@ -52,7 +48,9 @@ __HELP__ = """
 /kang
     To kang a Sticker or an Image."""
 
-MAX_STICKERS = 120  # would be better if we could fetch this limit directly from telegram
+MAX_STICKERS = (
+    120  # would be better if we could fetch this limit directly from telegram
+)
 SUPPORTED_TYPES = ["jpeg", "png", "webp"]
 
 
@@ -96,16 +94,13 @@ async def sticker_image(_, message: Message):
 
 
 @app2.on_message(
-    filters.command("kang", prefixes=USERBOT_PREFIX)
-    & filters.user(SUDOERS),
+    filters.command("kang", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS),
 )
 async def userbot_kang(_, message: Message):
     reply = message.reply_to_message
 
     if not reply:
-        return await message.reply_text(
-            "Reply to a sticker/image to kang it."
-        )
+        return await message.reply_text("Reply to a sticker/image to kang it.")
 
     sticker_m = await reply.forward(BOT_USERNAME)
 
@@ -134,9 +129,7 @@ async def userbot_kang(_, message: Message):
 @capture_err
 async def kang(client, message: Message):
     if not message.reply_to_message:
-        return await message.reply_text(
-            "Reply to a sticker/image to kang it."
-        )
+        return await message.reply_text("Reply to a sticker/image to kang it.")
     if not message.from_user:
         return await message.reply_text(
             "You are anon admin, kang stickers in my pm."
@@ -156,10 +149,7 @@ async def kang(client, message: Message):
         sticker_emoji = "🤔"
 
     # Get the corresponding fileid, resize the file if necessary
-    doc = (
-        message.reply_to_message.photo
-        or message.reply_to_message.document
-    )
+    doc = message.reply_to_message.photo or message.reply_to_message.document
     try:
         if message.reply_to_message.sticker:
             sticker = await create_sticker(
@@ -188,9 +178,7 @@ async def kang(client, message: Message):
                     f"Something went wrong while resizing the sticker (at {temp_file_path}); {e}"
                 )
             sticker = await create_sticker(
-                await upload_document(
-                    client, temp_file_path, message.chat.id
-                ),
+                await upload_document(client, temp_file_path, message.chat.id),
                 sticker_emoji,
             )
             if os.path.isfile(temp_file_path):
@@ -217,9 +205,7 @@ async def kang(client, message: Message):
             if limit >= 50:
                 return await msg.delete()
 
-            stickerset = await get_sticker_set_by_name(
-                client, packname
-            )
+            stickerset = await get_sticker_set_by_name(client, packname)
             if not stickerset:
                 stickerset = await create_sticker_set(
                     client,
@@ -242,13 +228,9 @@ async def kang(client, message: Message):
                 continue
             else:
                 try:
-                    await add_sticker_to_set(
-                        client, stickerset, sticker
-                    )
+                    await add_sticker_to_set(client, stickerset, sticker)
                 except StickerEmojiInvalid:
-                    return await msg.edit(
-                        "[ERROR]: INVALID_EMOJI_IN_ARGUMENT"
-                    )
+                    return await msg.edit("[ERROR]: INVALID_EMOJI_IN_ARGUMENT")
             limit += 1
             break
 
@@ -259,13 +241,7 @@ async def kang(client, message: Message):
         )
     except (PeerIdInvalid, UserIsBlocked):
         keyboard = InlineKeyboardMarkup(
-            [
-                [
-                    InlineKeyboardButton(
-                        text="Start", url=f"t.me/{BOT_USERNAME}"
-                    )
-                ]
-            ]
+            [[InlineKeyboardButton(text="Start", url=f"t.me/{BOT_USERNAME}")]]
         )
         await msg.edit(
             "You Need To Start A Private Chat With Me.",
@@ -276,6 +252,4 @@ async def kang(client, message: Message):
             "Stickers must be png files but the provided image was not a png"
         )
     except StickerPngDimensions:
-        await message.reply_text(
-            "The sticker png dimensions are invalid."
-        )
+        await message.reply_text("The sticker png dimensions are invalid.")

+ 3 - 6
wbb/modules/sudo.py

@@ -46,8 +46,7 @@ can even delete your account.
 
 
 @app2.on_message(
-    filters.command("useradd", prefixes=USERBOT_PREFIX)
-    & filters.user(SUDOERS)
+    filters.command("useradd", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
 )
 @capture_err
 async def useradd(_, message: Message):
@@ -75,8 +74,7 @@ async def useradd(_, message: Message):
 
 
 @app2.on_message(
-    filters.command("userdel", prefixes=USERBOT_PREFIX)
-    & filters.user(SUDOERS)
+    filters.command("userdel", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
 )
 @capture_err
 async def userdel(_, message: Message):
@@ -99,8 +97,7 @@ async def userdel(_, message: Message):
 
 
 @app2.on_message(
-    filters.command("sudoers", prefixes=USERBOT_PREFIX)
-    & filters.user(SUDOERS)
+    filters.command("sudoers", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
 )
 @capture_err
 async def sudoers_list(_, message: Message):

+ 7 - 16
wbb/modules/sudoers.py

@@ -30,14 +30,13 @@ import psutil
 from pyrogram import filters
 from pyrogram.errors import FloodWait
 
-from wbb import (BOT_ID, GBAN_LOG_GROUP_ID, SUDOERS, USERBOT_USERNAME,
-                 app, bot_start_time)
+from wbb import (BOT_ID, GBAN_LOG_GROUP_ID, SUDOERS, USERBOT_USERNAME, app,
+                 bot_start_time)
 from wbb.core.decorators.errors import capture_err
 from wbb.utils import formatter
 from wbb.utils.dbfunctions import (add_gban_user, get_served_chats,
                                    is_gbanned_user, remove_gban_user)
-from wbb.utils.functions import (extract_user,
-                                 extract_user_and_reason, restart)
+from wbb.utils.functions import extract_user, extract_user_and_reason, restart
 
 __MODULE__ = "Sudoers"
 __HELP__ = """
@@ -106,9 +105,7 @@ async def ban_globally(_, message):
     number_of_chats = 0
     for served_chat in served_chats:
         try:
-            await app.kick_chat_member(
-                served_chat["chat_id"], user.id
-            )
+            await app.kick_chat_member(served_chat["chat_id"], user.id)
             number_of_chats += 1
             await asyncio.sleep(1)
         except FloodWait as e:
@@ -164,25 +161,19 @@ async def unban_globally(_, message):
         await message.reply_text("I don't remember Gbanning him.")
     else:
         await remove_gban_user(user.id)
-        await message.reply_text(
-            f"Lifted {user.mention}'s Global Ban.'"
-        )
+        await message.reply_text(f"Lifted {user.mention}'s Global Ban.'")
 
 
 # Broadcast
 
 
 @app.on_message(
-    filters.command("broadcast")
-    & filters.user(SUDOERS)
-    & ~filters.edited
+    filters.command("broadcast") & filters.user(SUDOERS) & ~filters.edited
 )
 @capture_err
 async def broadcast_message(_, message):
     if len(message.command) < 2:
-        return await message.reply_text(
-            "**Usage**:\n/broadcast [MESSAGE]"
-        )
+        return await message.reply_text("**Usage**:\n/broadcast [MESSAGE]")
     sleep_time = 0.1
     text = message.text.split(None, 1)[1]
     sent = 0

+ 3 - 5
wbb/modules/taglogger.py

@@ -25,8 +25,8 @@ from pykeyboard import InlineKeyboard
 from pyrogram import filters
 from pyrogram.types import InlineKeyboardButton, Message
 
-from wbb import (BOT_ID, LOG_GROUP_ID, LOG_MENTIONS, USERBOT_ID,
-                 USERBOT_NAME, USERBOT_USERNAME, app, app2)
+from wbb import (BOT_ID, LOG_GROUP_ID, LOG_MENTIONS, USERBOT_ID, USERBOT_NAME,
+                 USERBOT_USERNAME, app, app2)
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.filter_groups import taglog_group
 
@@ -52,9 +52,7 @@ async def sendLog(message: Message):
 **Bot:** {message.from_user.is_bot}
 """
     button = InlineKeyboard(row_width=1)
-    button.add(
-        InlineKeyboardButton(text="Check Action", url=message.link)
-    )
+    button.add(InlineKeyboardButton(text="Check Action", url=message.link))
     await app.send_message(
         LOG_GROUP_ID,
         text=msg,

+ 4 - 9
wbb/modules/userbot.py

@@ -21,6 +21,7 @@ from pyrogram.types import Message, ReplyKeyboardMarkup
 
 from wbb import app2  # don't remove
 from wbb import SUDOERS, USERBOT_PREFIX, app, arq, eor
+from wbb.core.keyboard import ikb
 from wbb.core.tasks import add_task, rm_task
 
 # Eval and Sh module from nana-remix
@@ -82,9 +83,7 @@ async def executor(client, message: Message):
     # To prevent keyboard input attacks
     if m.reply_to_message:
         r = m.reply_to_message
-        if r.reply_markup and isinstance(
-            r.reply_markup, ReplyKeyboardMarkup
-        ):
+        if r.reply_markup and isinstance(r.reply_markup, ReplyKeyboardMarkup):
             return await eor(m, text="INSECURE!")
     status = None
     old_stderr = sys.stderr
@@ -150,9 +149,7 @@ async def executor(client, message: Message):
             return await message.reply(final_output, quote=True)
         return
     if not status.from_user:
-        status = await app2.get_messages(
-            status.chat.id, status.message_id
-        )
+        status = await app2.get_messages(status.chat.id, status.message_id)
     await eor(status, text=final_output, quote=True)
 
 
@@ -180,9 +177,7 @@ async def shellrunner(_, message: Message):
         code = text.split("\n")
         output = ""
         for x in code:
-            shell = re.split(
-                """ (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x
-            )
+            shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x)
             try:
                 process = subprocess.Popen(
                     shell,

+ 1 - 3
wbb/modules/webss.py

@@ -36,9 +36,7 @@ __HELP__ = "/webss | .webss [URL] - Take A Screenshot Of A Webpage"
 async def take_ss(_, message: Message):
     try:
         if len(message.command) != 2:
-            return await message.reply_text(
-                "Give A Url To Fetch Screenshot."
-            )
+            return await message.reply_text("Give A Url To Fetch Screenshot.")
         url = message.text.split(None, 1)[1]
         m = await message.reply_text("**Taking Screenshot**")
         await m.edit("**Uploading**")

+ 24 - 17
wbb/utils/dbfunctions.py

@@ -27,10 +27,10 @@ from typing import Dict, List, Union
 
 from wbb import db
 
-
 # SOME THINGS ARE FUCKED UP HERE, LIKE TOGGLEABLES HAVE THEIR OWN COLLECTION
-# (SHOULD FIX IT WITH SOMETHING LIKE TOGGLEDB, BUT I WON'T, AS IT WILL TAKE
-# TOO MUCH TIME AND WILL BE BAD FOR ALREADY STORED DATA)
+# (SHOULD FIX IT WITH SOMETHING LIKE TOGGLEDB), MOST OF THE CODE IS BAD AF
+# AND NEEDS TO BE REWRITTEN, BUT I WON'T, AS IT WILL TAKE
+# TOO MUCH TIME AND WILL BE BAD FOR ALREADY STORED DATA
 
 
 notesdb = db.notes
@@ -42,10 +42,11 @@ usersdb = db.users
 gbansdb = db.gban
 coupledb = db.couple
 captchadb = db.captcha
+solved_captcha_db = db.solved_captcha
+captcha_cachedb = db.captcha_cache
 antiservicedb = db.antiservice
 pmpermitdb = db.pmpermit
 welcomedb = db.welcome_text
-captcha_cachedb = db.captcha_cache
 blacklist_filtersdb = db.blacklistFilters
 pipesdb = db.pipes
 sudoersdb = db.sudoers
@@ -280,9 +281,7 @@ async def user_global_karma(user_id) -> int:
         return 0
     total_karma = 0
     for chat in await chats.to_list(length=1000000):
-        karma = await get_karma(
-            chat["chat_id"], await int_to_alpha(user_id)
-        )
+        karma = await get_karma(chat["chat_id"], await int_to_alpha(user_id))
         if karma and (int(karma["karma"]) > 0):
             total_karma += int(karma["karma"])
     return total_karma
@@ -459,6 +458,21 @@ async def captcha_off(chat_id: int):
     return await captchadb.insert_one({"chat_id": chat_id})
 
 
+async def has_solved_captcha_once(chat_id: int, user_id: int):
+    has_solved = await solved_captcha_db.find_one(
+        {"chat_id": chat_id, "user_id": user_id}
+    )
+    return bool(has_solved)
+
+
+async def save_captcha_solved(chat_id: int, user_id: int):
+    return await solved_captcha_db.update_one(
+        {"chat_id": chat_id},
+        {"$set": {"user_id": user_id}},
+        upsert=True,
+    )
+
+
 async def is_antiservice_on(chat_id: int) -> bool:
     chat = await antiservicedb.find_one({"chat_id": chat_id})
     if not chat:
@@ -554,9 +568,7 @@ async def get_blacklist_filters_count() -> dict:
 
 
 async def get_blacklisted_words(chat_id: int) -> List[str]:
-    _filters = await blacklist_filtersdb.find_one(
-        {"chat_id": chat_id}
-    )
+    _filters = await blacklist_filtersdb.find_one({"chat_id": chat_id})
     if not _filters:
         return []
     return _filters["filters"]
@@ -587,9 +599,7 @@ async def delete_blacklist_filter(chat_id: int, word: str) -> bool:
     return False
 
 
-async def activate_pipe(
-    from_chat_id: int, to_chat_id: int, fetcher: str
-):
+async def activate_pipe(from_chat_id: int, to_chat_id: int, fetcher: str):
     pipes = await show_pipes()
     pipe = {
         "from_chat_id": from_chat_id,
@@ -660,10 +670,7 @@ async def remove_sudo(user_id: int) -> bool:
 
 async def blacklisted_chats() -> list:
     chats = blacklist_chatdb.find({"chat_id": {"$lt": 0}})
-    return [
-        chat["chat_id"]
-        for chat in await chats.to_list(length=1000000000)
-    ]
+    return [chat["chat_id"] for chat in await chats.to_list(length=1000000000)]
 
 
 async def blacklist_chat(chat_id: int) -> bool:

+ 1 - 3
wbb/utils/downloader.py

@@ -25,9 +25,7 @@ async def download_url(
         async with aiofiles.open(file_path, "wb") as f:
 
             # Save content in file using aiohttp streamReader.
-            async for chunk in response.content.iter_chunked(
-                chunk_size
-            ):
+            async for chunk in response.content.iter_chunked(chunk_size):
                 await f.write(chunk)
 
     return absolute_path(file_path)

+ 3 - 10
wbb/utils/functions.py

@@ -86,9 +86,7 @@ def generate_captcha():
     for t in range(4):
         letter = gen_letter()
         correct_answer += letter
-        draw.text(
-            (60 * t + 50, 15), letter, font=font, fill=rndColor2()
-        )
+        draw.text((60 * t + 50, 15), letter, font=font, fill=rndColor2())
     image = image.filter(ImageFilter.BLUR)
     image.save(file, "jpeg")
     return [file, correct_answer, wrong_answers]
@@ -147,10 +145,7 @@ async def calc_distance_from_ip(ip1: str, ip2: str) -> float:
     lat2, lon2 = radians(float(lat2)), radians(float(lon2))
     dlon = lon2 - lon1
     dlat = lat2 - lat1
-    a = (
-        sin(dlat / 2) ** 2
-        + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
-    )
+    a = sin(dlat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(dlon / 2) ** 2
     c = 2 * atan2(sqrt(a), sqrt(1 - a))
     distance = Radius_Earth * c
     return distance
@@ -166,9 +161,7 @@ def get_urls_from_text(text: str) -> bool:
 
 async def time_converter(message: Message, time_value: str) -> int:
     unit = ["m", "h", "d"]  # m == minutes | h == hours | d == days
-    check_unit = "".join(
-        list(filter(time_value[-1].lower().endswith, unit))
-    )
+    check_unit = "".join(list(filter(time_value[-1].lower().endswith, unit)))
     currunt_time = datetime.now()
     time_digit = time_value[:-1]
     if not time_digit.isdigit():

+ 3 - 9
wbb/utils/http.py

@@ -54,21 +54,15 @@ async def post(url: str, *args, **kwargs):
 
 
 async def multiget(url: str, times: int, *args, **kwargs):
-    return await gather(
-        *[get(url, *args, **kwargs) for _ in range(times)]
-    )
+    return await gather(*[get(url, *args, **kwargs) for _ in range(times)])
 
 
 async def multihead(url: str, times: int, *args, **kwargs):
-    return await gather(
-        *[head(url, *args, **kwargs) for _ in range(times)]
-    )
+    return await gather(*[head(url, *args, **kwargs) for _ in range(times)])
 
 
 async def multipost(url: str, times: int, *args, **kwargs):
-    return await gather(
-        *[post(url, *args, **kwargs) for _ in range(times)]
-    )
+    return await gather(*[post(url, *args, **kwargs) for _ in range(times)])
 
 
 async def resp_get(url: str, *args, **kwargs):

+ 27 - 76
wbb/utils/inlinefuncs.py

@@ -36,8 +36,7 @@ from pyrogram import __version__ as pyrover
 from pyrogram import filters
 from pyrogram.raw.functions import Ping
 from pyrogram.types import (CallbackQuery, InlineKeyboardButton,
-                            InlineQueryResultArticle,
-                            InlineQueryResultPhoto,
+                            InlineQueryResultArticle, InlineQueryResultPhoto,
                             InputTextMessageContent)
 from search_engine_parser import GoogleSearch
 
@@ -76,11 +75,7 @@ async def inline_help_func(__HELP__):
     buttons = InlineKeyboard(row_width=4)
     buttons.add(
         *[
-            (
-                InlineKeyboardButton(
-                    text=i, switch_inline_query_current_chat=i
-                )
-            )
+            (InlineKeyboardButton(text=i, switch_inline_query_current_chat=i))
             for i in keywords_list
         ]
     )
@@ -149,9 +144,7 @@ async def translate_func(answers, lang, tex):
             InlineQueryResultArticle(
                 title="Error",
                 description=result.result,
-                input_message_content=InputTextMessageContent(
-                    result.result
-                ),
+                input_message_content=InputTextMessageContent(result.result),
             )
         )
         return answers
@@ -189,9 +182,7 @@ async def urban_func(answers, text):
             InlineQueryResultArticle(
                 title="Error",
                 description=results.result,
-                input_message_content=InputTextMessageContent(
-                    results.result
-                ),
+                input_message_content=InputTextMessageContent(results.result),
             )
         )
         return answers
@@ -249,9 +240,7 @@ async def wall_func(answers, text):
             InlineQueryResultArticle(
                 title="Error",
                 description=results.result,
-                input_message_content=InputTextMessageContent(
-                    results.result
-                ),
+                input_message_content=InputTextMessageContent(results.result),
             )
         )
         return answers
@@ -274,9 +263,7 @@ async def torrent_func(answers, text):
             InlineQueryResultArticle(
                 title="Error",
                 description=results.result,
-                input_message_content=InputTextMessageContent(
-                    results.result
-                ),
+                input_message_content=InputTextMessageContent(results.result),
             )
         )
         return answers
@@ -317,9 +304,7 @@ async def youtube_func(answers, text):
             InlineQueryResultArticle(
                 title="Error",
                 description=results.result,
-                input_message_content=InputTextMessageContent(
-                    results.result
-                ),
+                input_message_content=InputTextMessageContent(results.result),
             )
         )
         return answers
@@ -335,7 +320,9 @@ async def youtube_func(answers, text):
 **Duration:** {i.duration}
 **Uploaded:** {i.publish_time}
 **Description:** {i.long_desc}"""
-        description = f"{i.views} | {i.channel} | {i.duration} | {i.publish_time}"
+        description = (
+            f"{i.views} | {i.channel} | {i.duration} | {i.publish_time}"
+        )
         answers.append(
             InlineQueryResultArticle(
                 title=i.title,
@@ -357,9 +344,7 @@ async def lyrics_func(answers, text):
             InlineQueryResultArticle(
                 title="Error",
                 description=song.result,
-                input_message_content=InputTextMessageContent(
-                    song.result
-                ),
+                input_message_content=InputTextMessageContent(song.result),
             )
         )
         return answers
@@ -411,9 +396,7 @@ async def tg_search_func(answers, text, user_id):
         buttons.add(
             InlineKeyboardButton(
                 text="Origin",
-                url=message.link
-                if message.link
-                else "https://t.me/telegram",
+                url=message.link if message.link else "https://t.me/telegram",
             ),
             InlineKeyboardButton(
                 text="Search again",
@@ -474,9 +457,7 @@ async def music_inline_func(answers, query):
         messages_ids_and_duration.append(
             {
                 "message_id": f_.message_id,
-                "duration": f_.audio.duration
-                if f_.audio.duration
-                else 0,
+                "duration": f_.audio.duration if f_.audio.duration else 0,
             }
         )
     messages = list(
@@ -500,9 +481,7 @@ async def wiki_func(answers, text):
             InlineQueryResultArticle(
                 title="Error",
                 description=data.result,
-                input_message_content=InputTextMessageContent(
-                    data.result
-                ),
+                input_message_content=InputTextMessageContent(data.result),
             )
         )
         return answers
@@ -539,9 +518,7 @@ async def speedtest_init(query):
     msg = "**Click The Button Below To Perform A Speedtest**"
     button = InlineKeyboard(row_width=1)
     button.add(
-        InlineKeyboardButton(
-            text="Test", callback_data="test_speedtest"
-        )
+        InlineKeyboardButton(text="Test", callback_data="test_speedtest")
     )
     answers.append(
         InlineQueryResultArticle(
@@ -563,9 +540,7 @@ async def test_speedtest_cq(_, cq):
     inline_message_id = cq.inline_message_id
     await app.edit_inline_text(inline_message_id, "**Testing**")
     loop = asyncio.get_running_loop()
-    download, upload, info = await loop.run_in_executor(
-        None, test_speedtest
-    )
+    download, upload, info = await loop.run_in_executor(None, test_speedtest)
     msg = f"""
 **Download:** `{download}`
 **Upload:** `{upload}`
@@ -620,9 +595,7 @@ async def ping_func(answers):
     answers.append(
         InlineQueryResultArticle(
             title=ping,
-            input_message_content=InputTextMessageContent(
-                f"__**{ping}**__"
-            ),
+            input_message_content=InputTextMessageContent(f"__**{ping}**__"),
         )
     )
     return answers
@@ -633,9 +606,7 @@ async def yt_music_func(answers, url):
         url = (await arq.youtube(url)).result[0]
         url = f"https://youtube.com{url.url_suffix}"
     loop = asyncio.get_running_loop()
-    music = await loop.run_in_executor(
-        None, download_youtube_audio, url
-    )
+    music = await loop.run_in_executor(None, download_youtube_audio, url)
     if not music:
         msg = "**ERROR**\n__MUSIC TOO LONG__"
         answers.append(
@@ -664,9 +635,7 @@ async def yt_music_func(answers, url):
     os.remove(audio)
     os.remove(thumbnail)
     answers.append(
-        InlineQueryResultCachedDocument(
-            title=title, file_id=m.audio.file_id
-        )
+        InlineQueryResultCachedDocument(title=title, file_id=m.audio.file_id)
     )
     return answers
 
@@ -674,9 +643,7 @@ async def yt_music_func(answers, url):
 async def info_inline_func(answers, peer):
     not_found = InlineQueryResultArticle(
         title="PEER NOT FOUND",
-        input_message_content=InputTextMessageContent(
-            "PEER NOT FOUND"
-        ),
+        input_message_content=InputTextMessageContent("PEER NOT FOUND"),
     )
     try:
         user = await app.get_users(peer)
@@ -708,9 +675,7 @@ async def tmdb_func(answers, query):
             InlineQueryResultArticle(
                 title="Error",
                 description=response.result,
-                input_message_content=InputTextMessageContent(
-                    response.result
-                ),
+                input_message_content=InputTextMessageContent(response.result),
             )
         )
         return answers
@@ -722,9 +687,7 @@ async def tmdb_func(answers, query):
             genre = None
         else:
             genre = " | ".join(result.genre)
-        description = (
-            result.overview[0:900] if result.overview else "None"
-        )
+        description = result.overview[0:900] if result.overview else "None"
         caption = f"""
 **{result.title}**
 **Type:** {result.type}
@@ -761,9 +724,7 @@ async def image_func(answers, query):
             InlineQueryResultArticle(
                 title="Error",
                 description=results.result,
-                input_message_content=InputTextMessageContent(
-                    results.result
-                ),
+                input_message_content=InputTextMessageContent(results.result),
             )
         )
         return answers
@@ -817,9 +778,7 @@ async def execute_code(query):
             [
                 InlineQueryResultArticle(
                     title=lang,
-                    input_message_content=InputTextMessageContent(
-                        lang
-                    ),
+                    input_message_content=InputTextMessageContent(lang),
                 )
                 for lang in languages
             ][:49]
@@ -841,11 +800,7 @@ async def execute_code(query):
             res = response.result
             stdout, stderr = escape(res.stdout), escape(res.stderr)
             output = stdout or stderr
-            out = (
-                "STDOUT"
-                if stdout
-                else ("STDERR" if stderr else "No output")
-            )
+            out = "STDOUT" if stdout else ("STDERR" if stderr else "No output")
 
             msg = f"""
 **{lang.capitalize()}:**
@@ -858,9 +813,7 @@ async def execute_code(query):
                 InlineQueryResultArticle(
                     title="Executed",
                     description=output[:20],
-                    input_message_content=InputTextMessageContent(
-                        msg
-                    ),
+                    input_message_content=InputTextMessageContent(msg),
                 )
             )
     await query.answer(results=answers, cache_time=1)
@@ -906,9 +859,7 @@ async def cancel_task_button(_, query: CallbackQuery):
     keyb = None
 
     if tasks:
-        keyb = ikb(
-            {i: f"cancel_task_{i}" for i in list(tasks.keys())}
-        )
+        keyb = ikb({i: f"cancel_task_{i}" for i in list(tasks.keys())})
 
     await app.edit_inline_text(
         query.inline_message_id,

+ 5 - 15
wbb/utils/misc.py

@@ -88,28 +88,20 @@ def paginate_modules(page_n, module_dict, prefix, chat=None):
     # can only have a certain amount of buttons side by side
     if len(pairs) > COLUMN_SIZE:
         pairs = pairs[
-            modulo_page
-            * COLUMN_SIZE : COLUMN_SIZE
-            * (modulo_page + 1)
+            modulo_page * COLUMN_SIZE : COLUMN_SIZE * (modulo_page + 1)
         ] + [
             (
                 EqInlineKeyboardButton(
                     "❮",
-                    callback_data="{}_prev({})".format(
-                        prefix, modulo_page
-                    ),
+                    callback_data="{}_prev({})".format(prefix, modulo_page),
                 ),
                 EqInlineKeyboardButton(
                     "Back",
-                    callback_data="{}_home({})".format(
-                        prefix, modulo_page
-                    ),
+                    callback_data="{}_home({})".format(prefix, modulo_page),
                 ),
                 EqInlineKeyboardButton(
                     "❯",
-                    callback_data="{}_next({})".format(
-                        prefix, modulo_page
-                    ),
+                    callback_data="{}_next({})".format(prefix, modulo_page),
                 ),
             )
         ]
@@ -118,6 +110,4 @@ def paginate_modules(page_n, module_dict, prefix, chat=None):
 
 
 def is_module_loaded(name):
-    return (
-        not MOD_LOAD or name in MOD_LOAD
-    ) and name not in MOD_NOLOAD
+    return (not MOD_LOAD or name in MOD_LOAD) and name not in MOD_NOLOAD

+ 2 - 6
wbb/utils/stickerset.py

@@ -32,9 +32,7 @@ async def get_sticker_set_by_name(
     try:
         return await client.send(
             raw.functions.messages.GetStickerSet(
-                stickerset=raw.types.InputStickerSetShortName(
-                    short_name=name
-                )
+                stickerset=raw.types.InputStickerSetShortName(short_name=name)
             )
         )
     except errors.exceptions.not_acceptable_406.StickersetInvalid:
@@ -81,6 +79,4 @@ async def add_sticker_to_set(
 async def create_sticker(
     sticker: raw.base.InputDocument, emoji: str
 ) -> raw.base.InputStickerSetItem:
-    return raw.types.InputStickerSetItem(
-        document=sticker, emoji=emoji
-    )
+    return raw.types.InputStickerSetItem(document=sticker, emoji=emoji)