TheHamkerCat 5 jaren geleden
bovenliggende
commit
bfcc63f596
59 gewijzigde bestanden met toevoegingen van 1484 en 1395 verwijderingen
  1. 9 3
      sample_config.py
  2. 14 11
      wbb/__init__.py
  3. 27 47
      wbb/__main__.py
  4. 11 9
      wbb/core/decorators/errors.py
  5. 49 38
      wbb/core/types/InlineQueryResult.py
  6. 2 1
      wbb/core/types/__init__.py
  7. 1 1
      wbb/modules/__init__.py
  8. 65 41
      wbb/modules/admin.py
  9. 12 4
      wbb/modules/admin_misc.py
  10. 6 5
      wbb/modules/alive.py
  11. 83 59
      wbb/modules/anime.py
  12. 11 5
      wbb/modules/antiservice.py
  13. 2 1
      wbb/modules/arq.py
  14. 14 9
      wbb/modules/blacklist.py
  15. 5 4
      wbb/modules/carbon.py
  16. 27 17
      wbb/modules/chatbot.py
  17. 18 20
      wbb/modules/couple.py
  18. 3 3
      wbb/modules/covid.py
  19. 52 52
      wbb/modules/devs.py
  20. 31 18
      wbb/modules/filters.py
  21. 30 16
      wbb/modules/genstr.py
  22. 15 23
      wbb/modules/global_stats.py
  23. 56 52
      wbb/modules/greetings.py
  24. 8 8
      wbb/modules/images.py
  25. 4 2
      wbb/modules/info.py
  26. 67 149
      wbb/modules/inline.py
  27. 18 16
      wbb/modules/karma.py
  28. 12 6
      wbb/modules/locks.py
  29. 45 29
      wbb/modules/misc.py
  30. 52 27
      wbb/modules/music.py
  31. 10 7
      wbb/modules/notes.py
  32. 15 5
      wbb/modules/ocr.py
  33. 7 13
      wbb/modules/paste.py
  34. 26 21
      wbb/modules/pipes.py
  35. 41 19
      wbb/modules/pmpermit.py
  36. 1 0
      wbb/modules/reddit.py
  37. 8 5
      wbb/modules/regex.py
  38. 5 3
      wbb/modules/repo.py
  39. 23 16
      wbb/modules/reverse.py
  40. 20 23
      wbb/modules/rice.py
  41. 52 38
      wbb/modules/stickers.py
  42. 39 15
      wbb/modules/sudo.py
  43. 69 47
      wbb/modules/sudoers.py
  44. 15 7
      wbb/modules/telegraph.py
  45. 7 5
      wbb/modules/tts.py
  46. 45 33
      wbb/modules/userbot.py
  47. 3 3
      wbb/modules/webss.py
  48. 1 1
      wbb/utils/__init__.py
  49. 1 0
      wbb/utils/aiodownloader/__init__.py
  50. 32 26
      wbb/utils/aiodownloader/downloader.py
  51. 49 160
      wbb/utils/dbfunctions.py
  52. 2 2
      wbb/utils/fetch.py
  53. 20 11
      wbb/utils/files.py
  54. 22 25
      wbb/utils/functions.py
  55. 189 212
      wbb/utils/inlinefuncs.py
  56. 1 2
      wbb/utils/json_prettify.py
  57. 6 9
      wbb/utils/misc.py
  58. 2 2
      wbb/utils/pastebin.py
  59. 24 9
      wbb/utils/stickerset.py

+ 9 - 3
sample_config.py

@@ -2,6 +2,7 @@ HEROKU = True  # NOTE Make it false if you're not deploying on heroku.
 
 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")
@@ -21,12 +22,17 @@ else:
     API_ID = 123456
     API_HASH = "dfxcgs5s12hdcxfgdfz"
     USERBOT_PREFIX = "."
-    PHONE_NUMBER = "+916969696969" # Need for Helper Userbot
-    SUDO_USERS_ID = [4543744343, 543214651351] # Sudo users have full access to everythin, don't trust anyone
+    PHONE_NUMBER = "+916969696969"  # Need for Helper Userbot
+    SUDO_USERS_ID = [
+        4543744343,
+        543214651351,
+    ]  # Sudo users have full access to everythin, don't trust anyone
     LOG_GROUP_ID = -100125431255
     GBAN_LOG_GROUP_ID = -100125431255
     MESSAGE_DUMP_CHAT = -1001181696437
-    FERNET_ENCRYPTION_KEY = "iKMq0WZMnJKjMQxZWKtv-cplMuF_LoyshXj0XbTGGWM=" # Leave this as it is
+    FERNET_ENCRYPTION_KEY = (
+        "iKMq0WZMnJKjMQxZWKtv-cplMuF_LoyshXj0XbTGGWM="  # Leave this as it is
+    )
     WELCOME_DELAY_KICK_SEC = 300
     MONGO_DB_URI = "mongodb+srv://username:password@cluster0.ksiis.mongodb.net/YourDataBaseName?retryWrites=true&w=majority"
     # NOTE Don't make changes below this line

+ 14 - 11
wbb/__init__.py

@@ -22,16 +22,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+import asyncio
 import time
 from os import path
-from telegraph import Telegraph
-from Python_ARQ import ARQ
+
 from motor.motor_asyncio import AsyncIOMotorClient as MongoClient
-import asyncio
-from pyromod import listen
 from pyrogram import Client
+from pyromod import listen
+from Python_ARQ import ARQ
+from telegraph import Telegraph
+
 print("[INFO]: INITIALIZING")
-is_config = path.exists('config.py')
+is_config = path.exists("config.py")
 if is_config:
     from config import *
 else:
@@ -54,29 +56,30 @@ print("[INFO]: LOADING MONGODB")
 mongo_client = MongoClient(MONGO_DB_URI)
 db = mongo_client.wbb
 
+
 async def load_sudoers():
     global SUDOERS
     print("[INFO]: LOADING SUDOERS")
     sudoersdb = db.sudoers
     sudoers = await sudoersdb.find_one({"sudo": "sudo"})
-    sudoers = [] if not sudoers else sudoers['sudoers']
+    sudoers = [] if not sudoers else sudoers["sudoers"]
     for user_id in SUDOERS:
         if user_id not in sudoers:
             sudoers.append(user_id)
             await sudoersdb.update_one(
-                {"sudo": "sudo"},
-                {"$set": {"sudoers": sudoers}},
-                upsert=True
+                {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True
             )
     SUDOERS = (SUDOERS + sudoers) if sudoers else SUDOERS
 
+
 loop = asyncio.get_event_loop()
 loop.run_until_complete(load_sudoers())
 
 if not HEROKU:
     print("[INFO]: LOADING USERBOT CLIENT")
-    app2 = Client("userbot", phone_number=PHONE_NUMBER,
-                  api_id=API_ID, api_hash=API_HASH)
+    app2 = Client(
+        "userbot", phone_number=PHONE_NUMBER, api_id=API_ID, api_hash=API_HASH
+    )
 else:
     print("[INFO]: LOADING USERBOT CLIENT")
     app2 = Client(SESSION_STRING, api_id=API_ID, api_hash=API_HASH)

+ 27 - 47
wbb/__main__.py

@@ -22,15 +22,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 import asyncio
-import re
 import importlib
+import re
+
 import uvloop
 from pyrogram import filters, idle
 from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
-from wbb import app, BOT_NAME, BOT_USERNAME, USERBOT_NAME
-from wbb.utils import paginate_modules
-from wbb.modules.sudoers import bot_sys_stats
+
+from wbb import BOT_NAME, BOT_USERNAME, USERBOT_NAME, app
 from wbb.modules import ALL_MODULES
+from wbb.modules.sudoers import bot_sys_stats
+from wbb.utils import paginate_modules
 
 loop = asyncio.get_event_loop()
 
@@ -41,18 +43,10 @@ async def start_bot():
     global COMMANDS_COUNT
     for module in ALL_MODULES:
         imported_module = importlib.import_module("wbb.modules." + module)
-        if (
-            hasattr(imported_module, "__MODULE__")
-            and imported_module.__MODULE__
-        ):
+        if hasattr(imported_module, "__MODULE__") and imported_module.__MODULE__:
             imported_module.__MODULE__ = imported_module.__MODULE__
-            if (
-                hasattr(imported_module, "__HELP__")
-                and imported_module.__HELP__
-            ):
-                HELPABLE[
-                    imported_module.__MODULE__.lower()
-                ] = imported_module
+            if hasattr(imported_module, "__HELP__") and imported_module.__HELP__:
+                HELPABLE[imported_module.__MODULE__.lower()] = imported_module
     bot_modules = ""
     j = 1
     for i in ALL_MODULES:
@@ -91,18 +85,14 @@ async def help_command(_, message):
                     InlineKeyboardButton(
                         text="Repo 🛠",
                         url="https://github.com/thehamkercat/WilliamButcherBot",
-                    )
+                    ),
                 ],
                 [
                     InlineKeyboardButton(
-                        text="System Stats 💻",
-                        callback_data="stats_callback"
+                        text="System Stats 💻", callback_data="stats_callback"
                     ),
-                    InlineKeyboardButton(
-                        text="Support 👨",
-                        url="t.me/WBBSupport"
-                    )
-                ]
+                    InlineKeyboardButton(text="Support 👨", url="t.me/WBBSupport"),
+                ],
             ]
         )
         await message.reply("Pm Me For More Details.", reply_markup=keyboard)
@@ -110,34 +100,30 @@ async def help_command(_, message):
     keyboard = InlineKeyboardMarkup(
         [
             [
-                InlineKeyboardButton(
-                    text="Commands ❓",
-                    callback_data="bot_commands"
-                ),
+                InlineKeyboardButton(text="Commands ❓", callback_data="bot_commands"),
                 InlineKeyboardButton(
                     text="Repo 🛠",
-                    url="https://github.com/thehamkercat/WilliamButcherBot"
-                )
+                    url="https://github.com/thehamkercat/WilliamButcherBot",
+                ),
             ],
             [
                 InlineKeyboardButton(
-                    text="System Stats 🖥",
-                    callback_data="stats_callback"
+                    text="System Stats 🖥", callback_data="stats_callback"
                 ),
-                InlineKeyboardButton(
-                    text="Support 👨",
-                    url="t.me/WBBSupport"
-                )
+                InlineKeyboardButton(text="Support 👨", url="t.me/WBBSupport"),
             ],
             [
                 InlineKeyboardButton(
                     text="Add Me To Your Group 🎉",
-                    url=f"http://t.me/{BOT_USERNAME}?startgroup=new"
+                    url=f"http://t.me/{BOT_USERNAME}?startgroup=new",
                 )
-            ]
+            ],
         ]
     )
-    await message.reply(f"Hey there! My name is {BOT_NAME}. I can manage your group with lots of useful features, feel free to add me to your group.", reply_markup=keyboard)
+    await message.reply(
+        f"Hey there! My name is {BOT_NAME}. I can manage your group with lots of useful features, feel free to add me to your group.",
+        reply_markup=keyboard,
+    )
 
 
 async def help_parser(name, keyboard=None):
@@ -163,9 +149,7 @@ General command are:
 async def commands_callbacc(_, CallbackQuery):
     text, keyboard = await help_parser(CallbackQuery.from_user.mention)
     await app.send_message(
-        CallbackQuery.message.chat.id,
-        text=text,
-        reply_markup=keyboard
+        CallbackQuery.message.chat.id, text=text, reply_markup=keyboard
     )
 
     await CallbackQuery.message.delete()
@@ -197,9 +181,7 @@ General command are:
     if mod_match:
         module = mod_match.group(1)
         text = (
-            "{} **{}**:\n".format(
-                "Here is the help for", HELPABLE[module].__MODULE__
-            )
+            "{} **{}**:\n".format("Here is the help for", HELPABLE[module].__MODULE__)
             + HELPABLE[module].__HELP__
         )
 
@@ -234,9 +216,7 @@ General command are:
     elif back_match:
         await query.message.edit(
             text=top_text,
-            reply_markup=InlineKeyboardMarkup(
-                paginate_modules(0, HELPABLE, "help")
-            ),
+            reply_markup=InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help")),
             disable_web_page_preview=True,
         )
 

+ 11 - 9
wbb/core/decorators/errors.py

@@ -2,16 +2,18 @@
 import sys
 import traceback
 from functools import wraps
-from wbb import app, LOG_GROUP_ID
+
 from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
 
+from wbb import LOG_GROUP_ID, app
+
 
 def split_limits(text):
     if len(text) < 2048:
         return [text]
 
     lines = text.splitlines(True)
-    small_msg = ''
+    small_msg = ""
     result = []
     for line in lines:
         if len(small_msg) + len(line) < 2048:
@@ -36,20 +38,20 @@ def capture_err(func):
         except Exception as err:
             exc_type, exc_obj, exc_tb = sys.exc_info()
             errors = traceback.format_exception(
-                etype=exc_type, value=exc_obj, tb=exc_tb,
+                etype=exc_type,
+                value=exc_obj,
+                tb=exc_tb,
             )
             error_feedback = split_limits(
-                '**ERROR** | `{}` | `{}`\n\n```{}```\n\n```{}```\n'.format(
+                "**ERROR** | `{}` | `{}`\n\n```{}```\n\n```{}```\n".format(
                     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),
+                    "".join(errors),
                 ),
             )
             for x in error_feedback:
-                await app.send_message(
-                    LOG_GROUP_ID,
-                    x
-                )
+                await app.send_message(LOG_GROUP_ID, x)
             raise err
+
     return capture

+ 49 - 38
wbb/core/types/InlineQueryResult.py

@@ -1,8 +1,9 @@
-from typing import Optional, List, Union
+from typing import List, Optional, Union
+
+import pyrogram
 from pyrogram import raw, types, utils
-from pyrogram.file_id import FileType, FileId, PHOTO_TYPES, DOCUMENT_TYPES
+from pyrogram.file_id import DOCUMENT_TYPES, PHOTO_TYPES, FileId, FileType
 from pyrogram.types import InlineQueryResult
-import pyrogram
 
 
 class InlineQueryResultAudio(InlineQueryResult):
@@ -71,13 +72,13 @@ class InlineQueryResultAudio(InlineQueryResult):
         parse_mode: Optional[str] = object,
         caption_entities: List["types.MessageEntity"] = None,
         reply_markup: "types.InlineKeyboardMarkup" = None,
-        input_message_content: "types.InputMessageContent" = None
+        input_message_content: "types.InputMessageContent" = None,
     ):
         super().__init__("audio", id, input_message_content, reply_markup)
 
         self.audio_url = audio_url
         self.thumb_url = thumb_url
-        self.voice = True if self.mime_type == 'audio/ogg' else False
+        self.voice = True if self.mime_type == "audio/ogg" else False
         self.title = title
         self.caption = caption
         self.description = description
@@ -91,31 +92,33 @@ class InlineQueryResultAudio(InlineQueryResult):
 
         if mime_type == "text/html" and input_message_content is None:
             raise ValueError(
-                "input_message_content is required for audio with `text/html` mime type")
+                "input_message_content is required for audio with `text/html` mime type"
+            )
 
     async def write(self, client: "pyrogram.Client"):
         audio = raw.types.InputWebDocument(
-            url=self.audio_url,
-            size=0,
-            mime_type=self.mime_type,
-            attributes=[]
+            url=self.audio_url, size=0, mime_type=self.mime_type, attributes=[]
         )
 
         thumb = raw.types.InputWebDocument(
             url=self.thumb_url,
             size=0,
             mime_type="image/jpeg",
-            attributes=[raw.types.DocumentAttributeAudio(
-                duration=self.duration,
-                voice=self.voice,
-                title=self.title,
-                performer=self.performer,
-            )]
+            attributes=[
+                raw.types.DocumentAttributeAudio(
+                    duration=self.duration,
+                    voice=self.voice,
+                    title=self.title,
+                    performer=self.performer,
+                )
+            ],
         )
 
-        message, entities = (await utils.parse_text_entities(
-            client, self.caption, self.parse_mode, self.caption_entities
-        )).values()
+        message, entities = (
+            await utils.parse_text_entities(
+                client, self.caption, self.parse_mode, self.caption_entities
+            )
+        ).values()
 
         return raw.types.InputBotInlineResult(
             id=self.id,
@@ -128,10 +131,13 @@ class InlineQueryResultAudio(InlineQueryResult):
                 await self.input_message_content.write(client, self.reply_markup)
                 if self.input_message_content
                 else raw.types.InputBotInlineMessageMediaAuto(
-                    reply_markup=await self.reply_markup.write(client) if self.reply_markup else None,
+                    reply_markup=await self.reply_markup.write(client)
+                    if self.reply_markup
+                    else None,
                     message=message,
-                    entities=entities)
-            )
+                    entities=entities,
+                )
+            ),
         )
 
 
@@ -193,7 +199,7 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
         parse_mode: Optional[str] = object,
         caption_entities: List["types.MessageEntity"] = None,
         reply_markup: "types.InlineKeyboardMarkup" = None,
-        input_message_content: "types.InputMessageContent" = None
+        input_message_content: "types.InputMessageContent" = None,
     ):
         super().__init__("file", id, input_message_content, reply_markup)
 
@@ -209,9 +215,11 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
     async def write(self, client: "pyrogram.Client"):
         document = get_input_file_from_file_id(self.file_id)
 
-        message, entities = (await utils.parse_text_entities(
-            client, self.caption, self.parse_mode, self.caption_entities
-        )).values()
+        message, entities = (
+            await utils.parse_text_entities(
+                client, self.caption, self.parse_mode, self.caption_entities
+            )
+        ).values()
 
         return raw.types.InputBotInlineResultDocument(
             id=self.id,
@@ -223,46 +231,49 @@ class InlineQueryResultCachedDocument(InlineQueryResult):
                 await self.input_message_content.write(client, self.reply_markup)
                 if self.input_message_content
                 else raw.types.InputBotInlineMessageMediaAuto(
-                    reply_markup=await self.reply_markup.write(client) if self.reply_markup else None,
+                    reply_markup=await self.reply_markup.write(client)
+                    if self.reply_markup
+                    else None,
                     message=message,
-                    entities=entities
+                    entities=entities,
                 )
-            )
+            ),
         )
 
 
 def get_input_file_from_file_id(
-    file_id: str,
-    expected_file_type: FileType = None
+    file_id: str, expected_file_type: FileType = None
 ) -> Union["raw.types.InputPhoto", "raw.types.InputDocument"]:
     try:
         decoded = FileId.decode(file_id)
     except Exception:
-        raise ValueError(f'Failed to decode "{file_id}". The value does not represent an existing local file, '
-                         f'HTTP URL, or valid file id.')
+        raise ValueError(
+            f'Failed to decode "{file_id}". The value does not represent an existing local file, '
+            f"HTTP URL, or valid file id."
+        )
 
     file_type = decoded.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')
+            f'Expected: "{expected_file_type}", got "{file_type}" file_id instead'
+        )
 
     if file_type in (FileType.THUMBNAIL, FileType.CHAT_PHOTO):
-        raise ValueError(
-            f"This file_id can only be used for download: {file_id}")
+        raise ValueError(f"This file_id can only be used for download: {file_id}")
 
     if file_type in PHOTO_TYPES:
         return raw.types.InputPhoto(
             id=decoded.media_id,
             access_hash=decoded.access_hash,
-            file_reference=decoded.file_reference
+            file_reference=decoded.file_reference,
         )
 
     if file_type in DOCUMENT_TYPES:
         return raw.types.InputDocument(
             id=decoded.media_id,
             access_hash=decoded.access_hash,
-            file_reference=decoded.file_reference
+            file_reference=decoded.file_reference,
         )
 
     raise ValueError(f"Unknown file id: {file_id}")

+ 2 - 1
wbb/core/types/__init__.py

@@ -1,3 +1,4 @@
 # flake8: noqa
 
-from .InlineQueryResult import InlineQueryResultCachedDocument, InlineQueryResultAudio
+from .InlineQueryResult import (InlineQueryResultAudio,
+                                InlineQueryResultCachedDocument)

+ 1 - 1
wbb/modules/__init__.py

@@ -24,8 +24,8 @@ SOFTWARE.
 import glob
 import importlib
 import sys
+from os.path import basename, dirname, isfile
 
-from os.path import dirname, basename, isfile
 from wbb import MOD_LOAD, MOD_NOLOAD
 
 

+ 65 - 41
wbb/modules/admin.py

@@ -21,15 +21,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+import asyncio
+
 from pyrogram import filters
 from pyrogram.types import ChatPermissions
-from wbb import SUDOERS, app, BOT_ID
+
+from wbb import BOT_ID, SUDOERS, app
 from wbb.core.decorators.errors import capture_err
-from wbb.utils.dbfunctions import add_warn, get_warn, remove_warns, int_to_alpha
-import asyncio
+from wbb.utils.dbfunctions import (add_warn, get_warn, int_to_alpha,
+                                   remove_warns)
 
 __MODULE__ = "Admin"
-__HELP__ = '''/ban - Ban A User
+__HELP__ = """/ban - Ban A User
 /unban - Unban A User
 /warn - Warn A User
 /rmwarns - Remove All Warning of A User
@@ -42,20 +45,19 @@ __HELP__ = '''/ban - Ban A User
 /mute - Mute A User
 /unmute - Unmute A User
 /ban_ghosts - Ban Deleted Accounts
