Jelajahi Sumber

refactor: rules + small changes (#236)

SI_NN_ER_LS 2 tahun lalu
induk
melakukan
6f1c56a872
7 mengubah file dengan 259 tambahan dan 88 penghapusan
  1. 27 1
      wbb/__main__.py
  2. 24 0
      wbb/modules/admin.py
  3. 5 42
      wbb/modules/filters.py
  4. 5 44
      wbb/modules/notes.py
  5. 135 0
      wbb/modules/rules.py
  6. 21 0
      wbb/utils/dbfunctions.py
  7. 42 1
      wbb/utils/functions.py

+ 27 - 1
wbb/__main__.py

@@ -40,11 +40,13 @@ from wbb import (
     app,
     log,
 )
+from wbb.core.keyboard import ikb
 from wbb.modules import ALL_MODULES
 from wbb.modules.sudoers import bot_sys_stats
 from wbb.utils import paginate_modules
 from wbb.utils.constants import MARKDOWN
-from wbb.utils.dbfunctions import clean_restart_stage
+from wbb.utils.functions import extract_text_and_keyb
+from wbb.utils.dbfunctions import clean_restart_stage, get_rules
 
 loop = asyncio.get_event_loop()
 
@@ -177,7 +179,31 @@ async def start(_, message):
             "Pm Me For More Details.", reply_markup=keyboard
         )
     if len(message.text.split()) > 1:
+        user = await app.get_users(message.from_user.id)
         name = (message.text.split(None, 1)[1]).lower()
+        match = re.match(r"rules_(.*)", name)  
+        if match:
+            chat_id = match.group(1)
+            user_id = message.from_user.id
+            chat = await app.get_chat(int(chat_id))
+            text = f"**The rules for `{chat.title}` are:\n\n**"
+            rules = await get_rules(int(chat_id))
+            if rules:
+                text = text + rules
+                if "{chat}" in text:
+                    text = text.replace("{chat}", chat.title)
+                if "{name}" in text:
+                    text = text.replace("{name}", user.mention)
+                keyb = None
+                if "~" in text:
+                    text, keyb = extract_text_and_keyb(ikb, text)
+                await app.send_message(user_id, text=text, reply_markup=keyb)
+            else:
+                return await app.send_message(
+                    user_id,
+                    "The group admins haven't set any rules for this chat yet. "
+                    "This probably doesn't mean it's lawless though...!"
+                )
         if name == "mkdwn_help":
             await message.reply(
                 MARKDOWN,

+ 24 - 0
wbb/modules/admin.py

@@ -225,6 +225,9 @@ async def kickFunc(_, message: Message):
     if message.command[0][0] == "d":
         await message.reply_to_message.delete()
     await message.chat.ban_member(user_id)
+    replied_message = message.reply_to_message
+    if replied_message:
+        message = replied_message
     await message.reply_text(msg)
     await asyncio.sleep(1)
     await message.chat.unban_member(user_id)
@@ -279,6 +282,9 @@ async def banFunc(_, message: Message):
         with suppress(AttributeError):
             if len(time_value[:-1]) < 3:
                 await message.chat.ban_member(user_id, until_date=temp_ban)
+                replied_message = message.reply_to_message
+                if replied_message:
+                    message = replied_message
                 await message.reply_text(msg)
             else:
                 await message.reply_text("You can't use more than 99")
@@ -286,6 +292,9 @@ async def banFunc(_, message: Message):
     if reason:
         msg += f"**Reason:** {reason}"
     await message.chat.ban_member(user_id)
+    replied_message = message.reply_to_message
+    if replied_message:
+        message = replied_message
     await message.reply_text(msg)
 
 
@@ -314,6 +323,9 @@ async def unban_func(_, message: Message):
         )
     await message.chat.unban_member(user)
     umention = (await app.get_users(user)).mention
+    replied_message = message.reply_to_message
+    if replied_message:
+        message = replied_message
     await message.reply_text(f"Unbanned! {umention}")
 
 
@@ -589,6 +601,9 @@ async def mute(_, message: Message):
                     permissions=ChatPermissions(),
                     until_date=temp_mute,
                 )
+                replied_message = message.reply_to_message
+                if replied_message:
+                   message = replied_message
                 await message.reply_text(msg, reply_markup=keyboard)
             else:
                 await message.reply_text("You can't use more than 99")
