TheHamkerCat %!s(int64=5) %!d(string=hai) anos
pai
achega
cb9c8fc33c

+ 1 - 1
wbb/modules/anonymize.py

@@ -34,7 +34,7 @@ from pyrogram.types import Chat, Message
 from wbb import LOG_GROUP_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX
 from wbb import aiohttpsession as session
 from wbb import app, app2
-from wbb.modules.userbot import edit_or_reply as eor
+from wbb.modules.userbot import eor as eor
 from wbb.utils.functions import extract_user
 
 

+ 8 - 14
wbb/modules/chatbot.py

@@ -29,7 +29,7 @@ from pyrogram.types import Message
 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.modules.userbot import eor
 from wbb.utils.filter_groups import chatbot_group
 
 __MODULE__ = "ChatBot"
@@ -50,21 +50,15 @@ async def chat_bot_toggle(db, message: Message):
         if chat_id not in db:
             db.append(chat_id)
             text = "Chatbot Enabled!"
-            return await edit_or_reply(message, text=text)
-        await edit_or_reply(
-            message, text="ChatBot Is Already Enabled."
-        )
+            return await eor(message, text=text)
+        await eor(message, text="ChatBot Is Already Enabled.")
     elif status == "disable":
         if chat_id in db:
             db.remove(chat_id)
-            return await edit_or_reply(
-                message, text="Chatbot Disabled!"
-            )
-        await edit_or_reply(
-            message, text="ChatBot Is Already Disabled."
-        )
+            return await eor(message, text="Chatbot Disabled!")
+        await eor(message, text="ChatBot Is Already Disabled.")
     else:
-        await edit_or_reply(
+        await eor(
             message, text="**Usage:**\n/chatbot [ENABLE|DISABLE]"
         )
 
@@ -76,7 +70,7 @@ async def chat_bot_toggle(db, message: Message):
 @capture_err
 async def chatbot_status(_, message: Message):
     if len(message.command) != 2:
-        return await edit_or_reply(
+        return await eor(
             message, text="**Usage:**\n/chatbot [ENABLE|DISABLE]"
         )
     await chat_bot_toggle(active_chats_bot, message)
@@ -129,7 +123,7 @@ async def chatbot_talk(_, message: Message):
 @capture_err
 async def chatbot_status_ubot(_, message: Message):
     if len(message.text.split()) != 2:
-        return await edit_or_reply(
+        return await eor(
             message, text="**Usage:**\n.chatbot [ENABLE|DISABLE]"
         )
     await chat_bot_toggle(active_chats_ubot, message)

+ 5 - 7
wbb/modules/create.py

@@ -25,7 +25,7 @@ SOFTWARE.
 from pyrogram import filters
 
 from wbb import BOT_USERNAME, SUDOERS, USERBOT_PREFIX, app2
-from wbb.modules.userbot import edit_or_reply
+from wbb.modules.userbot import eor
 
 
 @app2.on_message(
@@ -37,9 +37,7 @@ from wbb.modules.userbot import edit_or_reply
 )
 async def create(_, message):
     if len(message.command) < 3:
-        return await edit_or_reply(
-            message, text="__**.create (b|s|c) Name**__"
-        )
+        return await eor(message, text="__**.create (b|s|c) Name**__")
     group_type = message.command[1]
     split = message.command[2:]
     group_name = " ".join(split)
@@ -49,7 +47,7 @@ async def create(_, message):
     if group_type == "b":  # for basicgroup
         _id = await app2.create_group(group_name, BOT_USERNAME)
         link = await app2.get_chat(_id["id"])
-        await edit_or_reply(
+        await eor(
             message,
             text=f"**Basicgroup Created: [{group_name}]({link['invite_link']})**",
             disable_web_page_preview=True,
@@ -57,7 +55,7 @@ async def create(_, message):
     elif group_type == "s":  # for supergroup
         _id = await app2.create_supergroup(group_name, desc)
         link = await app2.get_chat(_id["id"])
-        await edit_or_reply(
+        await eor(
             message,
             text=f"**Supergroup Created: [{group_name}]({link['invite_link']})**",
             disable_web_page_preview=True,
@@ -65,7 +63,7 @@ async def create(_, message):
     elif group_type == "c":  # for channel
         _id = await app2.create_channel(group_name, desc)
         link = await app2.get_chat(_id["id"])
-        await edit_or_reply(
+        await eor(
             message,
             text=f"**Channel Created: [{group_name}]({link['invite_link']})**",
             disable_web_page_preview=True,

+ 7 - 15
wbb/modules/devs.py

@@ -31,7 +31,7 @@ async def aexec(code, client, message):
     return await locals()["__aexec"](client, message)
 
 
-async def edit_or_reply(msg: Message, **kwargs):
+async def eor(msg: Message, **kwargs):
     func = msg.edit_text if msg.from_user.is_self else msg.reply
     spec = getfullargspec(func.__wrapped__).args
     await func(**{k: v for k, v in kwargs.items() if k in spec})
@@ -108,9 +108,7 @@ async def executor(client, message):
                 ]
             ]
         )
-        await edit_or_reply(
-            message, text=final_output, reply_markup=keyboard
-        )
+        await eor(message, text=final_output, reply_markup=keyboard)
 
 
 @app.on_callback_query(filters.regex(r"runtime"))
@@ -128,9 +126,7 @@ async def runtime_func_cq(_, cq):
 )
 async def shellrunner(client, message):
     if len(message.command) < 2:
-        return await edit_or_reply(
-            message, text="**Usage:**\n/sh git pull"
-        )
+        return await eor(message, text="**Usage:**\n/sh git pull")
     text = message.text.split(None, 1)[1]
     if "\n" in text:
         code = text.split("\n")
@@ -147,9 +143,7 @@ async def shellrunner(client, message):
                 )
             except Exception as err:
                 print(err)
-                await edit_or_reply(
-                    message, text=f"**ERROR:**\n```{err}```"
-                )
+                await eor(message, text=f"**ERROR:**\n```{err}```")
             output += f"**{code}**\n"
             output += process.stdout.read()[:-1].decode("utf-8")
             output += "\n"
@@ -171,7 +165,7 @@ async def shellrunner(client, message):
                 value=exc_obj,
                 tb=exc_tb,
             )
-            return await edit_or_reply(
+            return await eor(
                 message, text=f"**ERROR:**\n```{''.join(errors)}```"
             )
         output = process.stdout.read()[:-1].decode("utf-8")
@@ -188,8 +182,6 @@ async def shellrunner(client, message):
                 caption="`Output`",
             )
             return os.remove("output.txt")
-        await edit_or_reply(
-            message, text=f"**OUTPUT:**\n```{output}```"
-        )
+        await eor(message, text=f"**OUTPUT:**\n```{output}```")
     else:
-        await edit_or_reply(message, text="**OUTPUT: **\n`No output`")
+        await eor(message, text="**OUTPUT: **\n`No output`")

+ 11 - 15
wbb/modules/pmpermit.py

@@ -27,7 +27,7 @@ from pyrogram.raw.functions.messages import DeleteHistory
 
 from wbb import BOT_ID, SUDOERS, USERBOT_ID, USERBOT_PREFIX, app, app2
 from wbb.core.decorators.errors import capture_err
-from wbb.modules.userbot import edit_or_reply
+from wbb.modules.userbot import eor
 from wbb.utils.dbfunctions import (approve_pmpermit,
                                    disapprove_pmpermit,
                                    is_pmpermit_approved)
@@ -81,16 +81,16 @@ async def pmpermit_func(_, message):
 @capture_err
 async def pm_approve(_, message):
     if not message.reply_to_message:
-        return await edit_or_reply(
+        return await eor(
             message, text="Reply to a user's message to approve."
         )
     user_id = message.reply_to_message.from_user.id
     if await is_pmpermit_approved(user_id):
-        return await edit_or_reply(
+        return await eor(
             message, text="User is already approved to pm"
         )
     await approve_pmpermit(user_id)
-    await edit_or_reply(message, text="User is approved to pm")
+    await eor(message, text="User is approved to pm")
 
 
 @app2.on_message(
@@ -100,14 +100,12 @@ async def pm_approve(_, message):
 )
 async def pm_disapprove(_, message):
     if not message.reply_to_message:
-        return await edit_or_reply(
+        return await eor(
             message, text="Reply to a user's message to approve."
         )
     user_id = message.reply_to_message.from_user.id
     if not await is_pmpermit_approved(user_id):
-        await edit_or_reply(
-            message, text="User is already disapproved to pm"
-        )
+        await eor(message, text="User is already disapproved to pm")
         async for m in app2.iter_history(user_id, limit=6):
             if m.reply_markup:
                 try:
@@ -116,7 +114,7 @@ async def pm_disapprove(_, message):
                     pass
         return
     await disapprove_pmpermit(user_id)
-    await edit_or_reply(message, text="User is disapproved to pm")
+    await eor(message, text="User is disapproved to pm")
 
 
 @app2.on_message(
@@ -127,12 +125,12 @@ async def pm_disapprove(_, message):
 @capture_err
 async def block_user_func(_, message):
     if not message.reply_to_message:
-        return await edit_or_reply(
+        return await eor(
             message, text="Reply to a user's message to block."
         )
     user_id = message.reply_to_message.from_user.id
     # Blocking user after editing the message so that other person can get the update.
-    await edit_or_reply(message, text="Successfully blocked the user")
+    await eor(message, text="Successfully blocked the user")
     await app2.block_user(user_id)
 
 
@@ -143,14 +141,12 @@ async def block_user_func(_, message):
 )
 async def unblock_user_func(_, message):
     if not message.reply_to_message:
-        return await edit_or_reply(
+        return await eor(
             message, text="Reply to a user's message to unblock."
         )
     user_id = message.reply_to_message.from_user.id
     await app2.unblock_user(user_id)
-    await edit_or_reply(
-        message, text="Successfully Unblocked the user"
-    )
+    await eor(message, text="Successfully Unblocked the user")
 
 
 """ CALLBACK QUERY HANDLER """

+ 17 - 9
wbb/modules/purge_me.py

@@ -44,11 +44,15 @@ __HELP__ = """
         This will autocorrect your messages on the go.
 
 `.purgeme [Number of messages to purge]`
-        Purge your own messages. 
+        Purge your own messages.
         Ex: .purgeme 10
 
-`.py [Lines of code]`
+`.eval [Lines of code]`
         Execute Python Code.
+`.lsTasks`
+        List running tasks (eval)
+`.cancelTask [ID] or Reply to .eval message`
+        Cancel a running task (eval)
 `.sh [Some shell code]`
         Execute Shell Code.
 
@@ -67,7 +71,7 @@ __HELP__ = """
         Clone profile of a user.
 
 `.useradd`
-        To add a user in sudoers. 
+        To add a user in sudoers.
         [Don't use it if you don't know what you're doing]
 `.userdel`
         To remove a user from sudoers.
@@ -81,28 +85,32 @@ __HELP__ = """
     & filters.user(USERBOT_ID)
 )
 async def purge_me_func(_, message: Message):
+    await message.delete()
+
     if len(message.command) != 2:
-        return await message.delete()
+        return
 
     n = message.text.split(None, 1)[1].strip()
     if not n.isnumeric():
-        return await message.delete()
+        return
 
     n = int(n)
     if n < 1:
-        return await message.delete()
+        return
 
     chat_id = message.chat.id
 
     message_ids = [
         m.message_id
         async for m in app2.search_messages(
-            chat_id, limit=n, from_user=USERBOT_ID
+            chat_id, from_user=USERBOT_ID
         )
-    ]
+    ][
+        :n
+    ]  # NOTE Don't use limit param here
 
     if len(message_ids) == 0:
-        return await message.delete()
+        return
 
     # A list containing lists of 100 message chunks
     # because we can't delete more than 100 messages at once,

+ 1 - 23
wbb/modules/regex.py

@@ -1,26 +1,4 @@
-"""
-MIT License
-
-Copyright (c) 2021 TheHamkerCat
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-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.
-"""
+# https://github.com/PaulSonOfLars/tgbot/blob/master/tg_bot/modules/sed.py
 import re
 import sre_constants
 

+ 1 - 1
wbb/modules/rss.py

@@ -17,7 +17,7 @@ __HELP__ = f"""
 /add_feed [URL] - Add a feed to chat
 /rm_feed - Remove feed from chat
 
-**Note:** 
+**Note:**
     - This will check for updates every {RSS_DELAY//60} minutes.
     - You can only add one feed per chat.
     - Currently RSS and ATOM feeds are supported.

+ 11 - 19
wbb/modules/sudo.py

@@ -26,7 +26,7 @@ from pyrogram.types import Message
 
 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.modules.userbot import eor
 from wbb.utils.dbfunctions import add_sudo, get_sudoers, remove_sudo
 from wbb.utils.functions import restart
 
@@ -53,30 +53,26 @@ can even delete your account.
 @capture_err
 async def useradd(_, message: Message):
     if not message.reply_to_message:
-        return await edit_or_reply(
+        return await eor(
             message,
             text="Reply to someone's message to add him to sudoers.",
         )
     user_id = message.reply_to_message.from_user.id
     sudoers = await get_sudoers()
     if user_id in sudoers:
-        return await edit_or_reply(
-            message, text="User is already in sudoers."
-        )
+        return await eor(message, text="User is already in sudoers.")
     if user_id == BOT_ID:
-        return await edit_or_reply(
+        return await eor(
             message, text="You can't add assistant bot in sudoers."
         )
     added = await add_sudo(user_id)
     if added:
-        await edit_or_reply(
+        await eor(
             message,
             text="Successfully added user in sudoers, Bot will be restarted now.",
         )
         return await restart(None)
-    await edit_or_reply(
-        message, text="Something wrong happened, check logs."
-    )
+    await eor(message, text="Something wrong happened, check logs.")
 
 
 @app2.on_message(
@@ -86,25 +82,21 @@ async def useradd(_, message: Message):
 @capture_err
 async def userdel(_, message: Message):
     if not message.reply_to_message:
-        return await edit_or_reply(
+        return await eor(
             message,
             text="Reply to someone's message to remove him to sudoers.",
         )
     user_id = message.reply_to_message.from_user.id
     if user_id not in await get_sudoers():
-        return await edit_or_reply(
-            message, text="User is not in sudoers."
-        )
+        return await eor(message, text="User is not in sudoers.")
     removed = await remove_sudo(user_id)
     if removed:
-        await edit_or_reply(
+        await eor(
             message,
             text="Successfully removed user from sudoers, Bot will be restarted now.",
         )
         return await restart(None)
-    await edit_or_reply(
-        message, text="Something wrong happened, check logs."
-    )
+    await eor(message, text="Something wrong happened, check logs.")
 
 
 @app2.on_message(
@@ -119,4 +111,4 @@ async def sudoers_list(_, message: Message):
         user = await app2.get_users(user_id)
         user = user.first_name if not user.mention else user.mention
         text += f"{count}. {user}\n"
-    await edit_or_reply(message, text=text)
+    await eor(message, text=text)

+ 80 - 28
wbb/modules/userbot.py

@@ -1,6 +1,6 @@
 """
     CREDITS:
-        EVAL AND SH FUNCTION IN THIS MODULE IS WRITTEN BY @Pokurt.
+        MOST OF THE CODE IN THIS FILE IS WRITTEN BY @Pokurt.
         SOURCE:
             https://github.com/pokurt/Nana-Remix/blob/master/nana/plugins/devs.py
 """
@@ -10,6 +10,7 @@ import re
 import subprocess
 import sys
 import traceback
+from asyncio import get_event_loop
 from html import escape
 from inspect import getfullargspec
 from io import StringIO
@@ -20,15 +21,15 @@ from pyrogram.types import Message, ReplyKeyboardMarkup
 
 from wbb import app  # don't remove
 from wbb import SUDOERS, USERBOT_PREFIX, app2, arq
-from wbb.core.decorators.misc import exec_time
 
 # Eval and Sh module from nana-remix
 
 m = None
 p = print
 r = None
-exec_time = exec_time
 arq = arq
+arrow = lambda x: x.text + "\n`→`"
+tasks = {}
 
 
 async def aexec(code, client, message):
@@ -39,7 +40,7 @@ async def aexec(code, client, message):
     return await locals()["__aexec"](client, message)
 
 
-async def edit_or_reply(msg: Message, **kwargs):
+async def eor(msg: Message, **kwargs):
     func = msg.edit_text if msg.from_user.is_self else msg.reply
     spec = getfullargspec(func.__wrapped__).args
     return await func(
@@ -51,10 +52,59 @@ async def edit_or_reply(msg: Message, **kwargs):
     filters.user(SUDOERS)
     & ~filters.forwarded
     & ~filters.via_bot
-    & filters.command("py", prefixes=USERBOT_PREFIX)
+    & filters.command("cancelTask", prefixes=USERBOT_PREFIX)
+)
+async def task_cancel(_, message: Message):
+    global tasks
+    m = message
+    r = m.reply_to_message
+
+    if len(m.text.split()) == 2:
+        mid = int(m.text.split(None, 1)[1])
+    else:
+        mid = r.message_id if r else None
+
+    if not mid or not tasks:
+        return await m.delete()
+
+    if mid not in tasks:
+        return await m.delete()
+
+    tasks[mid].cancel()
+    del tasks[mid]
+    await eor(message, text=f"{arrow(m)} Task cancelled")
+
+
+@app2.on_message(
+    filters.user(SUDOERS)
+    & ~filters.forwarded
+    & ~filters.via_bot
+    & filters.command("lsTasks", prefixes=USERBOT_PREFIX)
+)
+async def task_list(_, message: Message):
+    global tasks
+    for key, value in tasks.items():
+        if value.done():
+            del tasks[key]
+
+    if not tasks:
+        return await eor(
+            message,
+            text=f"{arrow(message)} No tasks pending",
+        )
+
+    ls = "\n    ".join([str(i) for i in tasks.keys()])
+    await eor(message, text=f"{arrow(message)}  {ls}")
+
+
+@app2.on_message(
+    filters.user(SUDOERS)
+    & ~filters.forwarded
+    & ~filters.via_bot
+    & filters.command("eval", prefixes=USERBOT_PREFIX)
 )
 async def executor(client, message: Message):
-    global m, p, r
+    global m, p, r, tasks
     try:
         cmd = message.text.split(" ", maxsplit=1)[1]
     except IndexError:
@@ -65,22 +115,35 @@ async def executor(client, message: Message):
 
     m = message
     p = print
+    loop = get_event_loop()
+
+    for key, value in tasks.items():
+        if value.done():
+            del tasks[key]
 
     # To prevent keyboard input attacks
     if m.reply_to_message:
         r = m.reply_to_message
         if r.reply_markup:
             if isinstance(r.reply_markup, ReplyKeyboardMarkup):
-                return await m.edit("INSECURE!")
+                return await eor(m, text="INSECURE!")
     old_stderr = sys.stderr
     old_stdout = sys.stdout
     redirected_output = sys.stdout = StringIO()
     redirected_error = sys.stderr = StringIO()
     stdout, stderr, exc = None, None, None
     try:
-        await aexec(cmd, client, message)
+        task = loop.create_task(aexec(cmd, client, message))
+
+        # Save it in tasks, so we can cancel it with .cancelTask
+        tasks[m.message_id] = task
+        await task
     except Exception as e:
         exc = str(e)
+
+    if m.message_id in tasks:
+        del tasks[m.message_id]
+
     stdout = redirected_output.getvalue()
     stderr = redirected_error.getvalue()
     sys.stdout = old_stdout
@@ -92,6 +155,9 @@ async def executor(client, message: Message):
         evaluation = stderr
     elif stdout:
         evaluation = stdout
+        # Save the last stdout in globals,
+        # Can use the it in next calls
+        globals()["lstdout"] = stdout
     else:
         evaluation = "Success"
     final_output = f"**→**\n`{escape(evaluation.strip())}`"
@@ -101,7 +167,7 @@ async def executor(client, message: Message):
             out_file.write(str(evaluation.strip()))
         await message.reply_document(
             document=filename,
-            caption=f"`→`\n  **Attached Document**",
+            caption="`→`\n  **Attached Document**",
             quote=False,
         )
         os.remove(filename)
@@ -143,9 +209,7 @@ async def executor(client, message: Message):
 )
 async def shellrunner(client, message: Message):
     if len(message.command) < 2:
-        return await edit_or_reply(
-            message, text="**Usage:**\n/sh git pull"
-        )
+        return await eor(message, text="**Usage:**\n/sh git pull")
 
     if message.reply_to_message:
         r = message.reply_to_message
@@ -169,7 +233,7 @@ async def shellrunner(client, message: Message):
                 )
             except Exception as err:
                 print(err)
-                await edit_or_reply(
+                await eor(
                     message,
                     text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{escape(err)}```",
                 )
@@ -194,7 +258,7 @@ async def shellrunner(client, message: Message):
                 value=exc_obj,
                 tb=exc_tb,
             )
-            return await edit_or_reply(
+            return await eor(
                 message,
                 text=f"**INPUT:**\n```{escape(text)}```\n\n**ERROR:**\n```{''.join(errors)}```",
             )
@@ -212,24 +276,12 @@ async def shellrunner(client, message: Message):
                 caption=escape(text),
             )
             return os.remove("output.txt")
-        await edit_or_reply(
+        await eor(
             message,
             text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT:**\n```{escape(output)}```",
         )
     else:
-        await edit_or_reply(
+        await eor(
             message,
             text=f"**INPUT:**\n```{escape(text)}```\n\n**OUTPUT: **\n`No output`",
         )
-
-
-def shell(cmd: list) -> tuple:
-    proc = subprocess.run(
-        cmd,
-        stdout=subprocess.PIPE,
-        stderr=subprocess.PIPE,
-    )
-    stdout, stderr = proc.stdout, proc.stderr
-    stdout = stdout.decode() if stdout else None
-    stderr = stderr.decode() if stderr else None
-    return stdout, stderr

+ 1 - 1
wbb/utils/dbfunctions.py

@@ -29,7 +29,7 @@ from wbb import db
 
 """
 SOME THINGS ARE FUCKED UP HERE, LIKE TOGGLEABLES HAVE THEIR OWN COLLECTION
-(SHOULD FIX IT WITH SOMETHING LIKE TOGGLEDB, BUT I WON'T, AS IT WILL TAKE 
+(SHOULD FIX IT WITH SOMETHING LIKE TOGGLEDB, BUT I WON'T, AS IT WILL TAKE
 TOO MUCH TIME AND WILL BE BAD FOR ALREADY STORED DATA)
 """
 

+ 1 - 1
wbb/utils/inlinefuncs.py

@@ -846,7 +846,7 @@ async def execute_code(query):
             )
 
             msg = f"""
-**{lang.capitalize()}:** 
+**{lang.capitalize()}:**
 ```{code}```
 
 **{out}:**