-/report | @admins - Report A Message To Admins.'''
+/report | @admins - Report A Message To Admins."""
 
 
 async def list_admins(chat_id):
     list_of_admins = []
-    async for member in app.iter_chat_members(
-            chat_id, filter="administrators"):
+    async for member in app.iter_chat_members(chat_id, filter="administrators"):
         list_of_admins.append(member.user.id)
     return list_of_admins
 
 
 async def member_permissions(chat_id, user_id):
     perms = []
-    member = (await app.get_chat_member(chat_id, user_id))
+    member = await app.get_chat_member(chat_id, user_id)
     if member.can_post_messages:
         perms.append("can_post_messages")
     if member.can_edit_messages:
@@ -115,6 +117,7 @@ async def list_members(group_id):
         list_of_members.append(member.user.id)
     return list_of_members
 
+
 # Purge Messages
 
 
@@ -131,25 +134,22 @@ async def purge(client, message):
         if "can_delete_messages" in permissions or user_id in SUDOERS:
             if message.reply_to_message:
                 for a_s_message_id in range(
-                    message.reply_to_message.message_id,
-                    message.message_id
+                    message.reply_to_message.message_id, message.message_id
                 ):
                     message_ids.append(a_s_message_id)
                     if len(message_ids) == 100:
-                        await client.delete_messages(chat_id=chat_id,
-                                                     message_ids=message_ids,
-                                                     revoke=True)
+                        await client.delete_messages(
+                            chat_id=chat_id, message_ids=message_ids, revoke=True
+                        )
                         message_ids = []
                 if len(message_ids) > 0:
                     await client.delete_messages(
-                        chat_id=chat_id,
-                        message_ids=message_ids,
-                        revoke=True
+                        chat_id=chat_id, message_ids=message_ids, revoke=True
                     )
             else:
                 await message.reply_text(
-                    "Reply To A Message To Delete It,"
-                    " Don't Make Fun Of Yourself!")
+                    "Reply To A Message To Delete It," " Don't Make Fun Of Yourself!"
+                )
         else:
             await message.reply_text("Your Don't Have Enough Permissions!")
         await message.delete()
@@ -157,6 +157,7 @@ async def purge(client, message):
         print(e)
         await message.reply_text(e)
 
+
 # Kick members
 
 
@@ -175,7 +176,9 @@ async def kick(_, message):
         elif len(message.command) == 1 and message.reply_to_message:
             user_id = message.reply_to_message.from_user.id
         else:
-            await message.reply_text("Provide a username or reply to a user's message to kick.")
+            await message.reply_text(
+                "Provide a username or reply to a user's message to kick."
+            )
             return
         if user_id in SUDOERS:
             await message.reply_text("You Wanna Kick The Elevated One?")
@@ -188,6 +191,7 @@ async def kick(_, message):
         print(e)
         await message.reply_text(e)
 
+
 # Ban members
 
 
@@ -206,7 +210,9 @@ async def ban(_, message):
         elif len(message.command) == 1 and message.reply_to_message:
             user_id = message.reply_to_message.from_user.id
         else:
-            await message.reply_text("Provide a username or reply to a user's message to ban.")
+            await message.reply_text(
+                "Provide a username or reply to a user's message to ban."
+            )
             return
         if user_id in SUDOERS:
             await message.reply_text("You Wanna Ban The Elevated One?")
@@ -235,7 +241,9 @@ async def unban(_, message):
         elif len(message.command) == 1 and message.reply_to_message:
             user = message.reply_to_message.from_user.id
         else:
-            await message.reply_text("Provide a username or reply to a user's message to unban.")
+            await message.reply_text(
+                "Provide a username or reply to a user's message to unban."
+            )
             return
         await message.chat.unban_member(user)
         await message.reply_text("Unbanned!")
@@ -257,14 +265,16 @@ async def delete(_, message):
         chat_id = message.chat.id
         permissions = await member_permissions(chat_id, from_user_id)
         if "can_delete_messages" not in permissions and from_user_id not in SUDOERS:
-            await message.reply_text("You Don't Have Enough Permissions,"
-                                     + " Consider Deleting Yourself!")
+            await message.reply_text(
+                "You Don't Have Enough Permissions," + " Consider Deleting Yourself!"
+            )
             return
         await message.reply_to_message.delete()
         await message.delete()
     except Exception as e:
         await message.reply_text(str(e))
 
+
 # Promote Members
 
 
@@ -285,7 +295,9 @@ async def promote(_, message):
         elif len(message.command) == 1 and message.reply_to_message:
             user_id = message.reply_to_message.from_user.id
         else:
-            await message.reply_text("Reply To A User's Message Or Give A Username To Promote.")
+            await message.reply_text(
+                "Reply To A User's Message Or Give A Username To Promote."
+            )
             return
         await message.chat.promote_member(
             user_id=user_id,
@@ -296,13 +308,14 @@ async def promote(_, message):
             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
+            can_manage_voice_chats=bot.can_manage_voice_chats,
         )
-        await message.reply_text('Promoted!')
+        await message.reply_text("Promoted!")
 
     except Exception as e:
         await message.reply_text(str(e))
 
+
 # Pin Messages
 
 
@@ -343,19 +356,19 @@ async def mute(_, message):
         elif len(message.command) == 1 and message.reply_to_message:
             user_id = message.reply_to_message.from_user.id
         else:
-            await message.reply_text("Provide a username or reply to a user's message to mute.")
+            await message.reply_text(
+                "Provide a username or reply to a user's message to mute."
+            )
             return
         if user_id in SUDOERS:
             await message.reply_text("You Wanna Mute The Elevated One?")
             return
-        await message.chat.restrict_member(
-            user_id,
-            permissions=ChatPermissions()
-        )
+        await message.chat.restrict_member(user_id, permissions=ChatPermissions())
         await message.reply_text("Muted!")
     except Exception as e:
         await message.reply_text(str(e))
 
+
 # Unmute members
 
 
@@ -374,7 +387,9 @@ async def unmute(_, message):
         elif len(message.command) == 1 and message.reply_to_message:
             user = message.reply_to_message.from_user.id
         else:
-            await message.reply_text("Provide a username or reply to a user's message to Unmute")
+            await message.reply_text(
+                "Provide a username or reply to a user's message to Unmute"
+            )
             return
         await message.chat.unban_member(user)
         await message.reply_text("Unmuted!")
@@ -441,20 +456,26 @@ async def warn_user(_, message):
                 if user_id in await list_members(chat_id):
                     warns = await get_warn(chat_id, await int_to_alpha(user_id))
                     if warns:
-                        warns = warns['warns']
+                        warns = warns["warns"]
                     else:
                         warn = {"warns": 1}
                         await add_warn(chat_id, await int_to_alpha(user_id), warn)
-                        await message.reply_text(f"Warned {mention} !, 1/3 warnings now.")
+                        await message.reply_text(
+                            f"Warned {mention} !, 1/3 warnings now."
+                        )
                         return
                     if warns >= 2:
                         await message.chat.kick_member(user_id)
-                        await message.reply_text(f"Number of warns of {mention} exceeded, Banned!")
+                        await message.reply_text(
+                            f"Number of warns of {mention} exceeded, Banned!"
+                        )
                         await remove_warns(chat_id, await int_to_alpha(user_id))
                     else:
-                        warn = {"warns": warns+1}
+                        warn = {"warns": warns + 1}
                         await add_warn(chat_id, await int_to_alpha(user_id), warn)
-                        await message.reply_text(f"Warned {mention} !, {warns+1}/3 warnings now.")
+                        await message.reply_text(
+                            f"Warned {mention} !, {warns+1}/3 warnings now."
+                        )
                 else:
                     await message.reply_text("This user isn't here.")
         else:
@@ -481,7 +502,7 @@ async def remove_warnings(_, message):
         if "can_restrict_members" in permissions or from_user_id in SUDOERS:
             warns = await get_warn(chat_id, await int_to_alpha(user_id))
             if warns:
-                warns = warns['warns']
+                warns = warns["warns"]
             if warns == 0 or not warns:
                 await message.reply_text(f"{mention} have no warnings.")
             else:
@@ -510,7 +531,7 @@ async def check_warns(_, message):
         if message.reply_to_message:
             warns = await get_warn(chat_id, await int_to_alpha(user_id))
             if warns:
-                warns = warns['warns']
+                warns = warns["warns"]
             else:
                 await message.reply_text(f"{mention_user} have no warnings.")
                 return
@@ -518,7 +539,7 @@ async def check_warns(_, message):
             return
         warns = await get_warn(chat_id, await int_to_alpha(user_id))
         if warns:
-            warns = warns['warns']
+            warns = warns["warns"]
         else:
             await message.reply_text(f"{mention_user} have no warnings.")
             return
@@ -526,10 +547,13 @@ async def check_warns(_, message):
     except Exception as e:
         await message.reply_text(str(e))
 
+
 # Report
 
 
-@app.on_message(filters.command(["report", "admins"], prefixes=["@", "/"]) & ~filters.edited)
+@app.on_message(
+    filters.command(["report", "admins"], prefixes=["@", "/"]) & ~filters.edited
+)
 @capture_err
 async def report_user(_, message):
     if not message.reply_to_message:

+ 12 - 4
wbb/modules/admin_misc.py

@@ -21,11 +21,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+import os
+
 from pyrogram import filters
+
 from wbb import SUDOERS, app
 from wbb.core.decorators.errors import capture_err
 from wbb.modules.admin import member_permissions
-import os
 
 __MODULE__ = "Admin Miscs"
 __HELP__ = """
@@ -52,7 +54,9 @@ async def set_chat_title(_, message):
         old_title = message.chat.title
         new_title = message.text.split(None, 1)[1]
         await message.chat.set_title(new_title)
-        await message.reply_text(f"Successfully Changed Group Title From {old_title} To {new_title}")
+        await message.reply_text(
+            f"Successfully Changed Group Title From {old_title} To {new_title}"
+        )
     except Exception as e:
         print(e)
         await message.reply_text(e)
@@ -71,11 +75,15 @@ async def set_user_title(_, message):
                 await message.reply_text("You Don't Have Enough Permissions.")
                 return
         if len(message.command) < 2:
-            await message.reply_text("**Usage:**\n/set_user_title NEW ADMINISTRATOR TITLE")
+            await message.reply_text(
+                "**Usage:**\n/set_user_title NEW ADMINISTRATOR TITLE"
+            )
             return
         title = message.text.split(None, 1)[1]
         await app.set_administrator_title(chat_id, from_user.id, title)
-        await message.reply_text(f"Successfully Changed {from_user.mention}'s Admin Title To {title}")
+        await message.reply_text(
+            f"Successfully Changed {from_user.mention}'s Admin Title To {title}"
+        )
     except Exception as e:
         print(e)
         await message.reply_text(e)

+ 6 - 5
wbb/modules/alive.py

@@ -22,16 +22,17 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 
-from wbb import app2, BOT_ID, SUDOERS, USERBOT_PREFIX
 from pyrogram import filters
 
+from wbb import BOT_ID, SUDOERS, USERBOT_PREFIX, app2
 
-@app2.on_message(filters.command("alive", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS))
+
+@app2.on_message(
+    filters.command("alive", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
 async def alive_command_func(_, message):
     await message.delete()
     results = await app2.get_inline_bot_results(BOT_ID, "alive")
     await app2.send_inline_bot_result(
-        message.chat.id,
-        results.query_id,
-        results.results[0].id
+        message.chat.id, results.query_id, results.results[0].id
     )

+ 83 - 59
wbb/modules/anime.py

@@ -1,10 +1,12 @@
 # Part of Pull Req #2 by @MaskedVirus | github.com/swatv3nub
 
 import time
-import requests
 from datetime import timedelta
+
+import requests
 from pyrogram import filters
-from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
+from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
 
@@ -16,10 +18,10 @@ __HELP__ = """
 """
 
 
-def shorten(description, info='anilist.co'):
+def shorten(description, info="anilist.co"):
     ms_g = ""
     if len(description) > 700:
-        description = description[0:500] + '....'
+        description = description[0:500] + "...."
         ms_g += f"\n**Description**: __{description}__[More here]({info})"
     else:
         ms_g += f"\n**Description**: __{description}__"
@@ -38,15 +40,17 @@ def t(milliseconds: int) -> str:
     minutes, seconds = divmod(seconds, 60)
     hours, minutes = divmod(minutes, 60)
     days, hours = divmod(hours, 24)
-    tmp = ((str(days) + " Days, ") if days else "") + \
-        ((str(hours) + " Hours, ") if hours else "") + \
-        ((str(minutes) + " Minutes, ") if minutes else "") + \
-        ((str(seconds) + " Seconds, ") if seconds else "") + \
-        ((str(milliseconds) + " ms, ") if milliseconds else "")
+    tmp = (
+        ((str(days) + " Days, ") if days else "")
+        + ((str(hours) + " Hours, ") if hours else "")
+        + ((str(minutes) + " Minutes, ") if minutes else "")
+        + ((str(seconds) + " Seconds, ") if seconds else "")
+        + ((str(milliseconds) + " ms, ") if milliseconds else "")
+    )
     return tmp[:-2]
 
 
-airing_query = '''
+airing_query = """
     query ($id: Int,$search: String) {
       Media (id: $id, type: ANIME,search: $search) {
         id
@@ -64,7 +68,7 @@ airing_query = '''
         }
       }
     }
-    '''
+    """
 
 fav_query = """
 query ($id: Int) {
@@ -79,7 +83,7 @@ query ($id: Int) {
 }
 """
 
-anime_query = '''
+anime_query = """
    query ($id: Int,$search: String) {
       Media (id: $id, type: ANIME,search: $search) {
         id
@@ -115,7 +119,7 @@ anime_query = '''
           bannerImage
       }
     }