@@ -598,6 +613,9 @@ async def mute(_, message: Message):
     if reason:
         msg += f"**Reason:** {reason}"
     await message.chat.restrict_member(user_id, permissions=ChatPermissions())
+    replied_message = message.reply_to_message
+    if replied_message:
+        message = replied_message
     await message.reply_text(msg, reply_markup=keyboard)
 
 
@@ -612,6 +630,9 @@ async def unmute(_, message: Message):
         return await message.reply_text("I can't find that user.")
     await message.chat.unban_member(user_id)
     umention = (await app.get_users(user_id)).mention
+    replied_message = message.reply_to_message
+    if replied_message:
+        message = replied_message
     await message.reply_text(f"Unmuted! {umention}")
 
 
@@ -685,6 +706,9 @@ async def warn_user(_, message: Message):
 **Warned By:** {message.from_user.mention if message.from_user else 'Anon'}
 **Reason:** {reason or 'No Reason Provided.'}
 **Warns:** {warns + 1}/3"""
+        replied_message = message.reply_to_message
+        if replied_message:
+            message = replied_message
         await message.reply_text(msg, reply_markup=keyboard)
         await add_warn(chat_id, await int_to_alpha(user_id), warn)
 

+ 5 - 42
wbb/modules/filters.py

@@ -45,7 +45,7 @@ from wbb.utils.dbfunctions import (
     save_filter,
 )
 from wbb.utils.filter_groups import chat_filters_group
-from wbb.utils.functions import check_format, extract_text_and_keyb
+from wbb.utils.functions import check_format, extract_text_and_keyb, get_data_and_name
 
 __MODULE__ = "Filters"
 __HELP__ = """/filters To Get All The Filters In The Chat.
@@ -76,49 +76,11 @@ async def save_filters(_, message):
         replied_message = message.reply_to_message
         if not replied_message:
             replied_message = message
-        text = (
-            message.text.markdown if message.text else message.caption.markdown
-        )
-        name = text.split(None, 1)[1].strip()
-        if not name:
+        data, name = await get_data_and_name(replied_message, message)
+        if data == "error":
             return await message.reply_text(
-                "**Usage:**\n__/filter [FILTER_NAME]__"
-            )
-        chat_id = message.chat.id
-        text = name.split(" ", 1)
-        if len(text) > 1:
-            name = text[0]
-            data = text[1].strip()
-            if replied_message and (
-                replied_message.sticker or replied_message.video_note
-            ):
-                data = None
-        else:
-            if replied_message and (
-                replied_message.sticker or replied_message.video_note
-            ):
-                data = None
-            elif (
-                replied_message
-                and not replied_message.text
-                and not replied_message.caption
-            ):
-                data = None
-            else:
-                data = (
-                    replied_message.text.markdown
-                    if replied_message.text
-                    else replied_message.caption.markdown
+                    "**Usage:**\n__/filter [FILTER_NAME] [CONTENT]__\n`-----------OR-----------`\nReply to a message with.\n/filter [FILTER_NAME]."
                 )
-                match = "/filter " + name
-                if not message.reply_to_message and message.text:
-                    if match == data:
-                        return await message.reply_text(
-                            "**Usage:**\n__/filter [FILTER_NAME] [CONTENT]__\n`-----------OR-----------`\nReply to a message with.\n/filter [FILTER_NAME]."
-                        )
-                elif not message.reply_to_message and not message.text:
-                    if match == data:
-                        data = None
         if replied_message.text:
             _type = "text"
             file_id = None
@@ -165,6 +127,7 @@ async def save_filters(_, message):
             "data": data,
             "file_id": file_id,
         }
+        chat_id = message.chat.id
         await save_filter(chat_id, name, _filter)
         return await message.reply_text(f"__**Saved filter {name}.**__")
     except UnboundLocalError:

+ 5 - 44
wbb/modules/notes.py

@@ -43,7 +43,7 @@ from wbb.utils.dbfunctions import (
     get_note_names,
     save_note,
 )
