Przeglądaj źródła

Weekend Fixes (#116)

* Added .reverse in userbot

* Added .notes in userbot

* Removed /eval and /sh from bot

* Added support for /help [Module name]

* Added /dice in bot and userbot
Akshay Rajput 5 lat temu
rodzic
commit
6951ed7453

+ 17 - 3
wbb/__main__.py

@@ -43,6 +43,7 @@ HELPABLE = {}
 
 
 async def start_bot():
+    global HELPABLE
 
     for module in ALL_MODULES:
         imported_module = importlib.import_module("wbb.modules." + module)
@@ -161,9 +162,22 @@ async def help_command(_, message):
             "Pm Me For More Details.", reply_markup=keyboard
         )
     if len(message.text.split()) > 1:
-        start_what = (message.text.split(None, 1)[1]).lower()
-        if start_what == "mkdwn_help":
-            return await message.reply(MARKDOWN, parse_mode="html")
+        name = (message.text.split(None, 1)[1]).lower()
+        if name == "mkdwn_help":
+            return await message.reply(
+                MARKDOWN,
+                parse_mode="html",
+                disable_web_page_preview=True,
+            )
+        if name in HELPABLE:
+            text = (
+                f"Here is the help for **{HELPABLE[name].__MODULE__}**:\n"
+                + HELPABLE[name].__HELP__
+            )
+            return await message.reply(
+                text,
+                disable_web_page_preview=True,
+            )
     return await message.reply(
         home_text_pm,
         reply_markup=home_keyboard_pm,

+ 0 - 1
wbb/modules/admin.py

@@ -41,7 +41,6 @@ __HELP__ = """/ban - Ban A User
 /unban - Unban A User
 /warn - Warn A User
 /dwarn - Delete the replied message warning its sender
-/rmwarn - Remove 1 Warning Of A User
 /rmwarns - Remove All Warning of A User
 /warns - Show Warning Of A User
 /kick - Kick A User

+ 0 - 177
wbb/modules/devs.py

@@ -1,177 +0,0 @@
-"""
-    CREDITS:
-        THIS MODULE IS COMPLETELY WRITTEN BY @Pokurt.
-        SOURCE:
-            https://github.com/pokurt/Nana-Remix/blob/master/nana/plugins/devs.py
-"""
-
-import os
-import re
-import subprocess
-import sys
-import traceback
-from io import StringIO
-from time import time
-
-from pyrogram import filters
-from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
-
-from wbb import SUDOERS, app, eor
-
-# Module help for this is in sudoers.py
-
-
-async def aexec(code, client, message):
-    exec(
-        "async def __aexec(client, message): "
-        + "".join(f"\n {a}" for a in code.split("\n"))
-    )
-    return await locals()["__aexec"](client, message)
-
-
-@app.on_message(
-    filters.user(SUDOERS)
-    & ~filters.forwarded
-    & ~filters.via_bot
-    & ~filters.edited
-    & filters.command("eval")
-)
-async def executor(client, message: Message):
-    try:
-        cmd = message.text.split(" ", maxsplit=1)[1]
-    except IndexError:
-        return await message.delete()
-    t1 = time()
-    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)
-    except Exception:
-        exc = traceback.format_exc()
-    stdout = redirected_output.getvalue()
-    stderr = redirected_error.getvalue()
-    sys.stdout = old_stdout
-    sys.stderr = old_stderr
-    evaluation = ""
-    if exc:
-        evaluation = exc
-    elif stderr:
-        evaluation = stderr
-    elif stdout:
-        evaluation = stdout
-    else:
-        evaluation = "Success"
-    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",
-                    )
-                ]
-            ]
-        )
-        await message.reply_document(
-            document=filename,
-            caption=f"**INPUT:**\n`{cmd[0:980]}`\n\n**OUTPUT:**\n`Attached Document`",
-            quote=False,
-            reply_markup=keyboard,
-        )
-        await message.delete()
-        os.remove(filename)
-    else:
-        t2 = time()
-        keyboard = InlineKeyboardMarkup(
-            [
-                [
-                    InlineKeyboardButton(
-                        text="⏳",
-                        callback_data=f"runtime {round(t2-t1, 3)} Seconds",
-                    )
-                ]
-            ]
-        )
-        await eor(message, text=final_output, reply_markup=keyboard)
-
-
-@app.on_callback_query(filters.regex(r"runtime"))
-async def runtime_func_cq(_, cq):
-    runtime = cq.data.split(None, 1)[1]
-    await cq.answer(runtime, show_alert=True)
-
-
-@app.on_message(
-    filters.user(SUDOERS)
-    & ~filters.forwarded
-    & ~filters.via_bot
-    & ~filters.edited
-    & filters.command("sh"),
-)
-async def shellrunner(_, message: Message):
-    if len(message.command) < 2:
-        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")
-        output = ""
-        for x in code:
-            shell = re.split(""" (?=(?:[^'"]|'[^']*'|"[^"]*")*$)""", x)
-            try:
-                process = subprocess.Popen(
-                    shell,
-                    stdout=subprocess.PIPE,
-                    stderr=subprocess.PIPE,
-                )
-            except Exception as err:
-                print(err)
-                await eor(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 enumerate(shell):
-            shell[a] = shell[a].replace('"', "")
-        try:
-            process = subprocess.Popen(
-                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,
-            )
-            return await eor(
-                message, text=f"**ERROR:**\n```{''.join(errors)}```"
-            )
-        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:
-                file.write(output)
-            await app.send_document(
-                message.chat.id,
-                "output.txt",
-                reply_to_message_id=message.message_id,
-                caption="`Output`",
-            )
-            return os.remove("output.txt")
-        await eor(message, text=f"**OUTPUT:**\n```{output}```")
-    else:
-        await eor(message, text="**OUTPUT: **\n`No output`")

+ 28 - 0
wbb/modules/dice.py

@@ -0,0 +1,28 @@
+from pyrogram import filters
+from pyrogram.types import Message
+
+from wbb import app, app2, SUDOERS, USERBOT_PREFIX
+
+__MODULE__ = "Dice"
+__HELP__ = """
+/dice
+    Roll a dice.
+"""
+
+@app2.on_message(
+        filters.command("dice", prefixes=USERBOT_PREFIX)
+        & filters.user(SUDOERS)
+    )
+@app.on_message(filters.command("dice"))
+async def throw_dice(client, message: Message):
+    six = (message.from_user.id in SUDOERS) if message.from_user else False
+
+    c = message.chat.id
+    if not six:
+        return await client.send_dice(c, "🎲")
+
+    m = await client.send_dice(c, "🎲")
+
+    while m.dice.value != 6:
+        await m.delete()
+        m = await client.send_dice(c, "🎲")

+ 34 - 13
wbb/modules/global_stats.py

@@ -26,7 +26,7 @@ import asyncio
 from pyrogram import filters
 from pyrogram.errors import FloodWait
 
-from wbb import BOT_ID, BOT_NAME, SUDOERS, app
+from wbb import BOT_ID, BOT_NAME, SUDOERS, USERBOT_NAME, app, app2
 from wbb.core.decorators.errors import capture_err
 from wbb.modules import ALL_MODULES
 from wbb.utils.dbfunctions import (get_blacklist_filters_count,
@@ -59,7 +59,6 @@ async def clean_db(_, message):
             served_chats.remove(served_chat)
             pass
     await m.edit("**Database Cleaned.**")
-    # TODO Add shit to clean filters, notes and other things of left chats.
 
 
 @app.on_message(
@@ -116,18 +115,40 @@ async def global_stats(_, message):
     # Modules info
     modules_count = len(ALL_MODULES)
 
+    # Userbot info
+    groups_ub = channels_ub = bots_ub = privates_ub = total_ub = 0
+    async for i in app2.iter_dialogs():
+        t = i.chat.type
+        total_ub += 1
+
+        if t in ["supergroup", "group"]:
+            groups_ub += 1
+        elif t == "channel":
+            channels_ub += 1
+        elif t == "bot":
+            bots_ub += 1
+        elif t == "private":
+            privates_ub += 1
+
     msg = f"""
 **Global Stats of {BOT_NAME}**:
-**{modules_count}** Modules Loaded
-**{len(keywords_list)}** Inline Modules Loaded.
-**{rss_count}** Active RSS Feeds.
-**{gbans}** Globally banned users.
-**{filters_count}** Filters, Across **{filters_chats_count}** chats.
-**{blacklist_filters_count}** Blacklist Filters, Across **{blacklist_filters_chats_count}** chats.
-**{notes_count}** Notes, Across **{notes_chats_count}** chats.
-**{warns_count}** Warns, Across **{warns_chats_count}** chats.
-**{karmas_count}** Karma, Across **{karmas_chats_count}** chats.
-**{served_users}** Users, Across **{served_chats}** chats.
-**{developers}** Developers And **{commits}** Commits On **[Github]({rurl})**.
+    **{modules_count}** Modules Loaded.
+    **{len(keywords_list)}** Inline Modules Loaded.
+    **{rss_count}** Active RSS Feeds.
+    **{gbans}** Globally banned users.
+    **{filters_count}** Filters, Across **{filters_chats_count}** chats.
+    **{blacklist_filters_count}** Blacklist Filters, Across **{blacklist_filters_chats_count}** chats.
+    **{notes_count}** Notes, Across **{notes_chats_count}** chats.
+    **{warns_count}** Warns, Across **{warns_chats_count}** chats.
+    **{karmas_count}** Karma, Across **{karmas_chats_count}** chats.
+    **{served_users}** Users, Across **{served_chats}** chats.
+    **{developers}** Developers And **{commits}** Commits On **[Github]({rurl})**.
+
+**Global Stats of {USERBOT_NAME}**:
+    **{total_ub} Dialogs.**
+    **{groups_ub} Groups Joined.**
+    **{channels_ub} Channels Joined.**
+    **{bots_ub} Bots.**
+    **{privates_ub} Users.**
 """
     await m.edit(msg, disable_web_page_preview=True)

+ 65 - 17
wbb/modules/notes.py

@@ -25,7 +25,7 @@ from re import findall
 
 from pyrogram import filters
 
-from wbb import app
+from wbb import SUDOERS, USERBOT_ID, USERBOT_PREFIX, app, app2, eor
 from wbb.core.decorators.errors import capture_err
 from wbb.core.decorators.permissions import adminsOnly
 from wbb.core.keyboard import ikb
@@ -35,33 +35,41 @@ from wbb.utils.functions import extract_text_and_keyb
 
 __MODULE__ = "Notes"
 __HELP__ = """/notes To Get All The Notes In The Chat.
+
 /save [NOTE_NAME] To Save A Note (Can be a sticker or text).
+
 #NOTE_NAME To Get A Note.
+
 /delete [NOTE_NAME] To Delete A Note.
 
 Checkout /markdownhelp to know more about formattings and other syntax.
 """
 
 
+@app2.on_message(
+    filters.command("save", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
 @app.on_message(filters.command("save") & ~filters.edited & ~filters.private)
 @adminsOnly("can_change_info")
 async def save_notee(_, message):
     if len(message.command) < 2 or not message.reply_to_message:
-        await message.reply_text(
-            "**Usage:**\nReply to a text or sticker with /save [NOTE_NAME] to save it."
+        await eor(
+            message,
+            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.**__"
+        await eor(
+            message,
+            text="__**You can only save text or stickers in notes.**__",
         )
     else:
         name = message.text.split(None, 1)[1].strip()
         if not name:
-            return await message.reply_text("**Usage**\n__/save [NOTE_NAME]__")
+            return await eor(message, text="**Usage**\n__/save [NOTE_NAME]__")
         _type = "text" if message.reply_to_message.text else "sticker"
         note = {
             "type": _type,
@@ -69,22 +77,55 @@ async def save_notee(_, message):
             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}.**__")
+        prefix = message.text.split()[0][0]
+        chat_id = message.chat.id if prefix != USERBOT_PREFIX else USERBOT_ID
+        await save_note(chat_id, name, note)
+        await eor(message, text=f"__**Saved note {name}.**__")
 
 
+@app2.on_message(
+    filters.command("notes", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
 @app.on_message(filters.command("notes") & ~filters.edited & ~filters.private)
 @capture_err
 async def get_notes(_, message):
-    _notes = await get_note_names(message.chat.id)
+    prefix = message.text.split()[0][0]
+    is_ubot = bool(prefix == USERBOT_PREFIX)
+    chat_id = USERBOT_ID if is_ubot else message.chat.id
+
+    _notes = await get_note_names(chat_id)
 
     if not _notes:
-        return await message.reply_text("**No notes in this chat.**")
+        return await eor(message, text="**No notes in this chat.**")
     _notes.sort()
-    msg = f"List of notes in {message.chat.title}\n"
+    msg = f"List of notes in {'USERBOT' if is_ubot else message.chat.title}\n"
     for note in _notes:
         msg += f"**-** `{note}`\n"
-    await message.reply_text(msg)
+    await eor(message, text=msg)
+
+
+@app2.on_message(
+    filters.command("get", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
+async def get_one_note_userbot(_, message):
+    if len(message.text.split()) < 2:
+        return await eor(message, text="Invalid arguments")
+
+    name = message.text.split(None, 1)[1]
+
+    _note = await get_note(USERBOT_ID, name)
+    if not _note:
+        return await eor(message, text="No such note.")
+
+    if _note["type"] == "text":
+        data = _note["data"]
+        await eor(
+            message,
+            text=data,
+            disable_web_page_preview=True,
+        )
+    else:
+        await message.reply_sticker(_note["data"])
 
 
 @app.on_message(
@@ -114,17 +155,24 @@ async def get_one_note(_, message):
         await message.reply_sticker(_note["data"])
 
 
+@app2.on_message(
+    filters.command("delete", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
 @app.on_message(filters.command("delete") & ~filters.edited & ~filters.private)
 @adminsOnly("can_change_info")
 async def del_note(_, message):
     if len(message.command) < 2:
-        return await message.reply_text("**Usage**\n__/delete [NOTE_NAME]__")
+        return await eor(message, text="**Usage**\n__/delete [NOTE_NAME]__")
     name = message.text.split(None, 1)[1].strip()
     if not name:
-        return await message.reply_text("**Usage**\n__/delete [NOTE_NAME]__")
-    chat_id = message.chat.id
+        return await eor(message, text="**Usage**\n__/delete [NOTE_NAME]__")
+
+    prefix = message.text.split()[0][0]
+    is_ubot = bool(prefix == USERBOT_PREFIX)
+    chat_id = USERBOT_ID if is_ubot else message.chat.id
+
     deleted = await delete_note(chat_id, name)
     if deleted:
-        await message.reply_text(f"**Deleted note {name} successfully.**")
+        await eor(message, text=f"**Deleted note {name} successfully.**")
     else:
-        await message.reply_text("**No such note.**")
+        await eor(message, text="**No such note.**")

+ 4 - 2
wbb/modules/purge_me.py

@@ -73,9 +73,11 @@ TEXT = """
 
 <code>paste</code> → Paste shit on batbin.<br>
 
-<code>help</code> → Get link to this page.
+<code>help</code> → Get link to this page.<br>
 
-<code>kang</code> → Kang stickers.
+<code>kang</code> → Kang stickers.<br>
+
+<code>dice</code> → Roll a dice.<br>
 """
 print("[INFO]: Pasting userbot commands on telegraph")
 

+ 13 - 9
wbb/modules/reverse.py

@@ -33,7 +33,7 @@ from bs4 import BeautifulSoup
 from pyrogram import filters
 from pyrogram.types import InputMediaPhoto, Message
 
-from wbb import MESSAGE_DUMP_CHAT, app
+from wbb import MESSAGE_DUMP_CHAT, SUDOERS, USERBOT_PREFIX, app, app2, eor
 from wbb.core.decorators.errors import capture_err
 from wbb.utils.functions import get_file_id_from_message
 from wbb.utils.http import get
@@ -44,12 +44,15 @@ async def get_soup(url: str, headers):
     return BeautifulSoup(html, "html.parser")
 
 
+@app2.on_message(
+    filters.command("reverse", prefixes=USERBOT_PREFIX) & filters.user(SUDOERS)
+)
 @app.on_message(filters.command("reverse"))
 @capture_err
-async def reverse_image_search(_, message: Message):
+async def reverse_image_search(client, message: Message):
     if not message.reply_to_message:
-        return await message.reply_text(
-            "Reply to a message to reverse search it."
+        return await eor(
+            message, text="Reply to a message to reverse search it."
         )
     reply = message.reply_to_message
     if (
@@ -59,14 +62,15 @@ async def reverse_image_search(_, message: Message):
         and not reply.animation
         and not reply.video
     ):
-        return await message.reply_text(
-            "Reply to an image/document/sticker/animation to reverse search it."
+        return await eor(
+            message,
+            text="Reply to an image/document/sticker/animation to reverse search it.",
         )
-    m = await message.reply_text("Searching...")
+    m = await eor(message, text="Searching...")
     file_id = get_file_id_from_message(reply)
     if not file_id:
         return await m.edit("Can't reverse that")
-    image = await app.download_media(file_id, f"{randint(1000, 10000)}.jpg")
+    image = await client.download_media(file_id, f"{randint(1000, 10000)}.jpg")
     async with aiofiles.open(image, "rb") as f:
         if image:
             search_url = "http://www.google.com/searchbyimage/upload"
@@ -127,7 +131,7 @@ async def reverse_image_search(_, message: Message):
                 media.append(img)
 
         # Cache images, so we can use file_ids
-        tasks = [app.send_photo(MESSAGE_DUMP_CHAT, img) for img in media]
+        tasks = [client.send_photo(MESSAGE_DUMP_CHAT, img) for img in media]
         messages = await gather(*tasks)
 
         await message.reply_media_group(

+ 1 - 1
wbb/utils/dbfunctions.py

@@ -69,7 +69,7 @@ def str_to_obj(string: str):
 
 
 async def get_notes_count() -> dict:
-    chats = notesdb.find({"chat_id": {"$lt": 0}})
+    chats = notesdb.find({"chat_id": {"$exists": 1}})
     if not chats:
         return {}
     chats_count = 0