-'''
+"""
 character_query = """
     query ($query: String) {
         Character (search: $query) {
@@ -164,7 +168,7 @@ def format_bytes(size):
     size = int(size)
     power = 1024
     n = 0
-    power_labels = {0: '', 1: 'K', 2: 'M', 3: 'G', 4: 'T'}
+    power_labels = {0: "", 1: "K", 2: "M", 3: "G", 4: "T"}
     while size > power:
         size /= power
         n += 1
@@ -173,22 +177,21 @@ def format_bytes(size):
 
 def return_progress_string(current, total):
     filled_length = int(30 * current // total)
-    return '[' + '=' * filled_length + ' ' * (30 - filled_length) + ']'
+    return "[" + "=" * filled_length + " " * (30 - filled_length) + "]"
 
 
 def calculate_eta(current, total, start_time):
     if not current:
-        return '00:00:00'
+        return "00:00:00"
     end_time = time.time()
     elapsed_time = end_time - start_time
     seconds = (elapsed_time * (total / current)) - elapsed_time
-    thing = ''.join(str(timedelta(seconds=seconds)
-                        ).split('.')[:-1]).split(', ')
-    thing[-1] = thing[-1].rjust(8, '0')
-    return ', '.join(thing)
+    thing = "".join(str(timedelta(seconds=seconds)).split(".")[:-1]).split(", ")
+    thing[-1] = thing[-1].rjust(8, "0")
+    return ", ".join(thing)
 
 
-url = 'https://graphql.anilist.co'
+url = "https://graphql.anilist.co"
 
 
 @app.on_message(filters.command("anime"))
@@ -198,41 +201,50 @@ async def anime_search(_, message):
         await message.delete()
         return
     search = message.text.split(None, 1)[1]
-    variables = {'search': search}
-    json = requests.post(url, json={'query': anime_query, 'variables': variables}).json()[
-        'data'].get('Media', None)
+    variables = {"search": search}
+    json = (
+        requests.post(url, json={"query": anime_query, "variables": variables})
+        .json()["data"]
+        .get("Media", None)
+    )
     if json:
         msg = f"**{json['title']['romaji']}**(`{json['title']['native']}`)\n**Type**: {json['format']}\n**Status**: {json['status']}\n**Episodes**: {json.get('episodes', 'N/A')}\n**Duration**: {json.get('duration', 'N/A')} Per Ep.\n**Score**: {json['averageScore']}\n**Genres**: `"
-        for x in json['genres']:
+        for x in json["genres"]:
             msg += f"{x}, "
-        msg = msg[:-2] + '`\n'
+        msg = msg[:-2] + "`\n"
         msg += "**Studios**: `"
-        for x in json['studios']['nodes']:
+        for x in json["studios"]["nodes"]:
             msg += f"{x['name']}, "
-        msg = msg[:-2] + '`\n'
-        info = json.get('siteUrl')
-        trailer = json.get('trailer', None)
+        msg = msg[:-2] + "`\n"
+        info = json.get("siteUrl")
+        trailer = json.get("trailer", None)
         if trailer:
-            trailer_id = trailer.get('id', None)
-            site = trailer.get('site', None)
+            trailer_id = trailer.get("id", None)
+            site = trailer.get("site", None)
             if site == "youtube":
-                trailer = 'https://youtu.be/' + trailer_id
-        description = json.get(
-            'description', 'N/A').replace('<i>', '').replace('</i>', '').replace('<br>', '')
+                trailer = "https://youtu.be/" + trailer_id
+        description = (
+            json.get("description", "N/A")
+            .replace("<i>", "")
+            .replace("</i>", "")
+            .replace("<br>", "")
+        )
         msg += shorten(description, info)
-        image = info.replace('anilist.co/anime/', 'img.anili.st/media/')
+        image = info.replace("anilist.co/anime/", "img.anili.st/media/")
         if trailer:
             buttons = [
-                [InlineKeyboardButton("More Info", url=info),
-                 InlineKeyboardButton("Trailer", url=trailer)]
+                [
+                    InlineKeyboardButton("More Info", url=info),
+                    InlineKeyboardButton("Trailer", url=trailer),
+                ]
             ]
         else:
-            buttons = [
-                [InlineKeyboardButton("More Info", url=info)]
-            ]
+            buttons = [[InlineKeyboardButton("More Info", url=info)]]
         if image:
             try:
-                await message.reply_photo(image, caption=msg, reply_markup=InlineKeyboardMarkup(buttons))
+                await message.reply_photo(
+                    image, caption=msg, reply_markup=InlineKeyboardMarkup(buttons)
+                )
             except Exception:
                 msg += f" [✔️️]({image})"
                 await message.edit(msg)
@@ -247,15 +259,22 @@ async def manga_search(_, message):
         await message.delete()
         return
     search = message.text.split(None, 1)[1]
-    variables = {'search': search}
-    json = requests.post(url, json={'query': manga_query, 'variables': variables}).json()[
-        'data'].get('Media', None)
-    ms_g = ''
+    variables = {"search": search}
+    json = (
+        requests.post(url, json={"query": manga_query, "variables": variables})
+        .json()["data"]
+        .get("Media", None)
+    )
+    ms_g = ""
     if json:
-        title, title_native = json['title'].get(
-            'romaji', False), json['title'].get('native', False)
-        start_date, status, score = json['startDate'].get('year', False), json.get(
-            'status', False), json.get('averageScore', False)
+        title, title_native = json["title"].get("romaji", False), json["title"].get(
+            "native", False
+        )
+        start_date, status, score = (
+            json["startDate"].get("year", False),
+            json.get("status", False),
+            json.get("averageScore", False),
+        )
         if title:
             ms_g += f"**{title}**"
             if title_native:
@@ -266,8 +285,8 @@ async def manga_search(_, message):
             ms_g += f"\n**Status** - `{status}`"
         if score:
             ms_g += f"\n**Score** - `{score}`"
-        ms_g += '\n**Genres** - '
-        for x in json.get('genres', []):
+        ms_g += "\n**Genres** - "
+        for x in json.get("genres", []):
             ms_g += f"{x}, "
         ms_g = ms_g[:-2]
 
@@ -290,17 +309,22 @@ async def character_search(_, message):
         await message.delete()
         return
     search = message.text.split(None, 1)[1]
-    variables = {'query': search}
-    json = requests.post(url, json={'query': character_query, 'variables': variables}).json()[
-        'data'].get('Character', None)
+    variables = {"query": search}
+    json = (
+        requests.post(url, json={"query": character_query, "variables": variables})
+        .json()["data"]
+        .get("Character", None)
+    )
     if json:
-        ms_g = f"**{json.get('name').get('full')}**(`{json.get('name').get('native')}`)\n"
+        ms_g = (
+            f"**{json.get('name').get('full')}**(`{json.get('name').get('native')}`)\n"
+        )
         description = f"{json['description']}"
-        site_url = json.get('siteUrl')
+        site_url = json.get("siteUrl")
         ms_g += shorten(description, site_url)
-        image = json.get('image', None)
+        image = json.get("image", None)
         if image:
-            image = image.get('large')
+            image = image.get("large")
             await message.reply_photo(image, caption=ms_g)
         else:
             await message.reply(ms_g)

+ 11 - 5
wbb/modules/antiservice.py

@@ -1,11 +1,13 @@
 # Written By [MaskedVirus | swatv3nub] for William and Ryūga
 # Kang With Proper Credits
 
-from wbb import app
 from pyrogram import filters
-from wbb.modules.admin import member_permissions
+
+from wbb import app
 from wbb.core.decorators.errors import capture_err
-from wbb.utils.dbfunctions import is_antiservice_on, antiservice_on, antiservice_off
+from wbb.modules.admin import member_permissions
+from wbb.utils.dbfunctions import (antiservice_off, antiservice_on,
+                                   is_antiservice_on)
 
 __MODULE__ = "AntiService"
 __HELP__ = """
@@ -31,10 +33,14 @@ async def anti_service(_, message):
         return
     if status == "enable":
         await antiservice_on(chat_id)
-        await message.reply_text("Enabled AntiService System. I will Delete Service Messages from Now on.")
+        await message.reply_text(
+            "Enabled AntiService System. I will Delete Service Messages from Now on."
+        )
     elif status == "disable":
         await antiservice_off(chat_id)
-        await message.reply_text("Disabled AntiService System. I won't Be Deleting Service Message from Now on.")
+        await message.reply_text(
+            "Disabled AntiService System. I won't Be Deleting Service Message from Now on."
+        )
     else:
         await message.reply_text("Unknown Suffix, Use /antiservice [enable|disable]")
 

+ 2 - 1
wbb/modules/arq.py

@@ -21,9 +21,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app, arq, ARQ_API_BASE_URL
 from pyrogram import filters
 
+from wbb import ARQ_API_BASE_URL, app, arq
+
 
 @app.on_message(filters.command("arq"))
 async def arq_stats(_, message):

+ 14 - 9
wbb/modules/blacklist.py

@@ -21,17 +21,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app, SUDOERS
-from wbb.modules.admin import member_permissions, list_admins
-from wbb.utils.dbfunctions import (
-    save_blacklist_filter, get_blacklisted_words, delete_blacklist_filter
-)
+import re
+import traceback
+
 from pyrogram import filters
 from pyrogram.types import ChatPermissions
+
+from wbb import SUDOERS, app
 from wbb.core.decorators.errors import capture_err
+from wbb.modules.admin import list_admins, member_permissions
+from wbb.utils.dbfunctions import (delete_blacklist_filter,
+                                   get_blacklisted_words,
+                                   save_blacklist_filter)
 from wbb.utils.filter_groups import blacklist_filters_group
-import re
-import traceback
 
 __MODULE__ = "Blacklist"
 __HELP__ = """
@@ -119,8 +121,11 @@ async def blacklist_filters_re(_, message):
                     await message.chat.restrict_member(user.id, ChatPermissions())
                 except Exception:
                     return
-                await app.send_message(chat_id, f"Muted {user.mention} [`{user.id}`] due to a blacklist "
-                                       + f"match on {word}.")
+                await app.send_message(
+                    chat_id,
+                    f"Muted {user.mention} [`{user.id}`] due to a blacklist "
+                    + f"match on {word}.",
+                )
                 return
     except Exception as e:
         e = traceback.format_exc()

+ 5 - 4
wbb/modules/carbon.py

@@ -1,9 +1,10 @@
-from wbb import app
-from wbb.utils.functions import make_carbon
-from pyrogram import filters
-from wbb.core.decorators.errors import capture_err
 import os
 
+from pyrogram import filters
+
+from wbb import app
+from wbb.core.decorators.errors import capture_err
+from wbb.utils.functions import make_carbon
 
 __MODULE__ = "Carbon"
 __HELP__ = "/carbon - Make Carbon Of Code."

+ 27 - 17
wbb/modules/chatbot.py

@@ -21,15 +21,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import (
-    app, app2, arq, BOT_ID, SUDOERS, USERBOT_ID,
-    USERBOT_USERNAME, USERBOT_PREFIX
-)
+from pyrogram import filters
+
+from wbb import (BOT_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX, USERBOT_USERNAME,
+                 app, app2, arq)
 from wbb.core.decorators.errors import capture_err
 from wbb.modules.userbot import edit_or_reply
 from wbb.utils.filter_groups import chatbot_group
-from pyrogram import filters
-
 
 __MODULE__ = "ChatBot"
 __HELP__ = """
@@ -56,8 +54,7 @@ async def chatbot_status(_, message):
     if status == "ON" or status == "on" or status == "On":
         if chat_id not in active_chats_bot:
             active_chats_bot.append(chat_id)
-            text = "Chatbot Enabled Reply To Any Message " \
-                   + "Of Mine To Get A Reply"
+            text = "Chatbot Enabled Reply To Any Message " + "Of Mine To Get A Reply"
             await message.reply_text(text)
             return
         await message.reply_text("ChatBot Is Already Enabled.")
@@ -75,8 +72,10 @@ async def chatbot_status(_, message):
         await message.reply_text("**Usage**\n/chatbot [ON|OFF]")
 
 
-@app.on_message(filters.text & filters.reply & ~filters.bot &
-                ~filters.via_bot & ~filters.forwarded, group=chatbot_group)
+@app.on_message(
+    filters.text & filters.reply & ~filters.bot & ~filters.via_bot & ~filters.forwarded,
+    group=chatbot_group,
+)
 @capture_err
 async def chatbot_talk(_, message):
     if message.chat.id not in active_chats_bot:
@@ -94,7 +93,11 @@ async def chatbot_talk(_, message):
 """ FOR USERBOT """
 
 
-@app2.on_message(filters.command("chatbot", prefixes=USERBOT_PREFIX) & ~filters.edited & filters.user(SUDOERS))
+@app2.on_message(
+    filters.command("chatbot", prefixes=USERBOT_PREFIX)
+    & ~filters.edited
+    & filters.user(SUDOERS)
+)
 @capture_err
 async def chatbot_status_ubot(_, message):
     global active_chats_ubot
@@ -106,8 +109,7 @@ async def chatbot_status_ubot(_, message):
     if status == "ON" or status == "on" or status == "On":
         if chat_id not in active_chats_ubot:
             active_chats_ubot.append(chat_id)
-            text = "Chatbot Enabled Reply To Any Message " \
-                   + "Of Mine To Get A Reply"
+            text = "Chatbot Enabled Reply To Any Message " + "Of Mine To Get A Reply"
             await edit_or_reply(message, text=text)
             return
         await edit_or_reply(message, text="ChatBot Is Already Enabled.")
@@ -125,15 +127,20 @@ async def chatbot_status_ubot(_, message):
         await edit_or_reply(message, text="**Usage**\n/chatbot [ON|OFF]")
 
 
-@app2.on_message(~filters.me & ~filters.private & filters.text & ~filters.edited, group=chatbot_group)
+@app2.on_message(
+    ~filters.me & ~filters.private & filters.text & ~filters.edited, group=chatbot_group
+)
 @capture_err
 async def chatbot_talk_ubot(_, message):
     if message.chat.id not in active_chats_ubot:
         return
-    username = ("@" + str(USERBOT_USERNAME))
+    username = "@" + str(USERBOT_USERNAME)
     query = message.text
     if message.reply_to_message:
-        if message.reply_to_message.from_user.id != USERBOT_ID and username not in query:
+        if (
+            message.reply_to_message.from_user.id != USERBOT_ID
+            and username not in query
+        ):
             return
     else:
         if username not in query:
@@ -143,7 +150,10 @@ async def chatbot_talk_ubot(_, message):
     await message.reply_text(response)
 
 
-@app2.on_message(filters.text & filters.private & ~filters.me & ~filters.edited, group=(chatbot_group+1))
+@app2.on_message(
+    filters.text & filters.private & ~filters.me & ~filters.edited,
+    group=(chatbot_group + 1),
+)
 @capture_err
 async def chatbot_talk_ubot_pm(_, message):
     if message.chat.id not in active_chats_ubot:

+ 18 - 20
wbb/modules/couple.py

@@ -21,12 +21,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+import random
+from datetime import datetime
+
+from pyrogram import filters
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.dbfunctions import get_couple, save_couple
-from pyrogram import filters
-import random
-from datetime import datetime
 
 __MODULE__ = "Shippering"
 __HELP__ = "/detect_gay - To Choose Couple Of The Day"
@@ -36,13 +38,18 @@ __HELP__ = "/detect_gay - To Choose Couple Of The Day"
 def dt():
     now = datetime.now()
     dt_string = now.strftime("%d/%m/%Y %H:%M")
-    dt_list = dt_string.split(' ')
+    dt_list = dt_string.split(" ")
     return dt_list
 
 
 def dt_tom():
-    a = str(int(dt()[0].split('/')[0]) + 1)+"/" + \
-        dt()[0].split('/')[1]+"/" + dt()[0].split('/')[2]
+    a = (
+        str(int(dt()[0].split("/")[0]) + 1)
+        + "/"
+        + dt()[0].split("/")[1]
+        + "/"
+        + dt()[0].split("/")[2]
+    )
     return a
 
 
@@ -78,29 +85,20 @@ async def couple(_, message):
 {c1_mention} + {c2_mention} = ❤️
 
 __New couple of the day may be chosen at 12AM {tomorrow}__"""
-            await app.send_message(
-                message.chat.id,
-                text=couple_selection_message
-            )
-            couple = {
-                "c1_id": c1_id,
-                "c2_id": c2_id
-            }
+            await app.send_message(message.chat.id, text=couple_selection_message)
+            couple = {"c1_id": c1_id, "c2_id": c2_id}
             await save_couple(chat_id, today, couple)
 
         elif is_selected:
-            c1_id = int(is_selected['c1_id'])
-            c2_id = int(is_selected['c2_id'])
+            c1_id = int(is_selected["c1_id"])
+            c2_id = int(is_selected["c2_id"])
             c1_name = (await app.get_users(c1_id)).first_name
             c2_name = (await app.get_users(c2_id)).first_name
             couple_selection_message = f"""Couple of the day:
 [{c1_name}](tg://openmessage?user_id={c1_id}) + [{c2_name}](tg://openmessage?user_id={c2_id}) = ❤️
 
 __New couple of the day may be chosen at 12AM {tomorrow}__"""
-            await app.send_message(
-                message.chat.id,
-                text=couple_selection_message
-            )
+            await app.send_message(message.chat.id, text=couple_selection_message)
     except Exception as e:
         print(e)
         await message.reply_text(e)

+ 3 - 3
wbb/modules/covid.py

@@ -21,12 +21,12 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+from pyrogram import filters
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
-from wbb.utils.json_prettify import json_prettify
 from wbb.utils.fetch import fetch
-from pyrogram import filters
-
+from wbb.utils.json_prettify import json_prettify
 
 __MODULE__ = "Covid"
 __HELP__ = """/covid - To Get Global Stats of Covid.

+ 52 - 52
wbb/modules/devs.py

@@ -5,18 +5,20 @@
             https://github.com/pokurt/Nana-Remix/blob/master/nana/plugins/devs.py
 """
 
-import sys
-import traceback
-from io import StringIO
 import os
 import re
 import subprocess
+import sys
+import traceback
 from inspect import getfullargspec
-from wbb import app, SUDOERS
-from pyrogram import filters
-from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
+from io import StringIO
 from time import time
 
+from pyrogram import filters
+from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
+
+from wbb import SUDOERS, app
+
 __MODULE__ = "Devs"
 __HELP__ = "/eval - Execute Python Code\n/sh - Execute Shell Code"
 
@@ -35,7 +37,12 @@ async def edit_or_reply(msg: Message, **kwargs):
     await func(**{k: v for k, v in kwargs.items() if k in spec})
 
 
-@app.on_message(filters.user(SUDOERS) & ~filters.forwarded & ~filters.via_bot & filters.command("eval"))
+@app.on_message(
+    filters.user(SUDOERS)
+    & ~filters.forwarded
+    & ~filters.via_bot
+    & filters.command("eval")
+)
 async def executor(client, message):
     try:
         cmd = message.text.split(" ", maxsplit=1)[1]
@@ -68,38 +75,34 @@ async def executor(client, message):
         evaluation = stdout
     else:
         evaluation = "Success"
-    final_output = (f"**OUTPUT**:\n```{evaluation.strip()}```")
+    final_output = f"**OUTPUT**:\n```{evaluation.strip()}```"
     if len(final_output) > 4096:
         filename = "output.txt"
         with open(filename, "w+", encoding="utf8") as out_file:
             out_file.write(str(evaluation.strip()))
         t2 = time()
         keyboard = InlineKeyboardMarkup(
-            [[
-                InlineKeyboardButton(
-                    text="⏳",
-                    callback_data=f"runtime {t2-t1} Seconds"
-                )
-            ]]
+            [[InlineKeyboardButton(text="⏳", callback_data=f"runtime {t2-t1} Seconds")]]
         )
         await message.reply_document(
             document=filename,
             caption=cmd,
             disable_notification=True,
             reply_to_message_id=reply_to_id,
-            reply_markup=keyboard
+            reply_markup=keyboard,
         )
         os.remove(filename)
         await message.delete()
     else:
         t2 = time()
         keyboard = InlineKeyboardMarkup(
-            [[
-                InlineKeyboardButton(
-                    text="⏳",
-                    callback_data=f"runtime {round(t2-t1, 3)} Seconds"
-                )
-            ]]
+            [
+                [
+                    InlineKeyboardButton(
+                        text="⏳", callback_data=f"runtime {round(t2-t1, 3)} Seconds"
+                    )
+                ]
+            ]
         )
         await edit_or_reply(message, text=final_output, reply_markup=keyboard)
 
@@ -114,68 +117,65 @@ async def runtime_func_cq(_, cq):
     filters.user(SUDOERS)
     & ~filters.forwarded
     & ~filters.via_bot
-    & filters.command('sh'),
+    & filters.command("sh"),
 )
 async def shellrunner(client, message):
     if len(message.command) < 2:
-        await edit_or_reply(message, text='**Usage:**\n/sh git pull')
+        await edit_or_reply(message, text="**Usage:**\n/sh git pull")
         return
     text = message.text.split(None, 1)[1]
-    if '\n' in text:
-        code = text.split('\n')
-        output = ''
+    if "\n" in text:
+        code = text.split("\n")
+        output = ""
         for x in code:
             shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x)
             try:
                 process = subprocess.Popen(
-                    shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                    shell,
+                    stdout=subprocess.PIPE,
+                    stderr=subprocess.PIPE,
                 )
             except Exception as err:
                 print(err)
-                await edit_or_reply(
-                    message,
-                    text=f"**ERROR:**\n```{err}```")
-            output += f'**{code}**\n'
-            output += process.stdout.read()[:-1].decode('utf-8')
-            output += '\n'
+                await edit_or_reply(message, text=f"**ERROR:**\n```{err}```")
+            output += f"**{code}**\n"
+            output += process.stdout.read()[:-1].decode("utf-8")
+            output += "\n"
     else:
         shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
         for a in range(len(shell)):
-            shell[a] = shell[a].replace('"', '')
+            shell[a] = shell[a].replace('"', "")
         try:
             process = subprocess.Popen(
-                shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                shell,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE,
             )
         except Exception as err:
             print(err)
             exc_type, exc_obj, exc_tb = sys.exc_info()
             errors = traceback.format_exception(
-                etype=exc_type, value=exc_obj, tb=exc_tb,
+                etype=exc_type,
+                value=exc_obj,
+                tb=exc_tb,
             )
-            await edit_or_reply(
-                message,
-                text=f"**ERROR:**\n```{''.join(errors)}```")
+            await edit_or_reply(message, text=f"**ERROR:**\n```{''.join(errors)}```")
             return
-        output = process.stdout.read()[:-1].decode('utf-8')
-    if str(output) == '\n':
+        output = process.stdout.read()[:-1].decode("utf-8")
+    if str(output) == "\n":
         output = None
     if output:
         if len(output) > 4096:
-            with open('output.txt', 'w+') as file:
+            with open("output.txt", "w+") as file:
                 file.write(output)
             await app.send_document(
                 message.chat.id,
-                'output.txt',
+                "output.txt",
                 reply_to_message_id=message.message_id,
-                caption='`Output`',
+                caption="`Output`",
             )
-            os.remove('output.txt')
+            os.remove("output.txt")
             return
-        await edit_or_reply(
-            message,
-            text=f"**OUTPUT:**\n```{output}```"
-        )
+        await edit_or_reply(message, text=f"**OUTPUT:**\n```{output}```")
     else:
-        await edit_or_reply(
-            message,
-            text='**OUTPUT: **\n`No output`')
+        await edit_or_reply(message, text="**OUTPUT: **\n`No output`")

+ 31 - 18
wbb/modules/filters.py

@@ -21,18 +21,18 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app, SUDOERS
-from wbb.modules.admin import member_permissions
-from wbb.utils.dbfunctions import (
-    save_filter, get_filters_names, get_filter,
-    delete_filter, is_served_chat, add_served_chat
-)
-from pyrogram import filters
-from wbb.core.decorators.errors import capture_err
-from wbb.utils.filter_groups import chat_filters_group
 import re
 import traceback
 
+from pyrogram import filters
+
+from wbb import SUDOERS, app
+from wbb.core.decorators.errors import capture_err
+from wbb.modules.admin import member_permissions
+from wbb.utils.dbfunctions import (add_served_chat, delete_filter, get_filter,
+                                   get_filters_names, is_served_chat,
+                                   save_filter)
+from wbb.utils.filter_groups import chat_filters_group
 
 __MODULE__ = "Filters"
 __HELP__ = """/filters To Get All The Filters In The Chat.
@@ -49,10 +49,14 @@ async def save_filters(_, message):
     chat_id = message.chat.id
     user_id = message.from_user.id
     if len(message.command) < 2 or not message.reply_to_message:
-        await message.reply_text("Usage:\nReply to a text or sticker with /filter [FILTER_NAME] to save it.")
+        await message.reply_text(
+            "**Usage:**\nReply to a text or sticker with /filter [FILTER_NAME] to save it."
+        )
         return
     if not message.reply_to_message.text and not message.reply_to_message.sticker:
-        await message.reply_text("__**You can only save text or stickers in filters.**__")
+        await message.reply_text(
+            "__**You can only save text or stickers in filters.**__"
+        )
         return
     permissions = await member_permissions(chat_id, user_id)
     if "can_restrict_members" not in permissions and user_id not in SUDOERS:
@@ -65,7 +69,9 @@ async def save_filters(_, message):
     _type = "text" if message.reply_to_message.text else "sticker"
     _filter = {
         "type": _type,
-        "data": message.reply_to_message.text.markdown if _type == "text" else message.reply_to_message.sticker.file_id
+        "data": message.reply_to_message.text.markdown
+        if _type == "text"
+        else message.reply_to_message.sticker.file_id,
     }
     await save_filter(chat_id, name, _filter)
     await message.reply_text(f"__**Saved filter {name}.**__")
@@ -107,9 +113,14 @@ async def del_filter(_, message):
         await message.reply_text("**No such filter.**")
 
 
-@app.on_message(filters.text & ~filters.edited &
-                ~filters.private & ~filters.via_bot &
-                ~filters.forwarded, group=chat_filters_group)
+@app.on_message(
+    filters.text
+    & ~filters.edited
+    & ~filters.private
+    & ~filters.via_bot
+    & ~filters.forwarded,
+    group=chat_filters_group,
+)
 async def filters_re(_, message):
     text = message.text.lower().strip()
     if not text:
@@ -121,11 +132,13 @@ async def filters_re(_, message):
             pattern = r"( |^|[^\w])" + re.escape(word) + r"( |$|[^\w])"
             if re.search(pattern, text, flags=re.IGNORECASE):
                 _filter = await get_filter(chat_id, word)
-                data_type = _filter['type']
-                data = _filter['data']
+                data_type = _filter["type"]
+                data = _filter["data"]
                 if data_type == "text":
                     if message.reply_to_message:
-                        await message.reply_to_message.reply_text(data, disable_web_page_preview=True)
+                        await message.reply_to_message.reply_text(
+                            data, disable_web_page_preview=True
+                        )
                         if text == word:
                             await message.delete()
                         return

+ 30 - 16
wbb/modules/genstr.py

@@ -1,12 +1,12 @@
-from wbb import app
-from pyrogram import Client, filters
+import asyncio
 from asyncio.exceptions import TimeoutError
+
+from pyrogram import Client, filters
+from pyrogram.errors import (PhoneCodeExpired, PhoneCodeInvalid,
+                             PhoneNumberInvalid, SessionPasswordNeeded)
+
+from wbb import app
 from wbb.core.decorators.errors import capture_err
-from pyrogram.errors import (
-    SessionPasswordNeeded, PhoneNumberInvalid,
-    PhoneCodeInvalid, PhoneCodeExpired
-)
-import asyncio
 
 """
 Credits:
@@ -24,20 +24,25 @@ Send **/genstr** Command To The Bot In Private And Follow Instructions."""
 async def genstr(_, message):
     chat = message.chat
     while True:
-        number = await app.ask(chat.id, "Send Your Phone Number In International Format.")
+        number = await app.ask(
+            chat.id, "Send Your Phone Number In International Format."
+        )
         if not number.text:
             continue
         phone = number.text.strip()
         if phone.startswith("/"):
             continue
-        confirm = await app.ask(chat.id, f'`Is "{phone}" correct?` \n\nSend: `y`\nSend: `n`')
+        confirm = await app.ask(
+            chat.id, f'`Is "{phone}" correct?` \n\nSend: `y`\nSend: `n`'
+        )
         if confirm.text.startswith("/"):
             continue
         if "y" in confirm.text.lower():
             break
     try:
-        temp_client = Client(":memory:", api_id=6,
-                             api_hash="eb06d4abfb49dc3eeb1aeb98ae0f581e")
+        temp_client = Client(
+            ":memory:", api_id=6, api_hash="eb06d4abfb49dc3eeb1aeb98ae0f581e"
+        )
     except Exception as e:
         await app.send_message(chat.id, f"**ERROR:** `{str(e)}`")
         return
@@ -55,15 +60,22 @@ async def genstr(_, message):
 
     try:
         otp = await app.ask(
-            chat.id, ("An OTP is sent to your phone number, "
-                      "Please enter OTP in `1 2 3 4 5` format. __(Space between each numbers!)__"), timeout=300)
+            chat.id,
+            (
+                "An OTP is sent to your phone number, "
+                "Please enter OTP in `1 2 3 4 5` format. __(Space between each numbers!)__"
+            ),
+            timeout=300,
+        )
 
     except TimeoutError:
         await message.reply_text("Time limit reached of 5 min. Process Cancelled.")
         return
     otp_code = otp.text
     try:
-        await temp_client.sign_in(phone, code.phone_code_hash, phone_code=' '.join(str(otp_code)))
+        await temp_client.sign_in(
+            phone, code.phone_code_hash, phone_code=" ".join(str(otp_code))
+        )
     except PhoneCodeInvalid:
         await message.reply_text("Invalid OTP.")
         return
@@ -75,7 +87,7 @@ async def genstr(_, message):
             two_step_code = await app.ask(
                 chat.id,
                 "Your account have Two-Step Verification.\nPlease enter your Password.",
-                timeout=300
+                timeout=300,
             )
         except TimeoutError:
             await message.reply_text("Time limit reached of 5 min.")
@@ -92,7 +104,9 @@ async def genstr(_, message):
     try:
         session_string = await temp_client.export_session_string()
         await temp_client.disconnect()
-        await app.send_message(chat.id, text=f"**HERE IS YOUR STRING SESSION:**\n```{session_string}```")
+        await app.send_message(
+            chat.id, text=f"**HERE IS YOUR STRING SESSION:**\n```{session_string}```"
+        )
     except Exception as e:
         await app.send_message(chat.id, f"**ERROR:** `{str(e)}`")
         return

+ 15 - 23
wbb/modules/global_stats.py

@@ -21,37 +21,29 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app, SUDOERS, BOT_ID, BOT_NAME
+import asyncio
+
+from pyrogram import filters
+
+from wbb import BOT_ID, BOT_NAME, SUDOERS, app
 from wbb.core.decorators.errors import capture_err
-from wbb.utils.fetch import fetch
 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_served_chats, get_warns_count,
+                                   remove_served_chat)
+from wbb.utils.fetch import fetch
 from wbb.utils.inlinefuncs import keywords_list
-from wbb.utils.dbfunctions import (
-    get_served_chats,
-    remove_served_chat,
-    get_notes_count,
-    get_filters_count,
-    get_warns_count,
-    get_karmas_count,
-    get_gbans_count,
-    get_blacklist_filters_count
-)
-from pyrogram import filters
-import asyncio
 
 """ CHAT WATCHER IS IN filters.py"""
 
 
-@app.on_message(
-    filters.command("gstats") & filters.user(SUDOERS)
-    & ~filters.edited
-)
+@app.on_message(filters.command("gstats") & filters.user(SUDOERS) & ~filters.edited)
 @capture_err
 async def global_stats(_, message):
     m = await app.send_message(
-        message.chat.id,
-        text="__**Analysing Stats**__",
-        disable_web_page_preview=True
+        message.chat.id, text="__**Analysing Stats**__", disable_web_page_preview=True
     )
 
     # For bot served chat and users count
@@ -62,7 +54,7 @@ async def global_stats(_, message):
         served_chats.append(int(chat["chat_id"]))
     await m.edit(
         f"__**Generating Statistics Report, Should Take {len(served_chats)*6}+ Seconds.**__",
-        disable_web_page_preview=True
+        disable_web_page_preview=True,
     )
     for served_chat in served_chats:
         try:
@@ -113,7 +105,7 @@ async def global_stats(_, message):
     developers = await fetch(url)
     commits = 0
     for developer in developers:
-        commits += developer['contributions']
+        commits += developer["contributions"]
     developers = len(developers)
     # Modules info
     modules_count = len(ALL_MODULES)

+ 56 - 52
wbb/modules/greetings.py

@@ -24,25 +24,25 @@ SOFTWARE.
 
 import asyncio
 import os
-from wbb import app, WELCOME_DELAY_KICK_SEC, SUDOERS
-from wbb.modules.admin import member_permissions
+from datetime import datetime
+from random import shuffle
+
+from pykeyboard import InlineKeyboard
+from pyrogram import filters
+from pyrogram.errors.exceptions.bad_request_400 import (ChatAdminRequired,
+                                                        UserNotParticipant)
+from pyrogram.types import (ChatPermissions, InlineKeyboardButton,
+                            InlineKeyboardMarkup, Message, User)
+
+from wbb import SUDOERS, WELCOME_DELAY_KICK_SEC, app
 from wbb.core.decorators.errors import capture_err
+from wbb.modules.admin import member_permissions
+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.filter_groups import welcome_captcha_group
 from wbb.utils.functions import generate_captcha
-from wbb.utils.dbfunctions import (
-    is_gbanned_user, is_captcha_on, captcha_on, captcha_off,
-    set_welcome, del_welcome, get_welcome, get_captcha_cache,
-    update_captcha_cache
-)
-from pykeyboard import InlineKeyboard
-from pyrogram.types import (
-    Message, InlineKeyboardMarkup,
-    InlineKeyboardButton, ChatPermissions, User
-)
-from pyrogram.errors.exceptions.bad_request_400 import UserNotParticipant, ChatAdminRequired
-from pyrogram import filters
-from random import shuffle
-from datetime import datetime
 
 __MODULE__ = "Greetings"
 __HELP__ = """
@@ -84,6 +84,7 @@ async def get_initial_captcha_cache():
     answers_dicc = await get_captcha_cache()
     return
 
+
 loop.create_task(get_initial_captcha_cache())
 
 
@@ -102,15 +103,19 @@ async def welcome(_, message: Message):
                 continue  # ignore sudos
             if await is_gbanned_user(member.id):
                 await message.chat.kick_member(member.id)
-                await message.reply_text(f"{member.mention} was globally banned, and got removed,"
-                                         + " if you think this is a false gban, you can appeal"
-                                         + " for this ban in support chat.")
+                await message.reply_text(
+                    f"{member.mention} was globally banned, and got removed,"
+                    + " if you think this is a false gban, you can appeal"
+                    + " for this ban in support chat."
+                )
                 continue
             if member.is_bot:
                 continue  # ignore bots
             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.")
+            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."
+            )
         except ChatAdminRequired:
             return
         # Generate a captcha image, answers and some wrong answers
@@ -120,7 +125,7 @@ async def welcome(_, message: Message):
         wrong_answers = captcha[2]  # This consists of 8 wrong answers
         correct_button = InlineKeyboardButton(
             f"{captcha_answer}",
-            callback_data=f"pressed_button {captcha_answer} {member.id}"
+            callback_data=f"pressed_button {captcha_answer} {member.id}",
         )
         temp_keyboard_1 = [correct_button]  # Button row 1
         temp_keyboard_2 = []  # Botton row 2
@@ -129,21 +134,21 @@ async def welcome(_, message: Message):
             temp_keyboard_1.append(
                 InlineKeyboardButton(
                     f"{wrong_answers[i]}",
-                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
+                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
                 )
             )
         for i in range(2, 5):
             temp_keyboard_2.append(
                 InlineKeyboardButton(
                     f"{wrong_answers[i]}",
-                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
+                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
                 )
             )
         for i in range(5, 8):
             temp_keyboard_3.append(
                 InlineKeyboardButton(
                     f"{wrong_answers[i]}",
-                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}"
+                    callback_data=f"pressed_button {wrong_answers[i]} {member.id}",
                 )
             )
 
@@ -155,23 +160,21 @@ async def welcome(_, message: Message):
             "user_id": member.id,
             "answer": captcha_answer,
             "keyboard": keyboard,
-            "attempts": 0
+            "attempts": 0,
         }
         keyboard = InlineKeyboardMarkup(keyboard)
         # Append user info, correct answer and
         answers_dicc.append(verification_data)
         # keyboard for later use with callback query
         button_message = await message.reply_photo(
-            photo=captcha_image,
-            caption=text,
-            reply_markup=keyboard,
-            quote=True
+            photo=captcha_image, caption=text, reply_markup=keyboard, 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)
-        asyncio.create_task(kick_restricted_after_delay(
-            WELCOME_DELAY_KICK_SEC, button_message, member))
+        asyncio.create_task(
+            kick_restricted_after_delay(WELCOME_DELAY_KICK_SEC, button_message, member)
+        )
         await asyncio.sleep(0.5)
 
 
@@ -198,18 +201,13 @@ async def send_welcome_message(callback_query, pending_user_id):
         button_string = button_string.split(",")
         button_text = button_string[0].strip()
         button_url = button_string[1].strip()
-        list_of_buttons.append(
-            InlineKeyboardButton(
-                text=button_text,
-                url=button_url
-            )
-        )
+        list_of_buttons.append(InlineKeyboardButton(text=button_text, url=button_url))
     buttons.add(*list_of_buttons)
     await app.send_message(
         callback_query.message.chat.id,
         text=text,
         reply_markup=buttons,
-        disable_web_page_preview=True
+        disable_web_page_preview=True,
     )
 
 
@@ -227,15 +225,21 @@ async def callback_query_welcome_button(_, callback_query):
     answer = data.split(None, 2)[1]
     if len(answers_dicc) != 0:
         for i in answers_dicc:
-            if i['user_id'] == pending_user_id and i['chat_id'] == button_message.chat.id:
-                correct_answer = i['answer']
-                keyboard = i['keyboard']
+            if (
+                i["user_id"] == pending_user_id
+                and i["chat_id"] == button_message.chat.id
+            ):
+                correct_answer = i["answer"]
+                keyboard = i["keyboard"]
     if pending_user_id == pressed_user_id:
         if answer != correct_answer:
             await callback_query.answer("Yeah, It's Wrong.")
             for iii in answers_dicc:
-                if iii['user_id'] == pending_user_id and iii['chat_id'] == button_message.chat.id:
-                    attempts = iii['attempts']
+                if (
+                    iii["user_id"] == pending_user_id
+                    and iii["chat_id"] == button_message.chat.id
+                ):
+                    attempts = iii["attempts"]
                     if attempts >= 3:
                         answers_dicc.remove(iii)
                         await button_message.chat.kick_member(pending_user_id)
@@ -245,7 +249,7 @@ async def callback_query_welcome_button(_, callback_query):
                         await update_captcha_cache(answers_dicc)
                         return
                     else:
-                        iii['attempts'] += 1
+                        iii["attempts"] += 1
                         break
             shuffle(keyboard[0])
             shuffle(keyboard[1])
@@ -253,8 +257,7 @@ async def callback_query_welcome_button(_, callback_query):
             shuffle(keyboard)
             keyboard = InlineKeyboardMarkup(keyboard)
             await button_message.edit(
-                text=button_message.caption.markdown,
-                reply_markup=keyboard
+                text=button_message.caption.markdown, reply_markup=keyboard
             )
             return
         await callback_query.answer("Captcha passed successfully!")
@@ -262,7 +265,10 @@ async def callback_query_welcome_button(_, callback_query):
         await button_message.delete()
         if len(answers_dicc) != 0:
             for ii in answers_dicc:
-                if ii['user_id'] == pending_user_id and ii['chat_id'] == button_message.chat.id:
+                if (
+                    ii["user_id"] == pending_user_id
+                    and ii["chat_id"] == button_message.chat.id
+                ):
                     answers_dicc.remove(ii)
                     await update_captcha_cache(answers_dicc)
         """ send welcome message """
@@ -286,15 +292,13 @@ async def kick_restricted_after_delay(delay, button_message: Message, user: User
     await button_message.delete()
     if len(answers_dicc) != 0:
         for i in answers_dicc:
-            if i['user_id'] == user_id:
+            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)
 
 
-async def _ban_restricted_user_until_date(group_chat,
-                                          user_id: int,
-                                          duration: int):
+async def _ban_restricted_user_until_date(group_chat, user_id: int, duration: int):
     try:
         member = await group_chat.get_member(user_id)
         if member.status == "restricted":

+ 8 - 8
wbb/modules/images.py

@@ -21,17 +21,19 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-import urllib.request
-import json
 import asyncio
+import json
+import urllib.request
+
 from pyrogram import filters
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
 
 __MODULE__ = "Images"
-__HELP__ = '''/cat  - Get Cute Cats Images
+__HELP__ = """/cat  - Get Cute Cats Images
 For more images like wallpapers, use inline mode.
-send /inline for inline help.'''
+send /inline for inline help."""
 
 
 async def delete_message_with_delay(delay, message):