-from wbb.utils.functions import check_format, extract_text_and_keyb
+from wbb.utils.functions import check_format, extract_text_and_keyb, get_data_and_name
 
 __MODULE__ = "Notes"
 __HELP__ = """/notes To Get All The Notes In The Chat.
@@ -92,50 +92,11 @@ async def save_notee(_, message):
             replied_message = message.reply_to_message
             if not replied_message:
                 replied_message = message
-            text = (
-                message.text.markdown
-                if message.text
-                else message.caption.markdown
-            )
-            name = text.split(None, 1)[1].strip()
-            if not name:
-                return await eor(
-                    message, text="**Usage**\n__/save [NOTE_NAME]__"
+            data, name = await get_data_and_name(replied_message, message)
+            if data == "error":
+                return await message.reply_text(
+                    "**Usage:**\n__/save [NOTE_NAME] [CONTENT]__\n`-----------OR-----------`\nReply to a message with.\n/save [NOTE_NAME]"
                 )
-            text = name.split(" ", 1)
-            if len(text) > 1:
-                name = text[0]
-                data = text[1].strip()
-                if replied_message and (
-                    replied_message.sticker or replied_message.video_note
-                ):
-                    data = None
-            else:
-                if replied_message and (
-                    replied_message.sticker or replied_message.video_note
-                ):
-                    data = None
-                elif (
-                    replied_message
-                    and not replied_message.text
-                    and not replied_message.caption
-                ):
-                    data = None
-                else:
-                    data = (
-                        replied_message.text.markdown
-                        if replied_message.text
-                        else replied_message.caption.markdown
-                    )
-                    match = "/save " + name
-                    if not message.reply_to_message and message.text:
-                        if match == data:
-                            return await message.reply_text(
-                                "**Usage:**\n__/save [NOTE_NAME] [CONTENT]__\n`-----------OR-----------`\nReply to a message with.\n/save [NOTE_NAME]"
-                            )
-                    elif not message.reply_to_message and not message.text:
-                        if match == data:
-                            data = None
             if replied_message.text:
                 _type = "text"
                 file_id = None

+ 135 - 0
wbb/modules/rules.py

@@ -0,0 +1,135 @@
+"""
+MIT License
+
+Copyright (c) 2023 SI_NN_ER_LS 
+
+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.
+"""
+
+from pyrogram import filters
+from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
+from wbb import app, BOT_USERNAME
+from wbb.core.keyboard import ikb
+from wbb.core.decorators.permissions import adminsOnly
+from wbb.utils.dbfunctions import set_chat_rules, get_rules, delete_rules
+from wbb.utils.functions import check_format
+from wbb.modules.notes import extract_urls
+from wbb.modules.admin import member_permissions
+
+
+__MODULE__ = "Rules"
+__HELP__ = """
+ • `/rules`: get the rules for this chat.
+
+**Admins only:**
+ • `/setrules`: Reply to a message to set the rules for the chat.
+ • `/clearrules`: clear the rules for this chat.
+"""
+
+
+@app.on_message(filters.command("rules") & ~filters.private)
+async def send_rules(_, message):
+    chat_id = message.chat.id
+    replied_message = message.reply_to_message
+    if replied_message:
+        message = replied_message
+    await message.reply_text(
+        "**Click on the button to see the chat rules!**",
+        reply_markup=InlineKeyboardMarkup(
+            [
+                [
+                    InlineKeyboardButton(
+                        "rules", url=f"t.me/{BOT_USERNAME}?start=rules_{chat_id}"
+                    )
+                ]
+            ]
+        ),
+    )
+
+
+@app.on_message(filters.command("setrules") & ~filters.private)
+@adminsOnly("can_change_info")
+async def set_rules(_, message):
+    try:
+        chat_id = message.chat.id
+        replied_message = message.reply_to_message
+        if len(message.command) < 2 and not replied_message:
+            return await message.reply("**Reply to a message to set new rules.**")
+        if len(message.command) < 2 and replied_message.text:
+            rules = replied_message.text.markdown
+            if replied_message.reply_markup:
+                urls = extract_urls(replied_message.reply_markup)
+                if urls:
+                    response = "\n".join(
+                        [f"{name}=[{text}, {url}]" for name, text, url in urls]
+                    )
+                    rules = rules + response
+        else:
+            text = message.text.markdown
+            rules = text.split(" ", 1)[1]
+        rules = await check_format(ikb, rules)
+        if not rules:
+            return await message.reply_text(
+                "**Wrong formatting, check the help section.**"
+            )
+        await set_chat_rules(chat_id, rules)
+        return await message.reply_text("**Successfully set new rules for this chat.**")
+    except Exception:
+        await message.reply_text("**You can only set text messages as rules.**")
+
+
+@app.on_message(filters.command("clearrules") & ~filters.private)
+@adminsOnly("can_change_info")
+async def delete_rules_cmd(_, message):
+    rules = await get_rules(message.chat.id)
+    if not rules:
+        await message.reply_text("**No rules in this chat.**")
+    else:
+        keyboard = InlineKeyboardMarkup(
+            [
+                [
+                    InlineKeyboardButton("YES, DO IT", callback_data="drules_yes"),
+                    InlineKeyboardButton("Cancel", callback_data="drules_no"),
+                ]
+            ]
+        )
+        await message.reply_text(
+            "**Are you sure to delete the current rules ?.**", reply_markup=keyboard
+        )
+
+
+@app.on_callback_query(filters.regex("drules_(.*)"))
+async def delete_rules_cb(_, cb):
+    chat_id = cb.message.chat.id
+    from_user = cb.from_user
+    permissions = await member_permissions(chat_id, from_user.id)
+    permission = "can_change_info"
+    if permission not in permissions:
+        return await cb.answer(
+            f"You don't have the required permission.\n Permission: {permission}",
+            show_alert=True,
+        )
+    input = cb.data.split("_", 1)[1]
+    if input == "yes":
+        deleted = await delete_rules(chat_id)
+        if deleted:
+            return await cb.message.edit("**Successfully deleted rules of this chat.**")
+    if input == "no":
+        await cb.message.reply_to_message.delete()
+        await cb.message.delete()

+ 21 - 0
wbb/utils/dbfunctions.py

@@ -55,6 +55,7 @@ blacklist_chatdb = db.blacklistChat
 restart_stagedb = db.restart_stage
 flood_toggle_db = db.flood_toggle
 rssdb = db.rss
+rulesdb = db.rules
 chatbotdb = db.chatbot
 
 
@@ -194,6 +195,26 @@ async def deleteall_filters(chat_id: int):
     return await filtersdb.delete_one({"chat_id": chat_id})
 
 
+async def get_rules(chat_id: int):
+    chat = await rulesdb.find_one({"chat_id": chat_id})
+    if not chat:
+        return ""
+    rules = chat.get("rules", "")
+    return rules
+
+
+async def set_chat_rules(chat_id: int, rules: str):
+    await rulesdb.update_one(
+        {"chat_id": chat_id}, 
+        {"$set": {"rules": rules}}, 
+        upsert=True,
+    )
+
+
+async def delete_rules(chat_id: int):
+    return await rulesdb.delete_one({"chat_id": chat_id})
+
+
 async def int_to_alpha(user_id: int) -> str:
     alphabet = list(ascii_lowercase)[:10]
     text = ""

+ 42 - 1
wbb/utils/functions.py

@@ -28,7 +28,7 @@ from io import BytesIO
 from math import atan2, cos, radians, sin, sqrt
 from os import execvp
 from random import randint
-from re import findall
+from re import findall, search
 from re import sub as re_sub
 from sys import executable
 
@@ -333,6 +333,47 @@ async def check_format(ikb, raw_text: str):
         return raw_text
 
 
+async def get_data_and_name(replied_message, message):
+    text = (
+        message.text.markdown if message.text else message.caption.markdown
+    )
+    name = text.split(None, 1)[1].strip()
+    text = name.split(" ", 1)
+    if len(text) > 1:
+        name = text[0]
+        data = text[1].strip()
+        if replied_message and (
+            replied_message.sticker or replied_message.video_note
+        ):
+            data = None
+    else:
+        if replied_message and (
+            replied_message.sticker or replied_message.video_note
+        ):
+            data = None
+        elif (
+            replied_message
+            and not replied_message.text
+            and not replied_message.caption
+        ):
+            data = None
+        else:
+            data = (
+                replied_message.text.markdown
+                if replied_message.text
+                else replied_message.caption.markdown
+            )
+            command = search(r'\[\'(.*?)\'(?:, \'(.*?)\')*\]', str(message.command)).group(1)
+            match = f"/{command} " + name
+            if not message.reply_to_message and message.text:
+                if match == data:
+                    data ="error"
+            elif not message.reply_to_message and not message.text:
+                if match == data:
+                    data = None
+    return data, name
+
+
 async def get_user_id_and_usernames(client) -> dict:
     with client.storage.conn:
         users = client.storage.conn.execute(