import asyncio from functools import cached_property from motor.core import AgnosticCollection from pyrogram import filters from pyrogram.types import Chat, User from app import BOT, DB, Config, Message, bot from app.utils.helpers import get_name FED_LIST: AgnosticCollection = DB.FED_LIST FILTERS: filters.Filter = ( filters.user([609517172, 2059887769]) & ~filters.service ) # NOQA FBAN_REGEX: filters.Filter = filters.regex( r"(New FedBan|starting a federation ban|Starting a federation ban|start a federation ban|FedBan Reason update|FedBan reason updated|Would you like to update this reason)" ) UNFBAN_REGEX: filters.Filter = filters.regex(r"(New un-FedBan|I'll give|Un-FedBan)") class _User(User): def __init__(self, id): super().__init__(id=id) self.first_name = id @cached_property def mention(self) -> str: return f"{self.id}" @bot.add_cmd(cmd="addf") async def add_fed(bot: BOT, message: Message): """ CMD: ADDF INFO: Add a Fed Chat to DB. USAGE: .addf | .addf NAME """ data = dict(name=message.input or message.chat.title, type=str(message.chat.type)) await DB.add_data(collection=FED_LIST, id=message.chat.id, data=data) await message.reply( f"{data['name']} added to FED LIST.", del_in=5, block=False ) await bot.log( text=f"#FBANS\n{data['name']} {message.chat.id} added to FED LIST." ) @bot.add_cmd(cmd="delf") async def remove_fed(bot: BOT, message: Message): """ CMD: DELF INFO: Delete a Fed from DB. FLAGS: -all to delete all feds. USAGE: .delf | .delf id | .delf -all """ if "-all" in message.flags: await FED_LIST.drop() await message.reply("FED LIST cleared.") return chat: int | str | Chat = message.input or message.chat name = "" if isinstance(chat, Chat): name = f"Chat: {chat.title}\n" chat = chat.id elif chat.lstrip("-").isdigit(): chat = int(chat) deleted: bool | None = await DB.delete_data(collection=FED_LIST, id=chat) if deleted: await message.reply( f"{name}{chat} removed from FED LIST.", del_in=8, block=False, ) await bot.log( text=f"#FBANS\n{name}{chat} removed from FED LIST." ) else: await message.reply(f"{name or chat} not in FED LIST.", del_in=8) @bot.add_cmd(cmd=["fban", "fbanp"]) async def fed_ban(bot: BOT, message: Message): progress: Message = await message.reply("❯") user, reason = await message.extract_user_n_reason() if isinstance(user, str): await progress.edit(user) return if not isinstance(user, User): user = _User(id=message.text_list[1]) if user.id in [Config.OWNER_ID, *Config.SUDO_USERS]: await progress.edit("Cannot Fban Owner/Sudo users.") return proof_str: str = "" if message.cmd == "fbanp": if not message.replied: await message.reply("Reply to a proof") return proof = await message.replied.forward(Config.FBAN_LOG_CHANNEL) proof_str = f"\n{ {proof.link} }" await progress.edit("❯❯") total: int = 0 failed: list[str] = [] reason = f"{reason}{proof_str}" fban_cmd: str = f"/fban {user.id} {reason}" async for fed in FED_LIST.find(): chat_id = int(fed["_id"]) total += 1 cmd: Message = await bot.send_message( chat_id=chat_id, text=fban_cmd, disable_web_page_preview=True ) response: Message | None = await cmd.get_response(filters=FILTERS, timeout=8) if not response or not (await FBAN_REGEX(bot, response)): # NOQA failed.append(fed["name"]) elif "Would you like to update this reason" in response.text: await response.click("Update reason") await asyncio.sleep(1) if not total: await progress.edit("You Don't have any feds connected!") return resp_str = f"❯❯❯ FBanned {user.mention}\nID: {user.id}\nReason: {reason}\nInitiated in: {message.chat.title or 'PM'}" if failed: resp_str += f"\nFailed in: {len(failed)}/{total}\n• " + "\n• ".join( failed ) else: resp_str += f"\nStatus: Fbanned in {total} feds." if not message.is_from_owner: resp_str += f"\n\nBy: {get_name(message.from_user)}" await bot.send_message( chat_id=Config.FBAN_LOG_CHANNEL, text=resp_str, disable_web_page_preview=True ) await progress.edit( text=resp_str, del_in=5, block=True, disable_web_page_preview=True ) @bot.add_cmd(cmd="unfban") async def un_fban(bot: BOT, message: Message): progress: Message = await message.reply("❯") user, reason = await message.extract_user_n_reason() if isinstance(user, str): await progress.edit(user) return if not isinstance(user, User): user = _User(id=message.text_list[1]) await progress.edit("❯❯") total: int = 0 failed: list[str] = [] unfban_cmd: str = f"/unfban {user.id} {reason}" async for fed in FED_LIST.find(): chat_id = int(fed["_id"]) total += 1 cmd: Message = await bot.send_message( chat_id=chat_id, text=unfban_cmd, disable_web_page_preview=True ) response: Message | None = await cmd.get_response(filters=FILTERS, timeout=8) if not response or not (await UNFBAN_REGEX(bot, response)): failed.append(fed["name"]) await asyncio.sleep(0.8) if not total: await progress.edit("You Don't have any feds connected!") return resp_str = f"❯❯❯ Un-FBanned {user.mention}\nID: {user.id}\nReason: {reason}\n" if failed: resp_str += f"Failed in: {len(failed)}/{total}\n• " + "\n• ".join(failed) else: resp_str += f"Success! Un-Fbanned in {total} feds." await bot.send_message( chat_id=Config.FBAN_LOG_CHANNEL, text=resp_str, disable_web_page_preview=True ) await progress.edit( text=resp_str, del_in=8, block=False, disable_web_page_preview=True ) @bot.add_cmd(cmd="listf") async def fed_list(bot: BOT, message: Message): """ CMD: LISTF INFO: View Connected Feds. FLAGS: -id to list Fed Chat IDs. USAGE: .listf | .listf -id """ output: str = "" total = 0 async for fed in FED_LIST.find(): output += f'• {fed["name"]}\n' if "-id" in message.flags: output += f' {fed["_id"]}\n' total += 1 if not total: await message.reply("You don't have any Feds Connected.") return output: str = f"List of {total} Connected Feds:\n\n{output}" await message.reply(output, del_in=30, block=True)