@@ -42,9 +44,7 @@ async def delete_message_with_delay(delay, message):
 @app.on_message(filters.command("cat") & ~filters.edited)
 @capture_err
 async def cat(_, message):
-    with urllib.request.urlopen(
-            "https://api.thecatapi.com/v1/images/search"
-    ) as url:
+    with urllib.request.urlopen("https://api.thecatapi.com/v1/images/search") as url:
         data = json.loads(url.read().decode())
-    cat_url = (data[0]['url'])
+    cat_url = data[0]["url"]
     await message.reply_photo(cat_url)

+ 4 - 2
wbb/modules/info.py

@@ -1,9 +1,11 @@
-from wbb import app, SUDOERS
+import os
+
 from pyrogram import filters
 from pyrogram.types import Message
+
+from wbb import SUDOERS, app
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.dbfunctions import is_gbanned_user, user_global_karma
-import os
 
 __MODULE__ = "Info"
 __HELP__ = """

+ 67 - 149
wbb/modules/inline.py

@@ -24,11 +24,12 @@ SOFTWARE.
 """
 
 import traceback
+
 from wbb import app
 from wbb.utils.inlinefuncs import *
 
 __MODULE__ = "Inline"
-__HELP__ = '''See inline for help related to inline'''
+__HELP__ = """See inline for help related to inline"""
 
 
 @app.on_inline_query()
@@ -36,28 +37,20 @@ async def inline_query_handler(client, query):
     try:
         text = query.query.strip().lower()
         answers = []
-        if text.strip() == '':
+        if text.strip() == "":
             answerss = await inline_help_func(__HELP__)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=10
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=10)
             return
         elif text.split()[0] == "alive":
             answerss = await alive_function(answers)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=10
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=10)
         elif text.split()[0] == "tr":
             if len(text.split()) < 3:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Translator | tr [LANG] [TEXT]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Translator | tr [LANG] [TEXT]",
+                    switch_pm_parameter="inline",
                 )
                 return
             lang = text.split()[1]
@@ -72,8 +65,8 @@ async def inline_query_handler(client, query):
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Urban Dictionary | ud [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Urban Dictionary | ud [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
@@ -87,8 +80,8 @@ async def inline_query_handler(client, query):
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Google Search | google [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Google Search | google [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
@@ -102,73 +95,60 @@ async def inline_query_handler(client, query):
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Link Shortener | bitly [LINK]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Link Shortener | bitly [LINK]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await shortify(tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "wall":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Wallpapers Search | wall [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Wallpapers Search | wall [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await wall_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] == "saavn":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='JioSaavn Search | saavn [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="JioSaavn Search | saavn [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await saavn_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] == "deezer":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Deezer Search | deezer [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Deezer Search | deezer [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await deezer_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] == "torrent":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Torrent Search | torrent [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Torrent Search | torrent [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
@@ -183,126 +163,96 @@ async def inline_query_handler(client, query):
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='YouTube Search | yt [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="YouTube Search | yt [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             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:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Lyrics Search | lyrics [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Lyrics Search | lyrics [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             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] == "gh_user":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Github User | gh_user [USERNAME/LINK]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Github User | gh_user [USERNAME/LINK]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await github_user_func(answers, tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "gh_repo":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Github Repo Search | [LINK]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Github Repo Search | [LINK]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await github_repo_func(answers, tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "search":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Global Message Search. | search [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Global Message Search. | search [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             user_id = query.from_user.id
             tex = text.split(None, 1)[1].strip()
             answerss = await tg_search_func(answers, tex, user_id)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "music":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Music Search | music [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Music Search | music [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await music_inline_func(answers, tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "wiki":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Wikipedia | wiki [QUERY]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Wikipedia | wiki [QUERY]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await wiki_func(answers, tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "speedtest":
             answerss = await speedtest_init(query)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
             return
 
         elif text.split()[0] == "paste":
@@ -310,17 +260,13 @@ async def inline_query_handler(client, query):
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Pastebin | paste [TG_MESSAGE_LINK]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Pastebin | paste [TG_MESSAGE_LINK]",
+                    switch_pm_parameter="inline",
                 )
                 return
             link = text.strip().split()[1]
             answerss = await pastebin_func(answers, link)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
             return
 
         elif text.split()[0] == "carbon":
@@ -328,37 +274,25 @@ async def inline_query_handler(client, query):
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Carbon | carbon [TG_MESSAGE_LINK]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Carbon | carbon [TG_MESSAGE_LINK]",
+                    switch_pm_parameter="inline",
                 )
                 return
             link = text.split()[1]
             answerss = await carbon_inline_func(answers, link)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
             return
 
         elif text.split()[0] == "pmpermit":
             user_id = query.from_user.id
             victim = text.split()[1]
             answerss = await pmpermit_func(answers, user_id, victim)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
             return
 
         elif text.split()[0] == "ping":
             answerss = await ping_func(answers)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
             return
 
         elif text.split()[0] == "nsfw_scan":
@@ -366,69 +300,53 @@ async def inline_query_handler(client, query):
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='NSFW Scan | nsfw_scan [url]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="NSFW Scan | nsfw_scan [url]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split(None, 1)[1].strip()
             answerss = await nsfw_scan_func(answers, tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "ytmusic":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='YT Music | ytmusic [url]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="YT Music | ytmusic [url]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = query.query.split(None, 1)[1].strip()
             user_id = query.from_user.id
             answerss = await yt_music_func(answers, tex, user_id)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "info":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='User Info | info [USERNAME|ID]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="User Info | info [USERNAME|ID]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split()[1].strip()
             answerss = await user_info_inline_func(answers, tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
 
         elif text.split()[0] == "chat_info":
             if len(text.split()) < 2:
                 await client.answer_inline_query(
                     query.id,
                     results=answers,
-                    switch_pm_text='Chat Info | chat_info [USERNAME|ID]',
-                    switch_pm_parameter='inline',
+                    switch_pm_text="Chat Info | chat_info [USERNAME|ID]",
+                    switch_pm_parameter="inline",
                 )
                 return
             tex = text.split()[1].strip()
             answerss = await chat_info_inline_func(answers, tex)
-            await client.answer_inline_query(
-                query.id,
-                results=answerss,
-                cache_time=2
-            )
+            await client.answer_inline_query(query.id, results=answerss, cache_time=2)
     except Exception as e:
         e = traceback.format_exc()
         print(e, " InLine")

+ 18 - 16
wbb/modules/karma.py

@@ -21,14 +21,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+from pyrogram import filters
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
 from wbb.modules.admin import member_permissions
-from wbb.utils.dbfunctions import (update_karma, get_karma, get_karmas,
-                                   int_to_alpha, alpha_to_int, is_karma_on,
-                                   karma_on, karma_off)
-from wbb.utils.filter_groups import karma_positive_group, karma_negative_group
-from pyrogram import filters
+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
 
 __MODULE__ = "Karma"
 __HELP__ = """[UPVOTE] - Use upvote keywords like "+", "+1", "thanks" etc to upvote a message.
@@ -51,7 +52,7 @@ regex_downvote = r"^(\-|\-\-|\-1|👎)$"
     & ~filters.via_bot
     & ~filters.bot
     & ~filters.edited,
-    group=karma_positive_group
+    group=karma_positive_group,
 )
 @capture_err
 async def upvote(_, message):
@@ -64,7 +65,7 @@ async def upvote(_, message):
     user_mention = message.reply_to_message.from_user.mention
     current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
     if current_karma:
-        current_karma = current_karma['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)
@@ -73,7 +74,7 @@ async def upvote(_, message):
         new_karma = {"karma": 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}'
+        f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
     )
 
 
@@ -86,7 +87,7 @@ async def upvote(_, message):
     & ~filters.via_bot
     & ~filters.bot
     & ~filters.edited,
-    group=karma_negative_group
+    group=karma_negative_group,
 )
 @capture_err
 async def downvote(_, message):
@@ -99,7 +100,7 @@ async def downvote(_, message):
     user_mention = message.reply_to_message.from_user.mention
     current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
     if current_karma:
-        current_karma = current_karma['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)
@@ -108,7 +109,7 @@ async def downvote(_, message):
         new_karma = {"karma": 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}'
+        f"Decremented Karma Of {user_mention} By 1 \nTotal Points: {karma}"
     )
 
 
@@ -124,10 +125,11 @@ async def karma(_, message):
         karma_dicc = {}
         for i in karma:
             user_id = await alpha_to_int(i)
-            user_karma = karma[i]['karma']
+            user_karma = karma[i]["karma"]
             karma_dicc[str(user_id)] = user_karma
             karma_arranged = dict(
-                sorted(karma_dicc.items(), key=lambda item: item[1], reverse=True))
+                sorted(karma_dicc.items(), key=lambda item: item[1], reverse=True)
+            )
         for user_idd, karma_count in karma_arranged.items():
             if limit > 9:
                 break
@@ -142,11 +144,11 @@ async def karma(_, message):
         user_id = message.reply_to_message.from_user.id
         karma = await get_karma(chat_id, await int_to_alpha(user_id))
         if karma:
-            karma = karma['karma']
-            await message.reply_text(f'**Total Points**: __{karma}__')
+            karma = karma["karma"]
+            await message.reply_text(f"**Total Points**: __{karma}__")
         else:
             karma = 0
-            await message.reply_text(f'**Total Points**: __{karma}__')
+            await message.reply_text(f"**Total Points**: __{karma}__")
 
 
 @app.on_message(filters.command("karma_toggle") & ~filters.private)

+ 12 - 6
wbb/modules/locks.py

@@ -21,12 +21,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import SUDOERS, app
-from wbb.modules.admin import member_permissions, current_chat_permissions
-from wbb.core.decorators.errors import capture_err
 from pyrogram import filters
-from pyrogram.types import ChatPermissions
 from pyrogram.errors.exceptions.bad_request_400 import ChatNotModified
+from pyrogram.types import ChatPermissions
+
+from wbb import SUDOERS, app
+from wbb.core.decorators.errors import capture_err
+from wbb.modules.admin import current_chat_permissions, member_permissions
 
 __MODULE__ = "Locks"
 __HELP__ = """
@@ -55,7 +56,7 @@ data = {
     "polls": "can_send_polls",
     "group_info": "can_change_info",
     "useradd": "can_invite_users",
-    "pin": "can_pin_messages"
+    "pin": "can_pin_messages",
 }
 
 
@@ -101,7 +102,12 @@ async def locks_func(_, message):
 
         permissions = await current_chat_permissions(chat_id)
         if parameter in data:
-            await tg_lock(message, permissions, data[parameter], True if state == "lock" else False)
+            await tg_lock(
+                message,
+                permissions,
+                data[parameter],
+                True if state == "lock" else False,
+            )
             return
         elif parameter == "all" and state == "lock":
             await app.set_chat_permissions(chat_id, ChatPermissions())

+ 45 - 29
wbb/modules/misc.py

@@ -23,19 +23,21 @@ SOFTWARE.
 """
 import secrets
 import string
+
 import aiohttp
-from pyrogram import filters
-from googletrans import Translator
 from cryptography.fernet import Fernet
-from wbb import app, FERNET_ENCRYPTION_KEY
+from googletrans import Translator
+from pyrogram import filters
+
+from wbb import FERNET_ENCRYPTION_KEY, app
+from wbb.core.decorators.errors import capture_err
 from wbb.utils import random_line
-from wbb.utils.json_prettify import json_prettify
 from wbb.utils.fetch import fetch
+from wbb.utils.json_prettify import json_prettify
 from wbb.utils.pastebin import paste
-from wbb.core.decorators.errors import capture_err
 
 __MODULE__ = "Misc"
-__HELP__ = '''
+__HELP__ = """
 /commit - Generate Funny Commit Messages
 /runs  - Idk Test Yourself
 /id - Get Chat_ID or User_ID
@@ -49,12 +51,12 @@ __HELP__ = '''
 /ocr - Perform OCR On An Image.
 /arq - Statistics Of ARQ API.
 #RTFM - Check it lol
-'''
+"""
 
 
 @app.on_message(filters.command("commit") & ~filters.edited)
 async def commit(_, message):
-    await message.reply_text((await random_line('wbb/utils/commit.txt')))
+    await message.reply_text((await random_line("wbb/utils/commit.txt")))
 
 
 @app.on_message(filters.command("RTFM", "#"))
@@ -68,7 +70,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"))
@@ -118,61 +120,67 @@ async def getid(_, message):
             text += f" <code>{reply.forward_from.id}</code>\n"
             text_unping += text
             text_ping += f'\n<b><a href="tg://user?id={reply.forward_from.id}">Forwarded User ID:</a></b> <code>{reply.forward_from.id}</code>\n'
-    reply = await message.reply_text(text_unping, disable_web_page_preview=True, parse_mode="html")
+    reply = await message.reply_text(
+        text_unping, disable_web_page_preview=True, parse_mode="html"
+    )
     if text_unping != text_ping:
-        await reply.edit_text(text_ping, disable_web_page_preview=True, parse_mode="html")
+        await reply.edit_text(
+            text_ping, disable_web_page_preview=True, parse_mode="html"
+        )
+
 
 # Random
 
 
-@app.on_message(filters.command('random') & ~filters.edited)
+@app.on_message(filters.command("random") & ~filters.edited)
 @capture_err
 async def random(_, message):
     if len(message.command) != 2:
-        await message.reply_text('"/random" Needs An Argurment.'
-                                 ' Ex: `/random 5`')
+        await message.reply_text('"/random" Needs An Argurment.' " Ex: `/random 5`")
         return
     length = message.text.split(None, 1)[1]
 
     try:
         if 1 < int(length) < 1000:
             alphabet = string.ascii_letters + string.digits
-            password = ''.join(secrets.choice(alphabet) for i in
-                               range(int(length)))
+            password = "".join(secrets.choice(alphabet) for i in range(int(length)))
             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 Between 1-1000")
+        await message.reply_text(
+            "Strings Won't Work!, Pass A" + " Positive Integer Between 1-1000"
+        )
+
 
 # Encrypt
 
 
-@app.on_message(filters.command('encrypt') & ~filters.edited)
+@app.on_message(filters.command("encrypt") & ~filters.edited)
 @capture_err
 async def encrypt(_, message):
     if not message.reply_to_message:
-        await message.reply_text('Reply To A Message To Encrypt It.')
+        await message.reply_text("Reply To A Message To Encrypt It.")
         return
     text = message.reply_to_message.text
-    text_in_bytes = bytes(text, 'utf-8')
+    text_in_bytes = bytes(text, "utf-8")
     cipher_suite = Fernet(FERNET_ENCRYPTION_KEY)
     encrypted_text = cipher_suite.encrypt(text_in_bytes)
     bytes_in_text = encrypted_text.decode("utf-8")
     await message.reply_text(bytes_in_text)
 
+
 # Decrypt
 
 
-@app.on_message(filters.command('decrypt') & ~filters.edited)
+@app.on_message(filters.command("decrypt") & ~filters.edited)
 @capture_err
 async def decrypt(_, message):
     if not message.reply_to_message:
-        await message.reply_text('Reply To A Message To Decrypt It.')
+        await message.reply_text("Reply To A Message To Decrypt It.")
         return
     text = message.reply_to_message.text
-    text_in_bytes = bytes(text, 'utf-8')
+    text_in_bytes = bytes(text, "utf-8")
     cipher_suite = Fernet(FERNET_ENCRYPTION_KEY)
     decoded_text = cipher_suite.decrypt(text_in_bytes)
     bytes_in_text = decoded_text.decode("utf-8")
@@ -210,6 +218,7 @@ async def cheat(_, message):
         await m.edit(str(e))
         print(str(e))
 
+
 # Weather
 
 
@@ -224,6 +233,7 @@ async def weather(_, message):
     data = await fetch_text(f"https://wttr.in/{city}?mnTC0")
     await m.edit(f"`{data}`")
 
+
 # Translate
 
 
@@ -278,18 +288,24 @@ async def json_fetch(_, message):
             await message.reply_text(data)
         else:
             link = await paste(data)
-            await message.reply_text(f"[OUTPUT_TOO_LONG]({link})", disable_web_page_preview=True)
+            await message.reply_text(
+                f"[OUTPUT_TOO_LONG]({link})", disable_web_page_preview=True
+            )
     except Exception as e:
         await message.reply_text(str(e))
         print(str(e))
 
 
-@app.on_message(filters.command('bun'))
+@app.on_message(filters.command("bun"))
 async def bunn(_, message):
     if message.reply_to_message:
-        await message.reply_to_message.reply_sticker('CAACAgUAAx0CWIlO9AABARyRYBhyjKXFATVhu7AGQwip3TzSFiMAAuMBAAJ7usBUIu2xBtXTmuweBA')
+        await message.reply_to_message.reply_sticker(
+            "CAACAgUAAx0CWIlO9AABARyRYBhyjKXFATVhu7AGQwip3TzSFiMAAuMBAAJ7usBUIu2xBtXTmuweBA"
+        )
         await app.send_message(message.chat.id, text="Eat Bun")
         return
     if not message.reply_to_message:
-        await message.reply_sticker('CAACAgUAAx0CWIlO9AABARyRYBhyjKXFATVhu7AGQwip3TzSFiMAAuMBAAJ7usBUIu2xBtXTmuweBA')
+        await message.reply_sticker(
+            "CAACAgUAAx0CWIlO9AABARyRYBhyjKXFATVhu7AGQwip3TzSFiMAAuMBAAJ7usBUIu2xBtXTmuweBA"
+        )
         await app.send_message(message.chat.id, text="Eat Bun")

+ 52 - 27
wbb/modules/music.py

@@ -22,19 +22,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 from __future__ import unicode_literals
+
+import os
+from random import randint
 from urllib.parse import urlparse
-import youtube_dl
-import aiohttp
+
 import aiofiles
-import os
+import aiohttp
 import ffmpeg
-from random import randint
+import youtube_dl
 from pyrogram import filters
-from wbb import app, arq, SUDOERS
+
+from wbb import SUDOERS, app, arq
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.pastebin import paste
 
-
 __MODULE__ = "Music"
 __HELP__ = """/ytmusic [link] To Download Music From Various Websites Including Youtube. [SUDOERS]
 /saavn [query] To Download Music From Saavn.
@@ -52,9 +54,14 @@ def get_file_extension_from_url(url):
 
 async def download_youtube_audio(url: str, m=0):
     global is_downloading
-    with youtube_dl.YoutubeDL({'format': 'bestaudio', 'writethumbnail': True, }) as ydl:
+    with youtube_dl.YoutubeDL(
+        {
+            "format": "bestaudio",
+            "writethumbnail": True,
+        }
+    ) as ydl:
         info_dict = ydl.extract_info(url, download=False)
-        if int(float(info_dict['duration'])) > 600:
+        if int(float(info_dict["duration"])) > 600:
             if m != 0:
                 await m.edit("This music cannot be downloaded as it's too long.")
             is_downloading = False
@@ -62,18 +69,18 @@ async def download_youtube_audio(url: str, m=0):
         ydl.process_info(info_dict)
         audio_file = ydl.prepare_filename(info_dict)
         basename = audio_file.rsplit(".", 1)[-2]
-        if info_dict['ext'] == 'webm':
+        if info_dict["ext"] == "webm":
             audio_file_opus = basename + ".opus"
-            ffmpeg.input(audio_file).output(audio_file_opus,
-                                            codec="copy", loglevel='error').overwrite_output().run()
+            ffmpeg.input(audio_file).output(
+                audio_file_opus, codec="copy", loglevel="error"
+            ).overwrite_output().run()
             os.remove(audio_file)
             audio_file = audio_file_opus
-        thumbnail_url = info_dict['thumbnail']
-        thumbnail_file = basename + "." + \
-            get_file_extension_from_url(thumbnail_url)
-        title = info_dict['title']
-        performer = info_dict['uploader']
-        duration = int(float(info_dict['duration']))
+        thumbnail_url = info_dict["thumbnail"]
+        thumbnail_file = basename + "." + get_file_extension_from_url(thumbnail_url)
+        title = info_dict["title"]
+        performer = info_dict["uploader"]
+        duration = int(float(info_dict["duration"]))
     return [title, performer, duration, audio_file, thumbnail_file]
 
 
@@ -86,20 +93,30 @@ async def music(_, message):
         return
     url = message.text.split(None, 1)[1]
     if is_downloading:
-        await message.reply_text("Another download is in progress, try again after sometime.")
+        await message.reply_text(
+            "Another download is in progress, try again after sometime."
+        )
         return
     is_downloading = True
-    m = await message.reply_text(f"Downloading {url}",
-                                 disable_web_page_preview=True)
+    m = await message.reply_text(f"Downloading {url}", disable_web_page_preview=True)
     try:
-        title, performer, duration, audio_file, thumbnail_file = await download_youtube_audio(url, message)
+        (
+            title,
+            performer,
+            duration,
+            audio_file,
+            thumbnail_file,
+        ) = await download_youtube_audio(url, message)
     except Exception as e:
         is_downloading = False
         await m.edit(str(e))
         return
     await message.reply_audio(
-        audio_file, duration=duration,
-        performer=performer, title=title, thumb=thumbnail_file
+        audio_file,
+        duration=duration,
+        performer=performer,
+        title=title,
+        thumb=thumbnail_file,
     )
     await m.delete()
     os.remove(audio_file)
@@ -113,11 +130,12 @@ async def download_song(url):
     async with aiohttp.ClientSession() as session:
         async with session.get(url) as resp:
             if resp.status == 200:
-                f = await aiofiles.open(song_name, mode='wb')
+                f = await aiofiles.open(song_name, mode="wb")
                 await f.write(await resp.read())
                 await f.close()
     return song_name
 
+
 # Jiosaavn Music
 
 
@@ -129,7 +147,9 @@ async def jssong(_, message):
         await message.reply_text("/saavn requires an argument.")
         return
     if is_downloading:
-        await message.reply_text("Another download is in progress, try again after sometime.")
+        await message.reply_text(
+            "Another download is in progress, try again after sometime."
+        )
         return
     is_downloading = True
     text = message.text.split(None, 1)[1]
@@ -156,6 +176,7 @@ async def jssong(_, message):
         return
     is_downloading = False
 
+
 # Deezer Music
 
 
@@ -167,7 +188,9 @@ async def deezsong(_, message):
         await message.reply_text("/deezer requires an argument.")
         return
     if is_downloading:
-        await message.reply_text("Another download is in progress, try again after sometime.")
+        await message.reply_text(
+            "Another download is in progress, try again after sometime."
+        )
         return
     is_downloading = True
     text = message.text.split(None, 1)[1]
@@ -184,7 +207,8 @@ async def deezsong(_, message):
         await message.reply_audio(
             audio=song,
             title=title,
-            performer=artist,)
+            performer=artist,
+        )
         os.remove(song)
         await m.delete()
     except Exception as e:
@@ -193,6 +217,7 @@ async def deezsong(_, message):
         return
     is_downloading = False
 
+
 # Lyrics
 
 

+ 10 - 7
wbb/modules/notes.py

@@ -21,14 +21,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+from pyrogram import filters
+
 from wbb import app
-from wbb.utils.dbfunctions import (
-    save_note, get_note_names, get_note, delete_note
-)
 from wbb.core.decorators.errors import capture_err
 from wbb.modules.admin import member_permissions
-from pyrogram import filters
-
+from wbb.utils.dbfunctions import (delete_note, get_note, get_note_names,
+                                   save_note)
 
 __MODULE__ = "Notes"
 __HELP__ = """/notes To Get All The Notes In The Chat.
@@ -41,7 +40,9 @@ __HELP__ = """/notes To Get All The Notes In The Chat.
 @capture_err
 async def save_notee(_, message):
     if len(message.command) < 2 or not message.reply_to_message:
-        await message.reply_text("Usage:\nReply to a text or sticker with /save [NOTE_NAME] to save it.")
+        await message.reply_text(
+            "**Usage:**\nReply to a text or sticker with /save [NOTE_NAME] to save it."
+        )
 
     elif not message.reply_to_message.text and not message.reply_to_message.sticker:
         await message.reply_text("__**You can only save text or stickers in notes.**__")
@@ -56,7 +57,9 @@ async def save_notee(_, message):
         _type = "text" if message.reply_to_message.text else "sticker"
         note = {
             "type": _type,
-            "data": message.reply_to_message.text.markdown if _type == "text" else message.reply_to_message.sticker.file_id
+            "data": message.reply_to_message.text.markdown
+            if _type == "text"
+            else message.reply_to_message.sticker.file_id,
         }
         await save_note(message.chat.id, name, note)
         await message.reply_text(f"__**Saved note {name}.**__")

+ 15 - 5
wbb/modules/ocr.py

@@ -21,12 +21,14 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+import os
+
+from pyrogram import filters
+from pyrogram.errors.exceptions.bad_request_400 import MessageEmpty
+
 from wbb import app, arq
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.functions import transfer_sh
-from pyrogram import filters
-from pyrogram.errors.exceptions.bad_request_400 import MessageEmpty
-import os
 
 
 @app.on_message(filters.command("ocr"))
@@ -36,8 +38,16 @@ async def image_ocr(_, message):
         await message.reply_text("Reply to an image or document to perform OCR on it.")
         return
     reply = message.reply_to_message
-    if not reply.document and not reply.photo and not reply.sticker and not reply.animation and not reply.video:
-        await message.reply_text("Reply to an image/document/sticker/animation to perform OCR on it.")
+    if (
+        not reply.document
+        and not reply.photo
+        and not reply.sticker
+        and not reply.animation
+        and not reply.video
+    ):
+        await message.reply_text(
+            "Reply to an image/document/sticker/animation to perform OCR on it."
+        )
         return
     m = await message.reply_text("Scanning")
     if reply.document:

+ 7 - 13
wbb/modules/paste.py

@@ -21,13 +21,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-import os
 import asyncio
+import os
+
 from pyrogram import filters
+
 from wbb import app
-from wbb.utils.pastebin import paste
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.functions import get_http_status_code
+from wbb.utils.pastebin import paste
 
 __MODULE__ = "Paste"
 __HELP__ = "/paste - To Paste Replied Text Or Document To Nekobin"
@@ -52,18 +54,14 @@ async def paste_func(_, message):
                 await asyncio.sleep(0.2)
                 i += 1
             await m.delete()
-            await app.send_photo(
-                    message.chat.id,
-                    photo=preview,
-                    caption=link
-                    )
+            await app.send_photo(message.chat.id, photo=preview, caption=link)
 
         elif message.reply_to_message.document:
             if message.reply_to_message.document.file_size > 1048576:
                 await message.reply_text("You can only paste files smaller than 1MB.")
                 return
             m = await message.reply_text("Pasting...")
-            doc_file = await message.reply_to_message.download(file_name='paste.txt')
+            doc_file = await message.reply_to_message.download(file_name="paste.txt")
             i = open(doc_file, "r")
             link = await paste(i.read())
             preview = link + "/preview.png"
@@ -76,11 +74,7 @@ async def paste_func(_, message):
                 await asyncio.sleep(0.2)
                 i += 1
             await m.delete()
-            await app.send_photo(
-                    message.chat.id,
-                    photo=preview,
-                    caption=link
-                    )
+            await app.send_photo(message.chat.id, photo=preview, caption=link)
             os.remove(doc_file)
     else:
         await message.reply_text("Reply To A Message With /paste")

+ 26 - 21
wbb/modules/pipes.py

@@ -21,13 +21,16 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app, app2, SUDOERS, USERBOT_ID, BOT_ID
-from wbb.core.decorators.errors import capture_err
-from wbb.utils.filter_groups import pipes_group
-from wbb.utils.dbfunctions import is_pipe_active, activate_pipe, deactivate_pipe, show_pipes
+import asyncio
+
 from pyrogram import filters
 from pyrogram.types import Message
-import asyncio
+
+from wbb import BOT_ID, SUDOERS, USERBOT_ID, app, app2
+from wbb.core.decorators.errors import capture_err
+from wbb.utils.dbfunctions import (activate_pipe, deactivate_pipe,
+                                   is_pipe_active, show_pipes)
+from wbb.utils.filter_groups import pipes_group
 
 __MODULE__ = "Pipes"
 __HELP__ = """
@@ -64,11 +67,12 @@ async def load_pipes():
     pipes_list_userbot = []
     pipes = await show_pipes()
     for pipe in pipes:
-        if pipe['fetcher'] == "bot":
+        if pipe["fetcher"] == "bot":
             pipes_list_bot.append(pipe)
             continue
         pipes_list_userbot.append(pipe)
 
+
 loop = asyncio.get_running_loop()
 loop.create_task(load_pipes())
 
@@ -77,35 +81,30 @@ loop.create_task(load_pipes())
 @capture_err
 async def pipes_worker_bot(_, message: Message):
     for pipe in pipes_list_bot:
-        if pipe['from_chat_id'] == message.chat.id:
-            await message.forward(pipe['to_chat_id'])
+        if pipe["from_chat_id"] == message.chat.id:
+            await message.forward(pipe["to_chat_id"])
 
 
 @app2.on_message(~filters.me, group=pipes_group)
 @capture_err
 async def pipes_worker_userbot(_, message: Message):
     for pipe in pipes_list_userbot:
-        if pipe['from_chat_id'] == message.chat.id:
+        if pipe["from_chat_id"] == message.chat.id:
             if not message.text:
                 m, temp = await asyncio.gather(
-                    app.listen(USERBOT_ID),
-                    message.copy(BOT_ID)
+                    app.listen(USERBOT_ID), message.copy(BOT_ID)
                 )
                 caption = f"Forwarded from `{pipe['from_chat_id']}`"
                 caption = f"{temp.caption}\n\n{caption}" if temp.caption else caption
                 await app.copy_message(
-                    pipe['to_chat_id'],
-                    USERBOT_ID,
-                    m.message_id,
-                    caption=caption
+                    pipe["to_chat_id"], USERBOT_ID, m.message_id, caption=caption
                 )
                 await asyncio.sleep(10)
                 await temp.delete()
                 return
             caption = f"Forwarded from `{pipe['from_chat_id']}`"
             await app.send_message(
-                pipe['to_chat_id'],
-                text=message.text + "\n\n" + caption
+                pipe["to_chat_id"], text=message.text + "\n\n" + caption
             )
 
 
@@ -113,7 +112,9 @@ async def pipes_worker_userbot(_, message: Message):
 @capture_err
 async def activate_pipe_func(_, message: Message):
     if len(message.command) != 4:
-        await message.reply_text("**Usage:**\n/activate_pipe [FROM_CHAT_ID] [TO_CHAT_ID] [BOT|USERBOT]")
+        await message.reply_text(
+            "**Usage:**\n/activate_pipe [FROM_CHAT_ID] [TO_CHAT_ID] [BOT|USERBOT]"
+        )
         return
     text = message.text.strip().split()
     from_chat = int(text[1])
@@ -134,7 +135,9 @@ async def activate_pipe_func(_, message: Message):
 @capture_err
 async def deactivate_pipe_func(_, message: Message):
     if len(message.command) != 3:
-        await message.reply_text("**Usage:**\n/deactivate_pipe [FROM_CHAT_ID] [TO_CHAT_ID]")
+        await message.reply_text(
+            "**Usage:**\n/deactivate_pipe [FROM_CHAT_ID] [TO_CHAT_ID]"
+        )
         return
     text = message.text.strip().split()
     from_chat = int(text[1])
@@ -156,6 +159,8 @@ async def show_pipes_func(_, message: Message):
         return
     text = ""
     for count, pipe in enumerate(pipes, 1):
-        text += f"**Pipe:** `{count}`\n**From:** `{pipe['from_chat_id']}`\n" \
-                + f"**To:** `{pipe['to_chat_id']}`\n**Fetcher:** `{pipe['fetcher']}`\n\n"
+        text += (
+            f"**Pipe:** `{count}`\n**From:** `{pipe['from_chat_id']}`\n"
+            + f"**To:** `{pipe['to_chat_id']}`\n**Fetcher:** `{pipe['fetcher']}`\n\n"
+        )
     await message.reply_text(text)

+ 41 - 19
wbb/modules/pmpermit.py

@@ -22,17 +22,24 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 
-from wbb import app, app2, BOT_ID, USERBOT_ID, SUDOERS, USERBOT_PREFIX
 from pyrogram import filters
-from wbb.utils.dbfunctions import is_pmpermit_approved, approve_pmpermit, disapprove_pmpermit
-from wbb.modules.userbot import edit_or_reply
+
+from wbb import BOT_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX, app, app2
 from wbb.core.decorators.errors import capture_err
-import asyncio
+from wbb.modules.userbot import edit_or_reply
+from wbb.utils.dbfunctions import (approve_pmpermit, disapprove_pmpermit,
+                                   is_pmpermit_approved)
 
 flood = {}
 
 
-@app2.on_message(filters.private & ~filters.edited & ~filters.me & ~filters.bot & ~filters.user(SUDOERS))
+@app2.on_message(
+    filters.private
+    & ~filters.edited
+    & ~filters.me
+    & ~filters.bot
+    & ~filters.user(SUDOERS)
+)
 @capture_err
 async def pmpermit_func(_, message):
     user_id = message.from_user.id
@@ -51,14 +58,15 @@ async def pmpermit_func(_, message):
         return
     results = await app2.get_inline_bot_results(BOT_ID, f"pmpermit {user_id}")
     await app2.send_inline_bot_result(
-            user_id,
-            results.query_id,
-            results.results[0].id,
-            hide_via=True
-            )
+        user_id, results.query_id, results.results[0].id, hide_via=True
+    )
 
 
-@app2.on_message(filters.command("approve", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot)
+@app2.on_message(
+    filters.command("approve", prefixes=USERBOT_PREFIX)
+    & filters.user(SUDOERS)
+    & ~filters.via_bot
+)
 @capture_err
 async def pm_approve(_, message):
     if not message.reply_to_message:
@@ -69,12 +77,14 @@ async def pm_approve(_, message):
         await edit_or_reply(message, text="User is already approved to pm")
         return
     await approve_pmpermit(user_id)
-    m = await edit_or_reply(message, text="User is approved to pm")
-    await asyncio.sleep(2)
-    await m.delete()
+    await edit_or_reply(message, text="User is approved to pm")
 
 
-@app2.on_message(filters.command("disapprove", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot)
+@app2.on_message(
+    filters.command("disapprove", prefixes=USERBOT_PREFIX)
+    & filters.user(SUDOERS)
+    & ~filters.via_bot
+)
 async def pm_disapprove(_, message):
     if not message.reply_to_message:
         await edit_or_reply(message, text="Reply to a user's message to approve.")
@@ -93,7 +103,11 @@ async def pm_disapprove(_, message):
     await edit_or_reply(message, text="User is disapproved to pm")
 
 
-@app2.on_message(filters.command("block", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot)
+@app2.on_message(
+    filters.command("block", prefixes=USERBOT_PREFIX)
+    & filters.user(SUDOERS)
+    & ~filters.via_bot
+)
 @capture_err
 async def block_user_func(_, message):
     if not message.reply_to_message:
@@ -104,7 +118,11 @@ async def block_user_func(_, message):
     await edit_or_reply(message, text="Successfully blocked the user")
 
 
-@app2.on_message(filters.command("unblock", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS) & ~filters.via_bot)
+@app2.on_message(
+    filters.command("unblock", prefixes=USERBOT_PREFIX)
+    & filters.user(SUDOERS)
+    & ~filters.via_bot
+)
 async def unblock_user_func(_, message):
     if not message.reply_to_message:
         await edit_or_reply(message, text="Reply to a user's message to unblock.")
@@ -128,7 +146,9 @@ async def pmpermit_cq(_, cq):
             await cq.answer("This Button Is Not For You")
             return
         await approve_pmpermit(int(victim))
-        await app.edit_inline_text(cq.inline_message_id, "User Has Been Approved To PM.")
+        await app.edit_inline_text(
+            cq.inline_message_id, "User Has Been Approved To PM."
+        )
         return
     if user_id == USERBOT_ID:
         await cq.answer("It's For The Other Person.")
@@ -150,4 +170,6 @@ async def pmpermit_cq(_, cq):
             await app2.send_message(user_id, "SPAM DETECTED, USER BLOCKED.")
             await app2.block_user(user_id)
             return
-        await app2.send_message(user_id, "I'm busy right now, will approve you shortly, DO NOT SPAM.")
+        await app2.send_message(
+            user_id, "I'm busy right now, will approve you shortly, DO NOT SPAM."
+        )

+ 1 - 0
wbb/modules/reddit.py

@@ -22,6 +22,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 from pyrogram import filters
+
 from wbb import app, arq
 from wbb.core.decorators.errors import capture_err
 

+ 8 - 5
wbb/modules/regex.py

@@ -23,9 +23,11 @@ SOFTWARE.
 """
 import re
 import sre_constants
+
+from pyrogram import filters
+
 from wbb import app
 from wbb.utils.filter_groups import regex_group
-from pyrogram import filters
 
 __MODULE__ = "Sed"
 __HELP__ = "**Usage:**\ns/foo/bar"
@@ -34,7 +36,9 @@ __HELP__ = "**Usage:**\ns/foo/bar"
 DELIMITERS = ("/", ":", "|", "_")
 
 
-@app.on_message(filters.regex(r"s([{}]).*?\1.*".format("".join(DELIMITERS))), group=regex_group)
+@app.on_message(
+    filters.regex(r"s([{}]).*?\1.*".format("".join(DELIMITERS))), group=regex_group
+)
 async def sed(_, message):
     sed_result = separate_sed(message.text)
     if message.reply_to_message:
@@ -64,8 +68,7 @@ async def sed(_, message):
             if "i" in flags and "g" in flags:
                 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).strip()
+                text = re.sub(repl, repl_with, to_fix, count=1, flags=re.I).strip()
             elif "g" in flags:
                 text = re.sub(repl, repl_with, to_fix).strip()
             else:
@@ -125,7 +128,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]

+ 5 - 3
wbb/modules/repo.py

@@ -22,19 +22,21 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 from pyrogram import filters
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.fetch import fetch
 
 __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)
 @capture_err
 async def repo(_, message):
-    users = await fetch("https://api.github.com/repos/thehamkercat/williambutcherbot/contributors")
+    users = await fetch(
+        "https://api.github.com/repos/thehamkercat/williambutcherbot/contributors"
+    )
     list_of_users = ""
     count = 1
     for user in users:

+ 23 - 16
wbb/modules/reverse.py

@@ -1,12 +1,14 @@
-from wbb import app, SUDOERS
-from wbb.core.decorators.errors import capture_err
-from pyrogram import filters
-from bs4 import BeautifulSoup
+import os
 from random import randint
-import aiohttp
+
 import aiofiles
+import aiohttp
 import requests
-import os
+from bs4 import BeautifulSoup
+from pyrogram import filters
+
+from wbb import SUDOERS, app
+from wbb.core.decorators.errors import capture_err
 
 __MODULE__ = "Reverse"
 __HELP__ = "/reverse  - Reverse search an image. [SUDOERS ONLY]"
@@ -22,8 +24,16 @@ async def reverse_image_search(_, message):
         await message.reply_text("Reply to a message to reverse search it.")
         return
     reply = message.reply_to_message
-    if not reply.document and not reply.photo and not reply.sticker and not reply.animation and not reply.video:
-        await message.reply_text("Reply to an image/document/sticker/animation to reverse search it.")
+    if (
+        not reply.document
+        and not reply.photo
+        and not reply.sticker
+        and not reply.animation
+        and not reply.video
+    ):
+        await message.reply_text(
+            "Reply to an image/document/sticker/animation to reverse search it."
+        )
         return
     m = await message.reply_text("Searching")
     if reply.document:
@@ -61,10 +71,7 @@ async def reverse_image_search(_, message):
     async with aiofiles.open(image, "rb") as f:
         if image:
             search_url = "http://www.google.com/searchbyimage/upload"
-            multipart = {
-                "encoded_image": (image, await f.read()),
-                "image_content": ""
-            }
+            multipart = {"encoded_image": (image, await f.read()), "image_content": ""}
             response = requests.post(search_url, files=multipart, allow_redirects=False)
             location = response.headers.get("Location")
             os.remove(image)
@@ -82,10 +89,10 @@ async def reverse_image_search(_, message):
     text = anchor_element.text
     try:
         await app.send_photo(
-                message.chat.id,
-                photo=f"https://webshot.amanoteam.com/print?q={location}",
-                caption=f"**Query** [{text}]({location})"
-                )
+            message.chat.id,
+            photo=f"https://webshot.amanoteam.com/print?q={location}",
+            caption=f"**Query** [{text}]({location})",
+        )
         await m.delete()
     except Exception:
         text = f"**Result**: [Link]({location})"

+ 20 - 23
wbb/modules/rice.py

@@ -22,8 +22,9 @@ 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 Message, InlineKeyboardMarkup, InlineKeyboardButton
-from pyrogram.types import InputMediaPhoto, InputMediaVideo
+from pyrogram.types import (InlineKeyboardButton, InlineKeyboardMarkup,
+                            InputMediaPhoto, InputMediaVideo, Message)
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
 
@@ -31,11 +32,13 @@ RICE_GROUP = "DE_WM"
 RICE_CHANNEL = "RiceGallery"
 
 
-@app.on_message(filters.chat(RICE_GROUP)
-                & (filters.photo | filters.video | filters.document)
-                & filters.regex(r"^\[RICE\] ")
-                & ~filters.forwarded
-                & ~filters.edited)
+@app.on_message(
+    filters.chat(RICE_GROUP)
+    & (filters.photo | filters.video | filters.document)
+    & filters.regex(r"^\[RICE\] ")
+    & ~filters.forwarded
+    & ~filters.edited
+)
 @capture_err
 async def rice(_, message: Message):
     """Forward media and media_group messages which has caption starts
@@ -47,19 +50,13 @@ async def rice(_, message: Message):
         reply_markup=InlineKeyboardMarkup(
             [
                 [
-                    InlineKeyboardButton(
-                        "Approve (Forward)",
-                        callback_data="forward"
-                    ),
-                    InlineKeyboardButton(
-                        "Ignore",
-                        callback_data="ignore"
-                    )
+                    InlineKeyboardButton("Approve (Forward)", callback_data="forward"),
+                    InlineKeyboardButton("Ignore", callback_data="ignore"),
                 ]
             ]
         ),
         quote=True,
-        parse_mode="markdown"
+        parse_mode="markdown",
     )
 
 
@@ -82,13 +79,11 @@ async def callback_query_forward_rice(_, callback_query):
         arg_media = []
         for m in media_group:
             if m.photo and m.caption:
-                arg_media.append(InputMediaPhoto(m.photo.file_id,
-                                                 caption=arg_caption))
+                arg_media.append(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))
+                arg_media.append(InputMediaVideo(m.video.file_id, caption=arg_caption))
             elif m.video:
                 arg_media.append(InputMediaVideo(m.video.file_id))
         m_cp = await app.send_media_group(RICE_CHANNEL, arg_media)
@@ -97,9 +92,11 @@ async def callback_query_forward_rice(_, callback_query):
         m_cp = await m_op.copy(RICE_CHANNEL, caption=arg_caption)
         link = m_cp.link
     await callback_query.message.delete()
-    reply_text = (f"**OP**: {u_op.mention()}\n"
-                  f"**Approver**: {u_approver.mention()}\n"
-                  f"**Forwarded**: [Rice Gallery]({link})")
+    reply_text = (
+        f"**OP**: {u_op.mention()}\n"
+        f"**Approver**: {u_approver.mention()}\n"
+        f"**Forwarded**: [Rice Gallery]({link})"
+    )
     await m_op.reply_text(reply_text, disable_web_page_preview=True)
 
 

+ 52 - 38
wbb/modules/stickers.py

@@ -21,22 +21,31 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-import os
 import imghdr
-from wbb import app, BOT_USERNAME
+import os
+
 from pyrogram import filters
-from wbb.core.decorators.errors import capture_err
-from wbb.utils.files import resize_file_to_sticker_size, upload_document, get_document_from_file_id
-from wbb.utils.stickerset import get_sticker_set_by_name, create_sticker, add_sticker_to_set, create_sticker_set
+from pyrogram.errors.exceptions.bad_request_400 import (PeerIdInvalid,
+                                                        StickerPngDimensions,
+                                                        StickerPngNopng,
+                                                        UserIsBlocked)
 from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
-from pyrogram.errors.exceptions.bad_request_400 import PeerIdInvalid, StickerPngNopng, UserIsBlocked, StickerPngDimensions
+
+from wbb import BOT_USERNAME, app
+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)
+from wbb.utils.stickerset import (add_sticker_to_set, create_sticker,
+                                  create_sticker_set, get_sticker_set_by_name)
 
 __MODULE__ = "Stickers"
 __HELP__ = """/sticker_id - To Get File ID of A Sticker.
 /kang - To Kang A Sticker or Image."""
 
-MAX_STICKERS = 120  # would be better if we could fetch this limit directly from telegram
-SUPPORTED_TYPES = ['jpeg', 'png', 'webp']
+MAX_STICKERS = (
+    120  # would be better if we could fetch this limit directly from telegram
+)
+SUPPORTED_TYPES = ["jpeg", "png", "webp"]
 
 
 @app.on_message(filters.command("sticker_id") & ~filters.edited)
@@ -70,14 +79,12 @@ async def kang(client, 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
     if message.reply_to_message.sticker:
         sticker = await create_sticker(
-                await get_document_from_file_id(
-                    message.reply_to_message.sticker.file_id
-                    ),
-                sticker_emoji
-                )
+            await get_document_from_file_id(message.reply_to_message.sticker.file_id),
+            sticker_emoji,
+        )
     elif doc:
         temp_file_path = await app.download_media(doc)
         image_type = imghdr.what(temp_file_path)
@@ -89,16 +96,13 @@ async def kang(client, message):
         except OSError as e:
             await msg.edit_text("Something wrong happened.")
             raise Exception(
-                f"Something went wrong while resizing the sticker (at {temp_file_path}); {e}")
+                f"Something went wrong while resizing the sticker (at {temp_file_path}); {e}"
+            )
             return False
         sticker = await create_sticker(
-                await upload_document(
-                    client,
-                    temp_file_path,
-                    message.chat.id
-                    ),
-                sticker_emoji
-                )
+            await upload_document(client, temp_file_path, message.chat.id),
+            sticker_emoji,
+        )
         if os.path.isfile(temp_file_path):
             os.remove(temp_file_path)
     else:
@@ -114,32 +118,42 @@ async def kang(client, message):
             stickerset = await get_sticker_set_by_name(client, packname)
             if not stickerset:
                 stickerset = await create_sticker_set(
-                        client,
-                        message.from_user.id,
-                        f"{message.from_user.first_name[:32]}'s kang pack",
-                        packname,
-                        [sticker]
-                        )
+                    client,
+                    message.from_user.id,
+                    f"{message.from_user.first_name[:32]}'s kang pack",
+                    packname,
+                    [sticker],
+                )
             elif stickerset.set.count >= MAX_STICKERS:
                 packnum += 1
-                packname = "f" + str(packnum) + "_" + \
-                    str(message.from_user.id) + "_by_"+BOT_USERNAME
+                packname = (
+                    "f"
+                    + str(packnum)
+                    + "_"
+                    + str(message.from_user.id)
+                    + "_by_"
+                    + BOT_USERNAME
+                )
                 continue
             else:
                 await add_sticker_to_set(client, stickerset, sticker)
             break
 
         await msg.edit(
-                "Sticker Kanged To [Pack](t.me/addstickers/{})\nEmoji: {}".format(
-                    packname,
-                    sticker_emoji
-                    )
-                )
+            "Sticker Kanged To [Pack](t.me/addstickers/{})\nEmoji: {}".format(
+                packname, sticker_emoji
+            )
+        )
     except (PeerIdInvalid, UserIsBlocked):
         keyboard = InlineKeyboardMarkup(
-            [[InlineKeyboardButton(text="Start", url=f"t.me/{BOT_USERNAME}")]])
-        await msg.edit("You Need To Start A Private Chat With Me.", reply_markup=keyboard)
+            [[InlineKeyboardButton(text="Start", url=f"t.me/{BOT_USERNAME}")]]
+        )
+        await msg.edit(
+            "You Need To Start A Private Chat With Me.", reply_markup=keyboard
+        )
     except StickerPngNopng:
-        await message.reply_text("Stickers must be png files but the provided image was not a png")
+        await message.reply_text(
+            "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.")

+ 39 - 15
wbb/modules/sudo.py

@@ -21,13 +21,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app2, SUDOERS, USERBOT_ID, BOT_ID, USERBOT_PREFIX
-from wbb.core.decorators.errors import capture_err
-from wbb.utils.dbfunctions import add_sudo, remove_sudo, get_sudoers
-from wbb.modules.userbot import edit_or_reply
+import os
+
 from pyrogram import filters
 from pyrogram.types import Message
-import asyncio
+
+from wbb import BOT_ID, SUDOERS, USERBOT_PREFIX, app2
+from wbb.core.decorators.errors import capture_err
+from wbb.modules.userbot import edit_or_reply
+from wbb.utils.dbfunctions import add_sudo, get_sudoers, remove_sudo
 
 __MODULE__ = "Sudo"
 __HELP__ = """
@@ -45,28 +47,44 @@ can even delete your account.
 """
 
 
-@app2.on_message(filters.command("useradd", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS))
-async def useradd(_, message):
+@app2.on_message(
+    filters.command("useradd", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
+@capture_err
+async def useradd(_, message: Message):
     if not message.reply_to_message:
-        await edit_or_reply(message, text="Reply to someone's message to add him to sudoers.")
+        await edit_or_reply(
+            message, text="Reply to someone's message to add him to sudoers."
+        )
         return
     user_id = message.reply_to_message.from_user.id
     sudoers = await get_sudoers()
     if user_id in sudoers:
         await edit_or_reply(message, text="User is already in sudoers.")
         return
+    if user_id == BOT_ID:
+        await edit_or_reply(message, text="You can't add assistant bot in sudoers.")
+        return
     added = await add_sudo(user_id)
     if added:
-        await edit_or_reply(message, text="Successfully added user in sudoers, Bot will be restarted now.")
+        await edit_or_reply(
+            message,
+            text="Successfully added user in sudoers, Bot will be restarted now.",
+        )
         os.execvp("python3", ["python3", "-m", "wbb"])
         return
     await edit_or_reply(message, text="Something wrong happened, check logs.")
 
 
-@app2.on_message(filters.command("userdel", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS))
-async def userdel(_, message):
+@app2.on_message(
+    filters.command("userdel", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
+@capture_err
+async def userdel(_, message: Message):
     if not message.reply_to_message:
-        await edit_or_reply(message, text="Reply to someone's message to remove him to sudoers.")
+        await edit_or_reply(
+            message, text="Reply to someone's message to remove him to sudoers."
+        )
         return
     user_id = message.reply_to_message.from_user.id
     if user_id not in await get_sudoers():
@@ -74,14 +92,20 @@ async def userdel(_, message):
         return
     removed = await remove_sudo(user_id)
     if removed:
-        await edit_or_reply(message, text="Successfully removed user from sudoers, Bot will be restarted now.")
+        await edit_or_reply(
+            message,
+            text="Successfully removed user from sudoers, Bot will be restarted now.",
+        )
         os.execvp("python3", ["python3", "-m", "wbb"])
         return
     await edit_or_reply(message, text="Something wrong happened, check logs.")
 
 
-@app2.on_message(filters.command("sudoers", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS))
-async def sudoers_list(_, message):
+@app2.on_message(
+    filters.command("sudoers", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
+@capture_err
+async def sudoers_list(_, message: Message):
     sudoers = await get_sudoers()
     text = ""
     for count, user_id in enumerate(sudoers, 1):

+ 69 - 47
wbb/modules/sudoers.py

@@ -21,33 +21,29 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-import time
+import asyncio
 import os
 import subprocess
-from pyrogram import filters
+import time
+
 import psutil
-import asyncio
-from wbb import (
-    app, SUDOERS, bot_start_time, BOT_ID, USERBOT_USERNAME, GBAN_LOG_GROUP_ID
-)
-from wbb.utils import formatter
-from wbb.core.decorators.errors import capture_err
-from wbb.utils.dbfunctions import (
-    is_gbanned_user,
-    add_gban_user,
-    remove_gban_user,
-    get_served_chats
-)
+from pyrogram import filters
 
+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)
 
 __MODULE__ = "Sudoers"
-__HELP__ = '''
+__HELP__ = """
 /stats - To Check System Status.
 /gstats - To Check Bot's Global Stats.
 /gban - To Ban A User Globally.
 /broadcast - To Broadcast A Message To All Groups.
 /update - To Update And Restart The Bot
-'''
+"""
 
 # Stats Module
 
@@ -58,7 +54,7 @@ async def bot_sys_stats():
     mem = psutil.virtual_memory().percent
     disk = psutil.disk_usage("/").percent
     process = psutil.Process(os.getpid())
-    stats = f'''
+    stats = f"""
 {USERBOT_USERNAME}@William
 ------------------
 UPTIME: {formatter.get_readable_time((bot_uptime))}
@@ -66,18 +62,17 @@ BOT: {round(process.memory_info()[0] / 1024 ** 2)} MB
 CPU: {cpu}%
 RAM: {mem}%
 DISK: {disk}%
-'''
+"""
     return stats
 
 
-@app.on_message(
-    filters.user(SUDOERS) & filters.command("stats")
-)
+@app.on_message(filters.user(SUDOERS) & filters.command("stats"))
 @capture_err
 async def get_stats(_, message):
     stats = await bot_sys_stats()
     await message.reply_text(stats)
 
+
 # Gban
 
 
@@ -92,31 +87,37 @@ async def ban_globally(_, message):
         reason = message.text.split(None, 2)[2]
         if "@" in user:
             user = user.replace("@", "")
-        user = (await app.get_users(user))
+        user = await app.get_users(user)
         from_user = message.from_user
         if user.id == from_user.id:
             await message.reply_text("You want to gban yourself? FOOL!")
         elif user.id == BOT_ID:
-            await message.reply_text("Should i gban myself? I'm not fool like you, HUMAN!")
+            await message.reply_text(
+                "Should i gban myself? I'm not fool like you, HUMAN!"
+            )
         elif user.id in SUDOERS:
             await message.reply_text("You want to ban a sudo user? GET REKT!!")
         else:
             served_chats = await get_served_chats()
-            m = await message.reply_text(f"**Initializing WBB Global Ban Sequence To Add Restrictions On {user.mention}**"
-                                         + f" **This Action Should Take About {len(served_chats)} Seconds.**")
+            m = await message.reply_text(
+                f"**Initializing WBB Global Ban Sequence To Add Restrictions On {user.mention}**"
+                + f" **This Action Should Take About {len(served_chats)} Seconds.**"
+            )
             await add_gban_user(user.id)
             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 Exception:
                     pass
             try:
                 await app.send_message(
-                    user.id, f"Hello, You have been globally banned by {from_user.mention},"
-                    + " You can appeal for this ban in @WBBSupport.")
+                    user.id,
+                    f"Hello, You have been globally banned by {from_user.mention},"
+                    + " You can appeal for this ban in @WBBSupport.",
+                )
             except Exception:
                 pass
             await m.edit(f"Banned {user.mention} Globally!")
@@ -129,10 +130,17 @@ __**New Global Ban**__
 **Reason:** __{reason}__
 **Chats:** `{number_of_chats}`"""
             try:
-                m2 = await app.send_message(GBAN_LOG_GROUP_ID, text=ban_text, disable_web_page_preview=True)
-                await m.edit(f"Banned {user.mention} Globally!\nAction Log: {m2.link}", disable_web_page_preview=True)
+                m2 = await app.send_message(
+                    GBAN_LOG_GROUP_ID, text=ban_text, disable_web_page_preview=True
+                )
+                await m.edit(
+                    f"Banned {user.mention} Globally!\nAction Log: {m2.link}",
+                    disable_web_page_preview=True,
+                )
             except Exception:
-                await message.reply_text("User Gbanned, But This Gban Wasn't Logged, Add Bot In GBAN_LOG_GROUP")
+                await message.reply_text(
+                    "User Gbanned, But This Gban Wasn't Logged, Add Bot In GBAN_LOG_GROUP"
+                )
                 return
         return
     if len(message.command) < 2:
@@ -155,12 +163,14 @@ __**New Global Ban**__
             await message.reply_text("He's already gbanned, why bully him?")
         else:
             served_chats = await get_served_chats()
-            m = await message.reply_text(f"**Initializing WBB Global Ban Sequence To Add Restrictions On {mention}**"
-                                         + f" **This Action Should Take About {len(served_chats)} Seconds.**")
+            m = await message.reply_text(
+                f"**Initializing WBB Global Ban Sequence To Add Restrictions On {mention}**"
+                + f" **This Action Should Take About {len(served_chats)} Seconds.**"
+            )
             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 Exception:
@@ -168,9 +178,11 @@ __**New Global Ban**__
             await add_gban_user(user_id)
             try:
                 await app.send_message(
-                    user_id, f"""
+                    user_id,
+                    f"""
 Hello, You have been globally banned by {from_user_mention},
-You can appeal for this ban in @WBBSupport.""")
+You can appeal for this ban in @WBBSupport.""",
+                )
             except Exception:
                 pass
             await m.edit(f"Banned {mention} Globally!")
@@ -183,12 +195,20 @@ __**New Global Ban**__
 **Reason:** __{reason}__
 **Chats:** `{number_of_chats}`"""
             try:
-                m2 = await app.send_message(GBAN_LOG_GROUP_ID, text=ban_text, disable_web_page_preview=True)
-                await m.edit(f"Banned {mention} Globally!\nAction Log: {m2.link}", disable_web_page_preview=True)
+                m2 = await app.send_message(
+                    GBAN_LOG_GROUP_ID, text=ban_text, disable_web_page_preview=True
+                )
+                await m.edit(
+                    f"Banned {mention} Globally!\nAction Log: {m2.link}",
+                    disable_web_page_preview=True,
+                )
             except Exception:
-                await message.reply_text("User Gbanned, But This Gban Wasn't Logged, Add Bot In GBAN_LOG_GROUP")
+                await message.reply_text(
+                    "User Gbanned, But This Gban Wasn't Logged, Add Bot In GBAN_LOG_GROUP"
+                )
                 return
 
+
 # Ungban
 
 
@@ -197,12 +217,14 @@ __**New Global Ban**__
 async def unban_globally(_, message):
     if not message.reply_to_message:
         if len(message.command) != 2:
-            await message.reply_text("Reply to a user's message or give username/user_id.")
+            await message.reply_text(
+                "Reply to a user's message or give username/user_id."
+            )
             return
         user = message.text.split(None, 1)[1]
         if "@" in user:
             user = user.replace("@", "")
-        user = (await app.get_users(user))
+        user = await app.get_users(user)
         from_user = message.from_user
         if user.id == from_user.id:
             await message.reply_text("You want to ungban yourself? FOOL!")
@@ -236,14 +258,11 @@ async def unban_globally(_, message):
             await remove_gban_user(user_id)
             await message.reply_text(f"Unbanned {mention} Globally!")
 
+
 # Broadcast
 
 
-@app.on_message(
-    filters.command("broadcast")
-    & filters.user(SUDOERS)
-    & ~filters.edited
-)
+@app.on_message(filters.command("broadcast") & filters.user(SUDOERS) & ~filters.edited)
 @capture_err
 async def broadcast_message(_, message):
     if len(message.command) < 2:
@@ -266,7 +285,10 @@ async def broadcast_message(_, message):
 
 # Update
 
+
 @app.on_message(filters.command("update") & filters.user(SUDOERS))
 async def update_restart(_, message):
-    await message.reply_text(f'```{subprocess.check_output(["git", "pull"]).decode("UTF-8")}```')
+    await message.reply_text(
+        f'```{subprocess.check_output(["git", "pull"]).decode("UTF-8")}```'
+    )
     os.execvp("python3", ["python3", "-m", "wbb"])

+ 15 - 7
wbb/modules/telegraph.py

@@ -3,8 +3,10 @@
 # Part of Pull Req #2 by @MaskedVirus | github.com/swatv3nub
 
 import os
-from telegraph import upload_file
+
 from pyrogram import filters
+from telegraph import upload_file
+
 from wbb import app
 from wbb.core.decorators.errors import capture_err
 
@@ -28,14 +30,16 @@ async def tgphoto(client, message):
         return
     msg = await message.reply_text("`Uploading to Telegraph...`")
     userid = str(message.chat.id)
-    path = (f"./DOWNLOADS/{userid}.jpg")
+    path = f"./DOWNLOADS/{userid}.jpg"
     path = await client.download_media(message=message.reply_to_message, file_name=path)
     try:
         tlink = upload_file(path)
     except Exception:
         await msg.edit_text("Something went Wrong.")
     else:
-        await msg.edit_text(f"Successfully Uploaded to [Telegraph](https://telegra.ph{tlink[0]})")
+        await msg.edit_text(
+            f"Successfully Uploaded to [Telegraph](https://telegra.ph{tlink[0]})"
+        )
         os.remove(path)
 
 
@@ -48,14 +52,18 @@ async def tgvideo(client, message):
     if not message.reply_to_message.video:
         await message.reply_text("Works only for Videos")
         return
-    if(message.video.file_size < 5242880):
+    if message.video.file_size < 5242880:
         msg = await message.reply_text("Uploading to Telegraph...")
         userid = str(message.chat.id)
-        vid_path = (f"./DOWNLOADS/{userid}.mp4")
-        vid_path = await client.download_media(message=message.reply_to_message, file_name=vid_path)
+        vid_path = f"./DOWNLOADS/{userid}.mp4"
+        vid_path = await client.download_media(
+            message=message.reply_to_message, file_name=vid_path
+        )
         try:
             tlink = upload_file(vid_path)
-            await msg.edit_text(f"Successfully Uploaded to [Telegraph](https://telegra.ph{tlink[0]})")
+            await msg.edit_text(
+                f"Successfully Uploaded to [Telegraph](https://telegra.ph{tlink[0]})"
+            )
             os.remove(vid_path)
         except Exception:
             await msg.edit_text("Something went Wrong.")

+ 7 - 5
wbb/modules/tts.py

@@ -21,13 +21,15 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app
-from wbb.core.decorators.errors import capture_err
-from gtts import gTTS
+from io import BytesIO
+
 from googletrans import Translator
-from pyrogram.types import Message
+from gtts import gTTS
 from pyrogram import filters
-from io import BytesIO
+from pyrogram.types import Message
+
+from wbb import app
+from wbb.core.decorators.errors import capture_err
 
 __MODULE__ = "TTS"
 __HELP__ = "/tts - Convert Text To Speech."

+ 45 - 33
wbb/modules/userbot.py

@@ -5,17 +5,19 @@
             https://github.com/pokurt/Nana-Remix/blob/master/nana/plugins/devs.py
 """
 
-import sys
-import traceback
-from io import StringIO
 import os
 import re
 import subprocess
+import sys
+import traceback
 from inspect import getfullargspec
-from wbb import app, app2, SUDOERS, USERBOT_PREFIX
+from io import StringIO
+
 from pyrogram import filters
 from pyrogram.types import Message
 
+from wbb import SUDOERS, USERBOT_PREFIX, app, app2
+
 __MODULE__ = "Userbot"
 __HELP__ = """
 .alive - Send Alive Message.
@@ -28,6 +30,7 @@ __HELP__ = """
 
 # Eval and Sh module from nana-remix
 
+
 async def aexec(code, client, message):
     exec(
         "async def __aexec(client, message): "
@@ -42,8 +45,12 @@ async def edit_or_reply(msg: Message, **kwargs):
     await func(**{k: v for k, v in kwargs.items() if k in spec})
 
 
-@app2.on_message(filters.user(SUDOERS) & ~filters.forwarded &
-                 ~filters.via_bot & filters.command("l", prefixes=USERBOT_PREFIX))
+@app2.on_message(
+    filters.user(SUDOERS)
+    & ~filters.forwarded
+    & ~filters.via_bot
+    & filters.command("l", prefixes=USERBOT_PREFIX)
+)
 async def executor(client, message):
     try:
         cmd = message.text.split(" ", maxsplit=1)[1]
@@ -75,8 +82,7 @@ async def executor(client, message):
         evaluation = stdout
     else:
         evaluation = "Success"
-    final_output = (
-        f"**INPUT:**\n```{cmd}```\n\n**OUTPUT**:\n```{evaluation.strip()}```")
+    final_output = f"**INPUT:**\n```{cmd}```\n\n**OUTPUT**:\n```{evaluation.strip()}```"
     if len(final_output) > 4096:
         filename = "output.txt"
         with open(filename, "w+", encoding="utf8") as out_file:
@@ -97,68 +103,74 @@ async def executor(client, message):
     filters.user(SUDOERS)
     & ~filters.forwarded
     & ~filters.via_bot
-    & filters.command('sh', prefixes=USERBOT_PREFIX),
+    & filters.command("sh", prefixes=USERBOT_PREFIX),
 )
 async def shellrunner(client, message):
     if len(message.command) < 2:
-        await edit_or_reply(message, text='**Usage:**\n/sh git pull')
+        await edit_or_reply(message, text="**Usage:**\n/sh git pull")
         return
     text = message.text.split(None, 1)[1]
-    if '\n' in text:
-        code = text.split('\n')
-        output = ''
+    if "\n" in text:
+        code = text.split("\n")
+        output = ""
         for x in code:
             shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x)
             try:
                 process = subprocess.Popen(
-                    shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                    shell,
+                    stdout=subprocess.PIPE,
+                    stderr=subprocess.PIPE,
                 )
             except Exception as err:
                 print(err)
                 await edit_or_reply(
-                    message,
-                    text=f"**INPUT:**\n```{text}```\n\n**ERROR:**\n```{err}```")
-            output += f'**{code}**\n'
-            output += process.stdout.read()[:-1].decode('utf-8')
-            output += '\n'
+                    message, text=f"**INPUT:**\n```{text}```\n\n**ERROR:**\n```{err}```"
+                )
+            output += f"**{code}**\n"
+            output += process.stdout.read()[:-1].decode("utf-8")
+            output += "\n"
     else:
         shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", text)
         for a in range(len(shell)):
-            shell[a] = shell[a].replace('"', '')
+            shell[a] = shell[a].replace('"', "")
         try:
             process = subprocess.Popen(
-                shell, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
+                shell,
+                stdout=subprocess.PIPE,
+                stderr=subprocess.PIPE,
             )
         except Exception as err:
             print(err)
             exc_type, exc_obj, exc_tb = sys.exc_info()
             errors = traceback.format_exception(
-                etype=exc_type, value=exc_obj, tb=exc_tb,
+                etype=exc_type,
+                value=exc_obj,
+                tb=exc_tb,
             )
             await edit_or_reply(
                 message,
-                text=f"**INPUT:**\n```{text}```\n\n**ERROR:**\n```{''.join(errors)}```")
+                text=f"**INPUT:**\n```{text}```\n\n**ERROR:**\n```{''.join(errors)}```",
+            )
             return
-        output = process.stdout.read()[:-1].decode('utf-8')
-    if str(output) == '\n':
+        output = process.stdout.read()[:-1].decode("utf-8")
+    if str(output) == "\n":
         output = None
     if output:
         if len(output) > 4096:
-            with open('output.txt', 'w+') as file:
+            with open("output.txt", "w+") as file:
                 file.write(output)
             await app.send_document(
                 message.chat.id,
-                'output.txt',
+                "output.txt",
                 reply_to_message_id=message.message_id,
-                caption='`Output`',
+                caption="`Output`",
             )
-            os.remove('output.txt')
+            os.remove("output.txt")
             return
         await edit_or_reply(
-            message,
-            text=f"**INPUT:**\n```{text}```\n\n**OUTPUT:**\n```{output}```"
+            message, text=f"**INPUT:**\n```{text}```\n\n**OUTPUT:**\n```{output}```"
         )
     else:
         await edit_or_reply(
-            message,
-            text=f'**INPUT:**\n```{text}```\n\n**OUTPUT: **\n`No output`')
+            message, text=f"**INPUT:**\n```{text}```\n\n**OUTPUT: **\n`No output`"
+        )

+ 3 - 3
wbb/modules/webss.py

@@ -21,10 +21,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import app
-from wbb.core.decorators.errors import capture_err
 from pyrogram import filters
 
+from wbb import app
+from wbb.core.decorators.errors import capture_err
 
 __MODULE__ = "WebSS"
 __HELP__ = "/webss | .webss [URL] - Take A Screenshot Of A Webpage"
@@ -44,7 +44,7 @@ async def take_ss(_, message):
             await app.send_photo(
                 message.chat.id,
                 photo=f"https://webshot.amanoteam.com/print?q={url}",
-                )
+            )
         except TypeError:
             await m.edit("No Such Website.")
             return

+ 1 - 1
wbb/utils/__init__.py

@@ -21,5 +21,5 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
+from .misc import paginate_modules  # noqa: F401
 from .read_lines import random_line  # noqa: F401
-from .misc import paginate_modules   # noqa: F401

+ 1 - 0
wbb/utils/aiodownloader/__init__.py

@@ -1,2 +1,3 @@
 from .downloader import Handler
+
 Handler = Handler

+ 32 - 26
wbb/utils/aiodownloader/downloader.py

@@ -1,9 +1,9 @@
-import os
 import asyncio
-from typing import Optional, List
+import os
+from typing import Optional
 
-import aiohttp
 import aiofiles
+import aiohttp
 
 
 class DownloadJob:
@@ -16,19 +16,22 @@ class DownloadJob:
     :param save_path: dir where the file should be saved. Defaults to the current dir
     """
 
-    def __init__(self,
-                 session: aiohttp.ClientSession,
-                 file_url: str,
-                 save_path: Optional[str] = None,
-                 chunk_size: Optional[int] = 1024):
+    def __init__(
+        self,
+        session: aiohttp.ClientSession,
+        file_url: str,
+        save_path: Optional[str] = None,
+        chunk_size: Optional[int] = 1024,
+    ):
 
         self.file_url = file_url
         self._session = session
         self._chunk_size = chunk_size
 
-        self.file_name = file_url.split('/')[~0]
-        self.file_path = os.path.join(
-            save_path, self.file_name) if save_path else self.file_name
+        self.file_name = file_url.split("/")[~0]
+        self.file_path = (
+            os.path.join(save_path, self.file_name) if save_path else self.file_name
+        )
 
         self.completed = False
         self.progress = 0
@@ -42,12 +45,13 @@ class DownloadJob:
         if not self.size:
             async with self._session.get(self.file_url) as resp:
                 if 200 <= resp.status < 300:
-                    self.size = int(resp.headers['Content-Length'])
+                    self.size = int(resp.headers["Content-Length"])
 
                 else:
                     raise aiohttp.errors.HttpProcessingError(
-                        message=f'There was a problem processing {self.file_url}',
-                        code=resp.status)
+                        message=f"There was a problem processing {self.file_url}",
+                        code=resp.status,
+                    )
 
         return self.size
 
@@ -68,7 +72,7 @@ class DownloadJob:
             # Checkning the response code
             if 200 <= resp.status < 300:
                 # Saving the data to the file chunk by chunk.
-                async with aiofiles.open(self.file_path, 'wb') as file:
+                async with aiofiles.open(self.file_path, "wb") as file:
 
                     # Downloading the file using the aiohttp.StreamReader
                     async for data in resp.content.iter_chunked(self._chunk_size):
@@ -80,7 +84,9 @@ class DownloadJob:
 
             else:
                 raise aiohttp.errors.HttpProcessingError(
-                    message=f'There was a problem processing {self.file_url}', code=resp.status)
+                    message=f"There was a problem processing {self.file_url}",
+                    code=resp.status,
+                )
 
 
 class Handler:
@@ -93,18 +99,20 @@ class Handler:
     :param chunk_size: chunk bytes sizes to get from the file source. Defaults to 1024 bytes
     """
 
-    def __init__(self,
-                 loop: Optional[asyncio.BaseEventLoop] = None,
-                 session: Optional[aiohttp.ClientSession] = None,
-                 chunk_size: Optional[int] = 1024):
+    def __init__(
+        self,
+        loop: Optional[asyncio.BaseEventLoop] = None,
+        session: Optional[aiohttp.ClientSession] = None,
+        chunk_size: Optional[int] = 1024,
+    ):
 
         self._loop = loop or asyncio.get_event_loop()
         self._session = session or aiohttp.ClientSession(loop=self._loop)
         self._chunk_size = chunk_size
 
-    def _job_factory(self,
-                     file_url: str,
-                     save_path: Optional[str] = None) -> DownloadJob:
+    def _job_factory(
+        self, file_url: str, save_path: Optional[str] = None
+    ) -> DownloadJob:
         """
         Shortcut for creating a download job. It adds the session and the chunk size.
         :param file_url: url where the file is located
@@ -113,9 +121,7 @@ class Handler:
         """
         return DownloadJob(self._session, file_url, save_path, self._chunk_size)
 
-    async def download(self,
-                       url: str,
-                       save_path: Optional[str] = None) -> DownloadJob:
+    async def download(self, url: str, save_path: Optional[str] = None) -> DownloadJob:
         """
         Downloads a bulk of files from the given list of urls to the given path.
 

+ 49 - 160
wbb/utils/dbfunctions.py

@@ -21,8 +21,9 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from wbb import db
 from typing import Dict, List, Union
+
+from wbb import db
 from wbb.utils.functions import obj_to_str, str_to_obj
 
 notesdb = db.notes
@@ -52,13 +53,10 @@ async def get_notes_count() -> dict:
     chats_count = 0
     notes_count = 0
     for chat in await chats.to_list(length=1000000000):
-        notes_name = await get_note_names(chat['chat_id'])
+        notes_name = await get_note_names(chat["chat_id"])
         notes_count += len(notes_name)
         chats_count += 1
-    return {
-        "chats_count": chats_count,
-        "notes_count": notes_count
-    }
+    return {"chats_count": chats_count, "notes_count": notes_count}
 
 
 async def _get_notes(chat_id: int) -> Dict[str, int]:
@@ -90,13 +88,7 @@ async def save_note(chat_id: int, name: str, note: dict):
     _notes[name] = note
 
     await notesdb.update_one(
-        {"chat_id": chat_id},
-        {
-            "$set": {
-                "notes": _notes
-            }
-        },
-        upsert=True
+        {"chat_id": chat_id}, {"$set": {"notes": _notes}}, upsert=True
     )
 
 
@@ -106,13 +98,7 @@ async def delete_note(chat_id: int, name: str) -> bool:
     if name in notesd:
         del notesd[name]
         await notesdb.update_one(
-            {"chat_id": chat_id},
-            {
-                "$set": {
-                    "notes": notesd
-                }
-            },
-            upsert=True
+            {"chat_id": chat_id}, {"$set": {"notes": notesd}}, upsert=True
         )
         return True
     return False
@@ -128,20 +114,17 @@ async def get_filters_count() -> dict:
     chats_count = 0
     filters_count = 0
     for chat in await chats.to_list(length=1000000000):
-        filters_name = await get_filters_names(chat['chat_id'])
+        filters_name = await get_filters_names(chat["chat_id"])
         filters_count += len(filters_name)
         chats_count += 1
-    return {
-        "chats_count": chats_count,
-        "filters_count": filters_count
-    }
+    return {"chats_count": chats_count, "filters_count": filters_count}
 
 
 async def _get_filters(chat_id: int) -> Dict[str, int]:
     _filters = await filtersdb.find_one({"chat_id": chat_id})
     if not _filters:
         return {}
-    return _filters['filters']
+    return _filters["filters"]
 
 
 async def get_filters_names(chat_id: int) -> List[str]:
@@ -165,13 +148,7 @@ async def save_filter(chat_id: int, name: str, _filter: dict):
     _filters = await _get_filters(chat_id)
     _filters[name] = _filter
     await filtersdb.update_one(
-        {"chat_id": chat_id},
-        {
-            "$set": {
-                "filters": _filters
-            }
-        },
-        upsert=True
+        {"chat_id": chat_id}, {"$set": {"filters": _filters}}, upsert=True
     )
 
 
@@ -181,13 +158,7 @@ async def delete_filter(chat_id: int, name: str) -> bool:
     if name in filtersd:
         del filtersd[name]
         await filtersdb.update_one(
-            {"chat_id": chat_id},
-            {
-                "$set": {
-                    "filters": filtersd
-                }
-            },
-            upsert=True
+            {"chat_id": chat_id}, {"$set": {"filters": filtersd}}, upsert=True
         )
         return True
     return False
@@ -222,20 +193,17 @@ async def get_warns_count() -> dict:
     chats_count = 0
     warns_count = 0
     for chat in await chats.to_list(length=100000000):
-        for user in chat['warns']:
-            warns_count += chat['warns'][user]['warns']
+        for user in chat["warns"]:
+            warns_count += chat["warns"][user]["warns"]
         chats_count += 1
-    return {
-        "chats_count": chats_count,
-        "warns_count": warns_count
-    }
+    return {"chats_count": chats_count, "warns_count": warns_count}
 
 
 async def get_warns(chat_id: int) -> Dict[str, int]:
     warns = await warnsdb.find_one({"chat_id": chat_id})
     if not warns:
         return {}
-    return warns['warns']
+    return warns["warns"]
 
 
 async def get_warn(chat_id: int, name: str) -> Union[bool, dict]:
@@ -251,13 +219,7 @@ async def add_warn(chat_id: int, name: str, warn: dict):
     warns[name] = warn
 
     await warnsdb.update_one(
-        {"chat_id": chat_id},
-        {
-            "$set": {
-                "warns": warns
-            }
-        },
-        upsert=True
+        {"chat_id": chat_id}, {"$set": {"warns": warns}}, upsert=True
     )
 
 
@@ -267,13 +229,7 @@ async def remove_warns(chat_id: int, name: str) -> bool:
     if name in warnsd:
         del warnsd[name]
         await warnsdb.update_one(
-            {"chat_id": chat_id},
-            {
-                "$set": {
-                    "warns": warnsd
-                }
-            },
-            upsert=True
+            {"chat_id": chat_id}, {"$set": {"warns": warnsd}}, upsert=True
         )
         return True
     return False
@@ -289,13 +245,10 @@ async def get_karmas_count() -> dict:
     chats_count = 0
     karmas_count = 0
     for chat in await chats.to_list(length=1000000):
-        for i in chat['karma']:
-            karmas_count += chat['karma'][i]['karma']
+        for i in chat["karma"]:
+            karmas_count += chat["karma"][i]["karma"]
         chats_count += 1
-    return {
-        "chats_count": chats_count,
-        "karmas_count": karmas_count
-    }
+    return {"chats_count": chats_count, "karmas_count": karmas_count}
 
 
 async def user_global_karma(user_id) -> int:
@@ -304,10 +257,10 @@ 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:
-            if int(karma['karma']) > 0:
-                total_karma += int(karma['karma'])
+            if int(karma["karma"]) > 0:
+                total_karma += int(karma["karma"])
     return total_karma
 
 
@@ -315,7 +268,7 @@ async def get_karmas(chat_id: int) -> Dict[str, int]:
     karma = await karmadb.find_one({"chat_id": chat_id})
     if not karma:
         return {}
-    return karma['karma']
+    return karma["karma"]
 
 
 async def get_karma(chat_id: int, name: str) -> Union[bool, dict]:
@@ -330,13 +283,7 @@ async def update_karma(chat_id: int, name: str, karma: dict):
     karmas = await get_karmas(chat_id)
     karmas[name] = karma
     await karmadb.update_one(
-        {"chat_id": chat_id},
-        {
-            "$set": {
-                "karma": karmas
-            }
-        },
-        upsert=True
+        {"chat_id": chat_id}, {"$set": {"karma": karmas}}, upsert=True
     )
 
 
@@ -372,7 +319,7 @@ async def is_served_chat(chat_id: int) -> bool:
 
 
 async def get_served_chats() -> list:
-    chats = chatsdb.find({"chat_id": {'$lt': 0}})
+    chats = chatsdb.find({"chat_id": {"$lt": 0}})
     if not chats:
         return []
     chats_list = []
@@ -427,6 +374,7 @@ async def remove_gban_user(user_id: int):
 
 # Couple Chooser
 
+
 async def _get_lovers(chat_id: int):
     lovers = await coupledb.find_one({"chat_id": chat_id})
     if not lovers:
@@ -446,15 +394,10 @@ async def save_couple(chat_id: int, date: str, couple: dict):
     lovers = await _get_lovers(chat_id)
     lovers[date] = couple
     await coupledb.update_one(
-        {"chat_id": chat_id},
-        {
-            "$set": {
-                "couple": lovers
-            }
-        },
-        upsert=True
+        {"chat_id": chat_id}, {"$set": {"couple": lovers}}, upsert=True
     )
 
+
 # Captcha
 
 
@@ -478,6 +421,7 @@ async def captcha_off(chat_id: int):
         return
     return await captchadb.insert_one({"chat_id": chat_id})
 
+
 """Anti Service System"""
 
 
@@ -531,18 +475,12 @@ async def disapprove_pmpermit(user_id: int):
 
 async def get_welcome(chat_id: int) -> str:
     text = await welcomedb.find_one({"chat_id": chat_id})
-    return text['text']
+    return text["text"]
 
 
 async def set_welcome(chat_id: int, text: str):
     return await welcomedb.update_one(
-        {"chat_id": chat_id},
-        {
-            "$set": {
-                "text": text
-            }
-        },
-        upsert=True
+        {"chat_id": chat_id}, {"$set": {"text": text}}, upsert=True
     )
 
 
@@ -583,13 +521,7 @@ async def update_captcha_cache(captcha_dict):
     if not pickle:
         return
     await captcha_cachedb.update_one(
-        {"captcha": "cache"},
-        {
-            "$set": {
-                "pickled": pickle
-            }
-        },
-        upsert=True
+        {"captcha": "cache"}, {"$set": {"pickled": pickle}}, upsert=True
     )
 
 
@@ -597,7 +529,7 @@ async def get_captcha_cache():
     cache = await captcha_cachedb.find_one({"captcha": "cache"})
     if not cache:
         return []
-    return str_to_obj(cache['pickled'])
+    return str_to_obj(cache["pickled"])
 
 
 """ BLACKLIST FILTERS SYSTEM """
@@ -610,20 +542,17 @@ async def get_blacklist_filters_count() -> dict:
     chats_count = 0
     filters_count = 0
     for chat in await chats.to_list(length=1000000000):
-        filters = await get_blacklisted_words(chat['chat_id'])
+        filters = await get_blacklisted_words(chat["chat_id"])
         filters_count += len(filters)
         chats_count += 1
-    return {
-        "chats_count": chats_count,
-        "filters_count": filters_count
-    }
+    return {"chats_count": chats_count, "filters_count": filters_count}
 
 
 async def get_blacklisted_words(chat_id: int) -> List[str]:
     _filters = await blacklist_filtersdb.find_one({"chat_id": chat_id})
     if not _filters:
         return []
-    return _filters['filters']
+    return _filters["filters"]
 
 
 async def save_blacklist_filter(chat_id: int, word: str):
@@ -631,13 +560,7 @@ async def save_blacklist_filter(chat_id: int, word: str):
     _filters = await get_blacklisted_words(chat_id)
     _filters.append(word)
     await blacklist_filtersdb.update_one(
-        {"chat_id": chat_id},
-        {
-            "$set": {
-                "filters": _filters
-            }
-        },
-        upsert=True
+        {"chat_id": chat_id}, {"$set": {"filters": _filters}}, upsert=True
     )
 
 
@@ -647,36 +570,21 @@ async def delete_blacklist_filter(chat_id: int, word: str) -> bool:
     if word in filtersd:
         filtersd.remove(word)
         await blacklist_filtersdb.update_one(
-            {"chat_id": chat_id},
-            {
-                "$set": {
-                    "filters": filtersd
-                }
-            },
-            upsert=True
+            {"chat_id": chat_id}, {"$set": {"filters": filtersd}}, upsert=True
         )
         return True
     return False
 
+
 """ PIPES SYSTEM """
 
 
 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,
-        "to_chat_id": to_chat_id,
-        "fetcher": fetcher
-    }
+    pipe = {"from_chat_id": from_chat_id, "to_chat_id": to_chat_id, "fetcher": fetcher}
     pipes.append(pipe)
     return await pipesdb.update_one(
-        {"pipe": "pipe"},
-        {
-            "$set": {
-                "pipes": pipes
-            }
-        },
-        upsert=True
+        {"pipe": "pipe"}, {"$set": {"pipes": pipes}}, upsert=True
     )
 
 
@@ -685,22 +593,16 @@ async def deactivate_pipe(from_chat_id: int, to_chat_id: int):
     if not pipes:
         return
     for pipe in pipes:
-        if pipe['from_chat_id'] == from_chat_id and pipe['to_chat_id'] == to_chat_id:
+        if pipe["from_chat_id"] == from_chat_id and pipe["to_chat_id"] == to_chat_id:
             pipes.remove(pipe)
     return await pipesdb.update_one(
-        {"pipe": "pipe"},
-        {
-            "$set": {
-                "pipes": pipes
-            }
-        },
-        upsert=True
+        {"pipe": "pipe"}, {"$set": {"pipes": pipes}}, upsert=True
     )
 
 
 async def is_pipe_active(from_chat_id: int, to_chat_id: int) -> bool:
     for pipe in await show_pipes():
-        if pipe['from_chat_id'] == from_chat_id and pipe['to_chat_id'] == to_chat_id:
+        if pipe["from_chat_id"] == from_chat_id and pipe["to_chat_id"] == to_chat_id:
             return True
 
 
@@ -708,7 +610,7 @@ async def show_pipes() -> list:
     pipes = await pipesdb.find_one({"pipe": "pipe"})
     if not pipes:
         return []
-    return pipes['pipes']
+    return pipes["pipes"]
 
 
 """ SUDOERS FUNCTIONS """
@@ -718,20 +620,14 @@ async def get_sudoers() -> list:
     sudoers = await sudoersdb.find_one({"sudo": "sudo"})
     if not sudoers:
         return []
-    return sudoers['sudoers']
+    return sudoers["sudoers"]
 
 
 async def add_sudo(user_id: int) -> bool:
     sudoers = await get_sudoers()
     sudoers.append(user_id)
     await sudoersdb.update_one(
-        {"sudo": "sudo"},
-        {
-            "$set": {
-                "sudoers": sudoers
-            }
-        },
-        upsert=True
+        {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True
     )
     return True
 
@@ -740,13 +636,6 @@ async def remove_sudo(user_id: int) -> bool:
     sudoers = await get_sudoers()
     sudoers.remove(user_id)
     await sudoersdb.update_one(
-        {"sudo": "sudo"},
-        {
-            "$set": {
-                "sudoers": sudoers
-            }
-        },
-        upsert=True
+        {"sudo": "sudo"}, {"$set": {"sudoers": sudoers}}, upsert=True
     )
     return True
-

+ 2 - 2
wbb/utils/fetch.py

@@ -24,8 +24,8 @@ SOFTWARE.
 import aiohttp
 
 headers = {
-    'Accept': 'application/json',
-    'Content-Type': 'application/json',
+    "Accept": "application/json",
+    "Content-Type": "application/json",
 }
 
 

+ 20 - 11
wbb/utils/files.py

@@ -21,10 +21,10 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-import os
-from PIL import Image
 import math
+import os
 
+from PIL import Image
 from pyrogram import Client, raw
 from pyrogram.file_id import FileId
 
@@ -37,11 +37,11 @@ async def resize_file_to_sticker_size(file_path: str) -> str:
         size1 = im.width
         size2 = im.height
         if im.width > im.height:
-            scale = STICKER_DIMENSIONS[0]/size1
+            scale = STICKER_DIMENSIONS[0] / size1
             size1new = STICKER_DIMENSIONS[0]
             size2new = size2 * scale
         else:
-            scale = STICKER_DIMENSIONS[1]/size2
+            scale = STICKER_DIMENSIONS[1] / size2
             size1new = size1 * scale
             size2new = STICKER_DIMENSIONS[1]
         size1new = math.floor(size1new)
@@ -58,25 +58,34 @@ async def resize_file_to_sticker_size(file_path: str) -> str:
         im.save(file_path)
 
 
-async def upload_document(client: Client, file_path: str, chat_id: int) -> raw.base.InputDocument:
+async def upload_document(
+    client: Client, file_path: str, chat_id: int
+) -> raw.base.InputDocument:
     media = await client.send(
         raw.functions.messages.UploadMedia(
             peer=await client.resolve_peer(chat_id),
             media=raw.types.InputMediaUploadedDocument(
-                mime_type=client.guess_mime_type(
-                    file_path) or "application/zip",
+                mime_type=client.guess_mime_type(file_path) or "application/zip",
                 file=await client.save_file(file_path),
                 attributes=[
                     raw.types.DocumentAttributeFilename(
                         file_name=os.path.basename(file_path)
                     )
-                ]
-            )
+                ],
+            ),
         )
     )
-    return raw.types.InputDocument(id=media.document.id, access_hash=media.document.access_hash, file_reference=media.document.file_reference)
+    return raw.types.InputDocument(
+        id=media.document.id,
+        access_hash=media.document.access_hash,
+        file_reference=media.document.file_reference,
+    )
 
 
 async def get_document_from_file_id(file_id: str) -> raw.base.InputDocument:
     decoded = FileId.decode(file_id)
-    return raw.types.InputDocument(id=decoded.media_id, access_hash=decoded.access_hash, file_reference=decoded.file_reference)
+    return raw.types.InputDocument(
+        id=decoded.media_id,
+        access_hash=decoded.access_hash,
+        file_reference=decoded.file_reference,
+    )

+ 22 - 25
wbb/utils/functions.py

@@ -21,18 +21,20 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-from PIL import Image, ImageDraw, ImageFont, ImageFilter
+import codecs
+import pickle
+from asyncio import gather
+from math import atan2, cos, radians, sin, sqrt
 from random import randint
-from math import sin, cos, sqrt, atan2, radians
+
+import aiofiles
+import aiohttp
+import speedtest
+from carbonnow import Carbon
+from PIL import Image, ImageDraw, ImageFilter, ImageFont
+
 from wbb.utils import aiodownloader
 from wbb.utils.fetch import fetch
-from carbonnow import Carbon
-import speedtest
-import aiohttp
-import aiofiles
-import pickle
-import codecs
-from asyncio import gather
 
 """
 Just import 'downloader' anywhere and do downloader.download() to
@@ -69,7 +71,7 @@ def generate_captcha():
     correct_answer = ""
     font = ImageFont.truetype("assets/arial.ttf", 55)
     file = f"assets/{randint(1000, 9999)}.jpg"
-    image = Image.new('RGB', (width, height), (255, 255, 255))
+    image = Image.new("RGB", (width, height), (255, 255, 255))
     draw = ImageDraw.Draw(image)
 
     # Draw random points on image
@@ -80,14 +82,9 @@ 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')
+    image.save(file, "jpeg")
     return [file, correct_answer, wrong_answers]
 
 
@@ -100,6 +97,7 @@ async def test_speedtest():
             size /= power
             zero += 1
         return f"{round(size, 2)} {units[zero]}"
+
     speed = speedtest.Speedtest()
     info = speed.get_best_server()
     download = speed.download()
@@ -110,7 +108,7 @@ async def test_speedtest():
 async def file_size_from_url(url: str) -> int:
     async with aiohttp.ClientSession() as session:
         async with session.head(url) as resp:
-            size = int(resp.headers['content-length'])
+            size = int(resp.headers["content-length"])
     return size
 
 
@@ -127,10 +125,10 @@ async def make_carbon(code):
 
 
 async def transfer_sh(file):
-    async with aiofiles.open(file, 'rb') as f:
+    async with aiofiles.open(file, "rb") as f:
         params = {file: await f.read()}
     async with aiohttp.ClientSession() as session:
-        async with session.post('https://transfer.sh/', data=params) as resp:
+        async with session.post("https://transfer.sh/", data=params) as resp:
             download_link = str(await resp.text()).strip()
     return download_link
 
@@ -150,16 +148,15 @@ def str_to_obj(string: str):
 async def calc_distance_from_ip(ip1: str, ip2: str) -> float:
     Radius_Earth = 6371.0088
     data1, data2 = await gather(
-        fetch(f"http://ipinfo.io/{ip1}"),
-        fetch(f"http://ipinfo.io/{ip2}")
+        fetch(f"http://ipinfo.io/{ip1}"), fetch(f"http://ipinfo.io/{ip2}")
     )
-    lat1, lon1 = data1['loc'].split(",")
-    lat2, lon2 = data2['loc'].split(",")
+    lat1, lon1 = data1["loc"].split(",")
+    lat2, lon2 = data2["loc"].split(",")
     lat1, lon1 = radians(float(lat1)), radians(float(lon1))
     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

+ 189 - 212
wbb/utils/inlinefuncs.py

@@ -21,62 +21,82 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
-import aiohttp
-import aiofiles
+import asyncio
 import json
-import sys
 import os
-import asyncio
-from pyrogram.types import (
-    InlineQueryResultArticle,
-    InputTextMessageContent,
-    InlineKeyboardButton,
-    InlineQueryResultPhoto,
-)
-from pyrogram.raw.functions import Ping
-from googletrans import Translator
-from search_engine_parser import GoogleSearch
-from pykeyboard import InlineKeyboard
+import sys
+from random import randint
 from sys import version as pyver
+from time import ctime, time
+
+import aiofiles
+import aiohttp
+from googletrans import Translator
 from motor import version as mongover
-from pyrogram import __version__ as pyrover, filters
-from time import time, ctime
-from random import randint
-from wbb.utils.fetch import fetch
-from wbb.modules.info import get_user_info, get_chat_info
+from pykeyboard import InlineKeyboard
+from pyrogram import __version__ as pyrover
+from pyrogram import filters
+from pyrogram.raw.functions import Ping
+from pyrogram.types import (InlineKeyboardButton, InlineQueryResultArticle,
+                            InlineQueryResultPhoto, InputTextMessageContent)
+from search_engine_parser import GoogleSearch
+
+from wbb import (BOT_USERNAME, MESSAGE_DUMP_CHAT, SUDOERS, USERBOT_ID,
+                 USERBOT_NAME, USERBOT_USERNAME, app, app2, arq)
+from wbb.core.types import InlineQueryResultCachedDocument
+from wbb.modules.info import get_chat_info, get_user_info
 from wbb.modules.music import download_youtube_audio
-from wbb.utils.functions import test_speedtest, get_http_status_code, make_carbon
+from wbb.utils.fetch import fetch
 from wbb.utils.formatter import convert_seconds_to_minutes as time_convert
+from wbb.utils.functions import (get_http_status_code, make_carbon,
+                                 test_speedtest)
 from wbb.utils.pastebin import paste
-from wbb.core.types import InlineQueryResultCachedDocument
-from wbb import (
-    arq, app, app2, USERBOT_USERNAME,
-    BOT_USERNAME, USERBOT_ID,
-    SUDOERS, USERBOT_NAME, MESSAGE_DUMP_CHAT
-)
 
 keywords_list = [
-    "alive", "ping", "tr", "ud", "google", "bitly",
-    "wall", "yt", "torrent", "lyrics", "wiki",
-    "speedtest", "music", "saavn", "deezer",
-    "gh_repo", "gh_user", "search", "paste",
-    "nsfw_scan", "ytmusic", "carbon", "info",
-    "chat_info"
+    "alive",
+    "ping",
+    "tr",
+    "ud",
+    "google",
+    "bitly",
+    "wall",
+    "yt",
+    "torrent",
+    "lyrics",
+    "wiki",
+    "speedtest",
+    "music",
+    "saavn",
+    "deezer",
+    "gh_repo",
+    "gh_user",
+    "search",
+    "paste",
+    "nsfw_scan",
+    "ytmusic",
+    "carbon",
+    "info",
+    "chat_info",
 ]
 
 
 async def inline_help_func(__HELP__):
-    buttons = InlineKeyboard(row_width=3)
-    buttons.add(*[(InlineKeyboardButton(
-        text=i, switch_inline_query_current_chat=i)) for i in keywords_list])
+    buttons = InlineKeyboard(row_width=4)
+    buttons.add(
+        *[
+            (InlineKeyboardButton(text=i, switch_inline_query_current_chat=i))
+            for i in keywords_list
+        ]
+    )
     answerss = [
         InlineQueryResultArticle(
             title="Inline Commands",
             description="Help Related To Inline Usage.",
             input_message_content=InputTextMessageContent(
-                "Click A Button To Get Started."),
+                "Click A Button To Get Started."
+            ),
             thumb_url="https://hamker.me/cy00x5x.png",
-            reply_markup=buttons
+            reply_markup=buttons,
         ),
         InlineQueryResultArticle(
             title="Github Repo",
@@ -84,8 +104,8 @@ async def inline_help_func(__HELP__):
             input_message_content=InputTextMessageContent(
                 "https://github.com/thehamkercat/WilliamButcherBot"
             ),
-            thumb_url="https://hamker.me/gjc9fo3.png"
-        )
+            thumb_url="https://hamker.me/gjc9fo3.png",
+        ),
     ]
     answerss = await alive_function(answerss)
     return answerss
@@ -93,17 +113,11 @@ async def inline_help_func(__HELP__):
 
 async def alive_function(answers):
     buttons = InlineKeyboard(row_width=2)
-    bot_state = 'Dead' if not await app.get_me() else 'Alive'
-    ubot_state = 'Dead' if not await app2.get_me() else 'Alive'
+    bot_state = "Dead" if not await app.get_me() else "Alive"
+    ubot_state = "Dead" if not await app2.get_me() else "Alive"
     buttons.add(
-        InlineKeyboardButton(
-            'Stats',
-            callback_data='stats_callback'
-        ),
-        InlineKeyboardButton(
-            "Go Inline!",
-            switch_inline_query_current_chat=""
-        )
+        InlineKeyboardButton("Stats", callback_data="stats_callback"),
+        InlineKeyboardButton("Go Inline!", switch_inline_query_current_chat=""),
     )
 
     msg = f"""
@@ -118,12 +132,11 @@ async def alive_function(answers):
 """
     answers.append(
         InlineQueryResultArticle(
-            title='Alive',
+            title="Alive",
             description="Check Bot's Stats",
             thumb_url="https://static2.aniimg.com/upload/20170515/414/c/d/7/cd7EEF.jpg",
             input_message_content=InputTextMessageContent(
-                msg,
-                disable_web_page_preview=True
+                msg, disable_web_page_preview=True
             ),
             reply_markup=buttons,
         )
@@ -144,14 +157,13 @@ __**Translated from {i.src} to {lang}**__
     answers.extend(
         [
             InlineQueryResultArticle(
-                title=f'Translated from {i.src} to {lang}.',
+                title=f"Translated from {i.src} to {lang}.",
                 description=i.text,
-                input_message_content=InputTextMessageContent(msg)
+                input_message_content=InputTextMessageContent(msg),
             ),
             InlineQueryResultArticle(
-                title=i.text,
-                input_message_content=InputTextMessageContent(i.text)
-            )
+                title=i.text, input_message_content=InputTextMessageContent(i.text)
+            ),
         ]
     )
     return answers
@@ -176,8 +188,9 @@ async def urban_func(answers, text):
                 InlineQueryResultArticle(
                     title=results[i].word,
                     description=results[i].definition,
-                    input_message_content=InputTextMessageContent(msg)
-                ))
+                    input_message_content=InputTextMessageContent(msg),
+                )
+            )
         except KeyError:
             pass
     return answers
@@ -198,13 +211,13 @@ async def google_search_func(answers, text):
 
             answers.append(
                 InlineQueryResultArticle(
-                    title=i['titles'],
-                    description=i['descriptions'],
+                    title=i["titles"],
+                    description=i["descriptions"],
                     input_message_content=InputTextMessageContent(
-                        msg,
-                        disable_web_page_preview=True
-                    )
-                ))
+                        msg, disable_web_page_preview=True
+                    ),
+                )
+            )
         except KeyError:
             pass
     return answers
@@ -222,8 +235,9 @@ async def wall_func(answers, text):
                 InlineQueryResultPhoto(
                     photo_url=results[i].url_image,
                     thumb_url=results[i].url_thumb,
-                    caption=f"[Source]({results[i].url_image})"
-                ))
+                    caption=f"[Source]({results[i].url_image})",
+                )
+            )
         except KeyError:
             pass
     return answers
@@ -234,12 +248,7 @@ async def saavn_func(answers, text):
     results = await arq.saavn(text)
     for i in results:
         buttons = InlineKeyboard(row_width=1)
-        buttons.add(
-            InlineKeyboardButton(
-                'Download | Play',
-                url=results[i].media_url
-            )
-        )
+        buttons.add(InlineKeyboardButton("Download | Play", url=results[i].media_url))
         buttons_list.append(buttons)
         duration = await time_convert(results[i].duration)
         caption = f"""
@@ -248,20 +257,22 @@ async def saavn_func(answers, text):
 **Duration:** {duration}
 **Release:** {results[i].year}
 **Singers:** {results[i].singers}"""
-        description = f"{results[i].album} | {duration} " \
+        description = (
+            f"{results[i].album} | {duration} "
             + f"| {results[i].singers} ({results[i].year})"
+        )
         try:
             answers.append(
                 InlineQueryResultArticle(
                     title=results[i].song,
                     input_message_content=InputTextMessageContent(
-                        caption,
-                        disable_web_page_preview=True
+                        caption, disable_web_page_preview=True
                     ),
                     description=description,
                     thumb_url=results[i].image,
-                    reply_markup=buttons_list[i]
-                ))
+                    reply_markup=buttons_list[i],
+                )
+            )
         except (KeyError, ValueError):
             pass
     return answers
@@ -272,12 +283,7 @@ async def deezer_func(answers, text):
     results = await arq.deezer(text, 5)
     for i in results:
         buttons = InlineKeyboard(row_width=1)
-        buttons.add(
-            InlineKeyboardButton(
-                'Download | Play',
-                url=results[i].url
-            )
-        )
+        buttons.add(InlineKeyboardButton("Download | Play", url=results[i].url))
         buttons_list.append(buttons)
         duration = await time_convert(results[i].duration)
         caption = f"""
@@ -293,11 +299,11 @@ async def deezer_func(answers, text):
                     thumb_url=results[i].thumbnail,
                     description=description,
                     input_message_content=InputTextMessageContent(
-                        caption,
-                        disable_web_page_preview=True
+                        caption, disable_web_page_preview=True
                     ),
-                    reply_markup=buttons_list[i]
-                ))
+                    reply_markup=buttons_list[i],
+                )
+            )
         except (KeyError, ValueError):
             pass
     return answers
@@ -309,22 +315,23 @@ async def shortify(url):
         return
     header = {
         "Authorization": "Bearer ad39983fa42d0b19e4534f33671629a4940298dc",
-        'Content-Type': 'application/json'
-    }
-    payload = {
-        "long_url": f"{url}"
+        "Content-Type": "application/json",
     }
+    payload = {"long_url": f"{url}"}
     payload = json.dumps(payload)
     async with aiohttp.ClientSession() as session:
-        async with session.post("https://api-ssl.bitly.com/v4/shorten", headers=header, data=payload) as resp:
+        async with session.post(
+            "https://api-ssl.bitly.com/v4/shorten", headers=header, data=payload
+        ) as resp:
             data = await resp.json()
-    msg = data['link']
+    msg = data["link"]
     a = []
     b = InlineQueryResultArticle(
         title="Link Shortened!",
-        description=data['link'],
+        description=data["link"],
         input_message_content=InputTextMessageContent(
-            msg, disable_web_page_preview=True)
+            msg, disable_web_page_preview=True
+        ),
     )
     a.append(b)
     return a
@@ -357,9 +364,8 @@ async def torrent_func(answers, text):
                     title=title,
                     description=description,
                     input_message_content=InputTextMessageContent(
-                        caption,
-                        disable_web_page_preview=True
-                    )
+                        caption, disable_web_page_preview=True
+                    ),
                 )
             )
             limit += 1
@@ -377,12 +383,7 @@ async def youtube_func(answers, text):
         limit += 1
         buttons = InlineKeyboard(row_width=1)
         video_url = f"https://youtube.com{results[i].url_suffix}"
-        buttons.add(
-            InlineKeyboardButton(
-                'Watch',
-                url=video_url
-            )
-        )
+        buttons.add(InlineKeyboardButton("Watch", url=video_url))
         caption = f"""
 **Title:** {results[i].title}
 **Views:** {results[i].views}
@@ -390,8 +391,10 @@ async def youtube_func(answers, text):
 **Duration:** {results[i].duration}
 **Uploaded:** {results[i].publish_time}
 **Description:** {results[i].long_desc}"""
-        description = f"{results[i].views} | {results[i].channel} | " \
+        description = (
+            f"{results[i].views} | {results[i].channel} | "
             + f"{results[i].duration} | {results[i].publish_time}"
+        )
         try:
             answers.append(
                 InlineQueryResultArticle(
@@ -399,11 +402,11 @@ async def youtube_func(answers, text):
                     thumb_url=results[i].thumbnails[0],
                     description=description,
                     input_message_content=InputTextMessageContent(
-                        caption,
-                        disable_web_page_preview=True
+                        caption, disable_web_page_preview=True
                     ),
-                    reply_markup=buttons
-                ))
+                    reply_markup=buttons,
+                )
+            )
         except (KeyError, ValueError):
             pass
     return answers
@@ -425,8 +428,9 @@ async def lyrics_func(answers, text):
         InlineQueryResultArticle(
             title=song_name,
             description=artist,
-            input_message_content=InputTextMessageContent(msg)
-        ))
+            input_message_content=InputTextMessageContent(msg),
+        )
+    )
     return answers
 
 
@@ -434,10 +438,9 @@ async def github_user_func(answers, text):
     URL = f"https://api.github.com/users/{text}"
     result = await fetch(URL)
     buttons = InlineKeyboard(row_width=1)
-    buttons.add(InlineKeyboardButton(
-        text="Open On Github",
-        url=f"https://github.com/{text}"
-    ))
+    buttons.add(
+        InlineKeyboardButton(text="Open On Github", url=f"https://github.com/{text}")
+    )
     caption = f"""
 **Info Of {result['name']}**
 **Username:** `{text}`
@@ -452,10 +455,9 @@ async def github_user_func(answers, text):
 **Following:** `{result['following']}`"""
     answers.append(
         InlineQueryResultPhoto(
-            photo_url=result['avatar_url'],
-            caption=caption,
-            reply_markup=buttons
-        ))
+            photo_url=result["avatar_url"], caption=caption, reply_markup=buttons
+        )
+    )
     return answers
 
 
@@ -471,13 +473,10 @@ async def github_repo_func(answers, text):
     r1 = results[1]
     commits = 0
     for developer in r1:
-        commits += developer['contributions']
+        commits += developer["contributions"]
     buttons = InlineKeyboard(row_width=1)
     buttons.add(
-        InlineKeyboardButton(
-            'Open On Github',
-            url=f"https://github.com/{text}"
-        )
+        InlineKeyboardButton("Open On Github", url=f"https://github.com/{text}")
     )
     caption = f"""
 **Info Of {r['full_name']}**
@@ -499,10 +498,10 @@ async def github_repo_func(answers, text):
             description=text,
             reply_markup=buttons,
             input_message_content=InputTextMessageContent(
-                caption,
-                disable_web_page_preview=True
-            )
-        ))
+                caption, disable_web_page_preview=True
+            ),
+        )
+    )
     return answers
 
 
@@ -513,8 +512,9 @@ async def tg_search_func(answers, text, user_id):
             InlineQueryResultArticle(
                 title="ERROR",
                 description="THIS FEATURE IS ONLY FOR SUDO USERS",
-                input_message_content=InputTextMessageContent(msg)
-            ))
+                input_message_content=InputTextMessageContent(msg),
+            )
+        )
         return answers
     if str(text)[-1] != ":":
         msg = "**ERROR**\n__Put A ':' After The Text To Search__"
@@ -522,8 +522,9 @@ async def tg_search_func(answers, text, user_id):
             InlineQueryResultArticle(
                 title="ERROR",
                 description="Put A ':' After The Text To Search",
-                input_message_content=InputTextMessageContent(msg)
-            ))
+                input_message_content=InputTextMessageContent(msg),
+            )
+        )
 
         return answers
     text = text[0:-1]
@@ -532,14 +533,15 @@ 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",
-                switch_inline_query_current_chat="search"
-            )
+                text="Search again", switch_inline_query_current_chat="search"
+            ),
+        )
+        name = (
+            message.from_user.first_name if message.from_user.first_name else "NO NAME"
         )
-        name = message.from_user.first_name if message.from_user.first_name else "NO NAME"
         caption = f"""
 **Query:** {text}
 **Name:** {str(name)} [`{message.from_user.id}`]
@@ -554,9 +556,8 @@ async def tg_search_func(answers, text, user_id):
             description=message.text if message.text else "[NO_TEXT]",
             reply_markup=buttons,
             input_message_content=InputTextMessageContent(
-                caption,
-                disable_web_page_preview=True
-            )
+                caption, disable_web_page_preview=True
+            ),
         )
         answers.append(result)
     return answers
@@ -566,7 +567,12 @@ async def music_inline_func(answers, query):
     chat_id = -1001445180719
     group_invite = "https://t.me/joinchat/vSDE2DuGK4Y4Nzll"
     try:
-        messages = [m async for m in app2.search_messages(chat_id, query, filter="audio", limit=199)]
+        messages = [
+            m
+            async for m in app2.search_messages(
+                chat_id, query, filter="audio", limit=199
+            )
+        ]
     except Exception as e:
         print(e)
         msg = f"You Need To Join Here With Your Bot And Userbot To Get Cached Music.\n{group_invite}"
@@ -575,29 +581,28 @@ async def music_inline_func(answers, query):
                 title="ERROR",
                 description="Click Here To Know More.",
                 input_message_content=InputTextMessageContent(
-                    msg,
-                    disable_web_page_preview=True
-                )
+                    msg, disable_web_page_preview=True
+                ),
             )
         )
         return answers
     messages_ids_and_duration = []
     for f_ in messages:
         messages_ids_and_duration.append(
-            {"message_id": f_.message_id,
-                "duration": f_.audio.duration if f_.audio.duration else 0}
+            {
+                "message_id": f_.message_id,
+                "duration": f_.audio.duration if f_.audio.duration else 0,
+            }
         )
-    messages = list(
-        {v["duration"]: v for v in messages_ids_and_duration}.values())
+    messages = list({v["duration"]: v for v in messages_ids_and_duration}.values())
     messages_ids = []
     for ff_ in messages:
-        messages_ids.append(ff_['message_id'])
+        messages_ids.append(ff_["message_id"])
     messages = await app.get_messages(chat_id, messages_ids[0:48])
     for message_ in messages:
         answers.append(
             InlineQueryResultCachedDocument(
-                file_id=message_.audio.file_id,
-                title=message_.audio.title
+                file_id=message_.audio.file_id, title=message_.audio.title
             )
         )
     return answers
@@ -613,9 +618,9 @@ async def wiki_func(answers, text):
 __{data['answer']}__"""
     answers.append(
         InlineQueryResultArticle(
-            title=data['title'],
-            description=data['answer'],
-            input_message_content=InputTextMessageContent(msg)
+            title=data["title"],
+            description=data["answer"],
+            input_message_content=InputTextMessageContent(msg),
         )
     )
     return answers
@@ -630,22 +635,23 @@ async def speedtest_init(query):
             InlineQueryResultArticle(
                 title="ERROR",
                 description="THIS FEATURE IS ONLY FOR SUDO USERS",
-                input_message_content=InputTextMessageContent(msg)
-            ))
+                input_message_content=InputTextMessageContent(msg),
+            )
+        )
         return answers
     msg = "**Click The Button Below To Perform A Speedtest**"
     button = InlineKeyboard(row_width=1)
-    button.add(InlineKeyboardButton(
-        text="Test", callback_data="test_speedtest"))
+    button.add(InlineKeyboardButton(text="Test", callback_data="test_speedtest"))
     answers.append(
         InlineQueryResultArticle(
             title="Click Here",
             input_message_content=InputTextMessageContent(msg),
-            reply_markup=button
+            reply_markup=button,
         )
     )
     return answers
 
+
 """ callback query for the function above """
 
 
@@ -655,10 +661,7 @@ async def test_speedtest_cq(_, cq):
         await cq.answer("This Isn't For You!")
         return
     inline_message_id = cq.inline_message_id
-    await app.edit_inline_text(
-        inline_message_id,
-        "**Testing**"
-    )
+    await app.edit_inline_text(inline_message_id, "**Testing**")
     download, upload, info = await test_speedtest()
     msg = f"""
 **Download:** `{download}`
@@ -668,10 +671,7 @@ async def test_speedtest_cq(_, cq):
 **Latitude:** `{info['lat']}`
 **Longitude:** `{info['lon']}`
 """
-    await app.edit_inline_text(
-        inline_message_id,
-        msg
-    )
+    await app.edit_inline_text(inline_message_id, msg)
 
 
 async def pastebin_func(answers, link):
@@ -691,9 +691,7 @@ async def pastebin_func(answers, link):
                 InlineQueryResultArticle(
                     title="DOCUMENT TOO BIG",
                     description="Maximum supported size is 1MB",
-                    input_message_content=InputTextMessageContent(
-                        "DOCUMENT TOO BIG")
-
+                    input_message_content=InputTextMessageContent("DOCUMENT TOO BIG"),
                 )
             )
             return answers
@@ -714,12 +712,7 @@ async def pastebin_func(answers, link):
     await app.send_photo(MESSAGE_DUMP_CHAT, preview)  # To Pre-cache the media
     buttons = InlineKeyboard(row_width=1)
     buttons.add(InlineKeyboardButton(text="Paste Link", url=link))
-    answers.append(
-        InlineQueryResultPhoto(
-            photo_url=preview,
-            reply_markup=buttons
-        )
-    )
+    answers.append(InlineQueryResultPhoto(photo_url=preview, reply_markup=buttons))
     return answers
 
 
@@ -730,27 +723,21 @@ async def pmpermit_func(answers, user_id, victim):
     buttons = InlineKeyboard(row_width=2)
     buttons.add(
         InlineKeyboardButton(
-            text="To Scam You",
-            callback_data="pmpermit to_scam_you a"
+            text="To Scam You", callback_data="pmpermit to_scam_you a"
         ),
         InlineKeyboardButton(
-            text="For promotion",
-            callback_data="pmpermit to_scam_you a"
+            text="For promotion", callback_data="pmpermit to_scam_you a"
         ),
+        InlineKeyboardButton(text="Approve me", callback_data="pmpermit approve_me a"),
         InlineKeyboardButton(
-            text="Approve me",
-            callback_data="pmpermit approve_me a"
+            text="Approve", callback_data=f"pmpermit approve {victim}"
         ),
-        InlineKeyboardButton(
-            text="Approve",
-            callback_data=f"pmpermit approve {victim}"
-        )
     )
     answers.append(
         InlineQueryResultArticle(
             title="do_not_click_here",
             reply_markup=buttons,
-            input_message_content=InputTextMessageContent(caption)
+            input_message_content=InputTextMessageContent(caption),
         )
     )
     return answers
@@ -764,9 +751,7 @@ async def ping_func(answers):
     ping = f"{str(round((t2 - t1), 6)) * 100} ms"
     answers.append(
         InlineQueryResultArticle(
-            title=ping,
-            input_message_content=InputTextMessageContent(
-                f"__**{ping}**__")
+            title=ping, input_message_content=InputTextMessageContent(f"__**{ping}**__")
         )
     )
     return answers
@@ -776,7 +761,7 @@ async def nsfw_scan_func(answers, url: str):
     t1 = time()
     data = (await arq.nsfw_scan(url)).data
     t2 = time()
-    tt = round(t2-t1, 4)
+    tt = round(t2 - t1, 4)
     content = f"""
 **Scanned [Image]({url}) In {tt} Seconds.**
 
@@ -790,7 +775,7 @@ async def nsfw_scan_func(answers, url: str):
         InlineQueryResultArticle(
             title="Scanned",
             description=f"Took {tt} Seconds.",
-            input_message_content=InputTextMessageContent(content)
+            input_message_content=InputTextMessageContent(content),
         )
     )
     return answers
@@ -803,8 +788,9 @@ async def yt_music_func(answers, url, user_id):
             InlineQueryResultArticle(
                 title="ERROR",
                 description="THIS FEATURE IS ONLY FOR SUDO USERS",
-                input_message_content=InputTextMessageContent(msg)
-            ))
+                input_message_content=InputTextMessageContent(msg),
+            )
+        )
         return answers
     if "http" not in url:
         url = (await arq.youtube(url))[0]
@@ -816,15 +802,12 @@ async def yt_music_func(answers, url, user_id):
         title=title,
         duration=duration,
         performer=performer,
-        thumb=thumbnail
+        thumb=thumbnail,
     )
     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
 
@@ -846,9 +829,7 @@ async def carbon_inline_func(answers, link):
                 InlineQueryResultArticle(
                     title="DOCUMENT TOO BIG",
                     description="Maximum supported size is 1MB",
-                    input_message_content=InputTextMessageContent(
-                        "DOCUMENT TOO BIG")
-
+                    input_message_content=InputTextMessageContent("DOCUMENT TOO BIG"),
                 )
             )
             return answers
@@ -865,9 +846,7 @@ async def carbon_inline_func(answers, link):
     buttons.add(InlineKeyboardButton(text="Paste Link", url=link))
     answers.append(
         InlineQueryResultCachedDocument(
-            file_id=carbon.document.file_id,
-            title="Carbon",
-            reply_markup=buttons
+            file_id=carbon.document.file_id, title="Carbon", reply_markup=buttons
         )
     )
     return answers
@@ -879,9 +858,8 @@ async def user_info_inline_func(answers, user):
         InlineQueryResultArticle(
             title="Found User.",
             input_message_content=InputTextMessageContent(
-                caption,
-                disable_web_page_preview=True
-            )
+                caption, disable_web_page_preview=True
+            ),
         )
     )
     return answers
@@ -893,9 +871,8 @@ async def chat_info_inline_func(answers, chat):
         InlineQueryResultArticle(
             title="Found Chat.",
             input_message_content=InputTextMessageContent(
-                caption,
-                disable_web_page_preview=True
-            )
+                caption, disable_web_page_preview=True
+            ),
         )
     )
     return answers

+ 1 - 2
wbb/utils/json_prettify.py

@@ -27,8 +27,7 @@ async def json_object_prettify(objecc):
     dicc = objecc.__dict__
     output = ""
     for key, value in dicc.items():
-        if key == "pinned_message" or key == "photo" \
-                or key == "_" or key == "_client":
+        if key == "pinned_message" or key == "photo" or key == "_" or key == "_client":
             continue
         output += f"**{key}:** `{value}`\n"
     return output

+ 6 - 9
wbb/utils/misc.py

@@ -22,7 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 SOFTWARE.
 """
 from math import ceil
+
 from pyrogram.types import InlineKeyboardButton
+
 from wbb import MOD_LOAD, MOD_NOLOAD
 
 
@@ -43,8 +45,7 @@ def paginate_modules(page_n, module_dict, prefix, chat=None):
             [
                 EqInlineKeyboardButton(
                     x.__MODULE__,
-                    callback_data="{}_module({})".format(
-                        prefix, x.__MODULE__.lower()),
+                    callback_data="{}_module({})".format(prefix, x.__MODULE__.lower()),
                 )
                 for x in module_dict.values()
             ]
@@ -82,19 +83,15 @@ def paginate_modules(page_n, module_dict, prefix, chat=None):
 
     # can only have a certain amount of buttons side by side
     if len(pairs) > 7:
-        pairs = pairs[modulo_page * 7: 7 * (modulo_page + 1)] + [
+        pairs = pairs[modulo_page * 7 : 7 * (modulo_page + 1)] + [
             (
                 EqInlineKeyboardButton(
                     "<",
-                    callback_data="{}_prev({})".format(
-                        prefix, modulo_page
-                    ),
+                    callback_data="{}_prev({})".format(prefix, modulo_page),
                 ),
                 EqInlineKeyboardButton(
                     ">",
-                    callback_data="{}_next({})".format(
-                        prefix, modulo_page
-                    ),
+                    callback_data="{}_next({})".format(prefix, modulo_page),
                 ),
             )
         ]

+ 2 - 2
wbb/utils/pastebin.py

@@ -30,7 +30,7 @@ async def _netcat(host, port, content):
     s.sendall(content.encode())
     s.shutdown(socket.SHUT_WR)
     while True:
-        data = s.recv(4096).decode('utf-8').strip('\n\x00')
+        data = s.recv(4096).decode("utf-8").strip("\n\x00")
         if not data:
             break
         return data
@@ -38,5 +38,5 @@ async def _netcat(host, port, content):
 
 
 async def paste(content):
-    link = await _netcat('ezup.dev', 9999, content)
+    link = await _netcat("ezup.dev", 9999, content)
     return link

+ 24 - 9
wbb/utils/stickerset.py

@@ -23,11 +23,12 @@ SOFTWARE.
 """
 from typing import List
 
-from pyrogram import Client, raw
-from pyrogram import errors
+from pyrogram import Client, errors, raw
 
 
-async def get_sticker_set_by_name(client: Client, name: str) -> raw.base.messages.StickerSet:
+async def get_sticker_set_by_name(
+    client: Client, name: str
+) -> raw.base.messages.StickerSet:
     try:
         return await client.send(
             raw.functions.messages.GetStickerSet(
@@ -37,31 +38,45 @@ async def get_sticker_set_by_name(client: Client, name: str) -> raw.base.message
     except errors.exceptions.not_acceptable_406.StickersetInvalid:
         return None
 
+
 # Known errors: (I don't see a reason to catch them as we, for sure, won't face them right now):
 # errors.exceptions.bad_request_400.PackShortNameInvalid -> pack name needs to end with _by_botname
 # errors.exceptions.bad_request_400.ShortnameOccupyFailed -> pack's name is already in use
 
 
-async def create_sticker_set(client: Client, owner: int, title: str, short_name: str, stickers: List[raw.base.InputStickerSetItem]) -> raw.base.messages.StickerSet:
+async def create_sticker_set(
+    client: Client,
+    owner: int,
+    title: str,
+    short_name: str,
+    stickers: List[raw.base.InputStickerSetItem],
+) -> raw.base.messages.StickerSet:
     return await client.send(
         raw.functions.stickers.CreateStickerSet(
             user_id=await client.resolve_peer(owner),
             title=title,
             short_name=short_name,
-            stickers=stickers
+            stickers=stickers,
         )
     )
 
 
-async def add_sticker_to_set(client: Client, stickerset: raw.base.messages.StickerSet, sticker: raw.base.InputStickerSetItem) -> raw.base.messages.StickerSet:
+async def add_sticker_to_set(
+    client: Client,
+    stickerset: raw.base.messages.StickerSet,
+    sticker: raw.base.InputStickerSetItem,
+) -> raw.base.messages.StickerSet:
     return await client.send(
         raw.functions.stickers.AddStickerToSet(
             stickerset=raw.types.InputStickerSetShortName(
-                short_name=stickerset.set.short_name),
-            sticker=sticker
+                short_name=stickerset.set.short_name
+            ),
+            sticker=sticker,
         )
     )
 
 
-async def create_sticker(sticker: raw.base.InputDocument, emoji: str) -> raw.base.InputStickerSetItem:
+async def create_sticker(
+    sticker: raw.base.InputDocument, emoji: str
+) -> raw.base.InputStickerSetItem:
     return raw.types.InputStickerSetItem(document=sticker, emoji=emoji)