from os import remove from html import escape from asyncio import sleep from pyrogram import filters from Powers.vars import Config from traceback import format_exc from Powers.bot_class import Gojo from pyrogram.types import Message from Powers.utils.parser import mention_html from Powers.database.approve_db import Approve from Powers.database.reporting_db import Reporting from Powers.utils.extract_user import extract_user from pyrogram.enums import ChatType, ChatMemberStatus as CMS from Powers import LOGGER, OWNER_ID, DEV_USERS, SUPPORT_GROUP, SUPPORT_STAFF from Powers.utils.caching import ( ADMIN_CACHE, TEMP_ADMIN_CACHE_BLOCK, admin_cache_reload) from Powers.utils.custom_filters import ( DEV_LEVEL, command, admin_filter, owner_filter, promote_filter) from pyrogram.errors import ( RPCError, FloodWait, RightForbidden, UserAdminInvalid, ChatAdminRequired, ChatAdminInviteRequired) @Gojo.on_message(command("adminlist")) async def adminlist_show(_, m: Message): global ADMIN_CACHE if m.chat.type != ChatType.SUPERGROUP: return await m.reply_text( text="This command is made to be used in groups only!", ) try: try: admin_list = ADMIN_CACHE[m.chat.id] note = "Note: These are cached values!" except KeyError: admin_list = await admin_cache_reload(m, "adminlist") note = "Note: These are up-to-date values!" adminstr = f"Admins in {m.chat.title}:" + "\n\n" bot_admins = [i for i in admin_list if (i[1].lower()).endswith("bot")] user_admins = [i for i in admin_list if not (i[1].lower()).endswith("bot")] # format is like: (user_id, username/name,anonyamous or not) mention_users = [ ( admin[1] if admin[1].startswith("@") else (await mention_html(admin[1], admin[0])) ) for admin in user_admins if not admin[2] # if non-anonyamous admin ] mention_users.sort(key=lambda x: x[1]) mention_bots = [ ( admin[1] if admin[1].startswith("@") else (await mention_html(admin[1], admin[0])) ) for admin in bot_admins ] mention_bots.sort(key=lambda x: x[1]) adminstr += "User Admins:\n" adminstr += "\n".join(f"- {i}" for i in mention_users) adminstr += "\n\nBots:\n" adminstr += "\n".join(f"- {i}" for i in mention_bots) await m.reply_text(adminstr + "\n\n" + note) LOGGER.info(f"Adminlist cmd use in {m.chat.id} by {m.from_user.id}") except Exception as ef: if str(ef) == str(m.chat.id): await m.reply_text(text="Use /admincache to reload admins!") else: ef = str(ef) + f"{admin_list}\n" await m.reply_text( text=f"Some error occured, report to @{SUPPORT_GROUP} \n Error: {ef}" ) LOGGER.error(ef) LOGGER.error(format_exc()) return @Gojo.on_message(command("zombies") & owner_filter) async def zombie_clean(c: Gojo, m: Message): zombie = 0 wait = await m.reply_text("Searching ... and banning ...") async for member in c.get_chat_members(m.chat.id): if member.user.is_deleted: zombie += 1 try: await c.kick_chat_member(m.chat.id, member.user.id) except UserAdminInvalid: zombie -= 1 except FloodWait as e: await sleep(e.x) if zombie == 0: return await wait.edit_text("Group is clean!") return await wait.edit_text( text=f"{zombie} Zombies found and has been banned!", ) @Gojo.on_message(command("admincache")) async def reload_admins(_, m: Message): global TEMP_ADMIN_CACHE_BLOCK if m.chat.type != ChatType.SUPERGROUP: return await m.reply_text( "This command is made to be used in groups only!", ) if ( (m.chat.id in set(TEMP_ADMIN_CACHE_BLOCK.keys())) and (m.from_user.id not in SUPPORT_STAFF) and TEMP_ADMIN_CACHE_BLOCK[m.chat.id] == "manualblock" ): await m.reply_text("Can only reload admin cache once per 10 mins!") return try: await admin_cache_reload(m, "admincache") TEMP_ADMIN_CACHE_BLOCK[m.chat.id] = "manualblock" await m.reply_text(text="Reloaded all admins in this chat!") LOGGER.info(f"Admincache cmd use in {m.chat.id} by {m.from_user.id}") except RPCError as ef: await m.reply_text( text=f"Some error occured, report to @{SUPPORT_GROUP} \n Error: {ef}" ) LOGGER.error(ef) LOGGER.error(format_exc()) return @Gojo.on_message(filters.regex(r"^(?i)@admin(s)?") & filters.group) async def tag_admins(_, m: Message): db = Reporting(m.chat.id) if not db.get_settings(): return try: admin_list = ADMIN_CACHE[m.chat.id] except KeyError: admin_list = await admin_cache_reload(m, "adminlist") user_admins = [i for i in admin_list if not (i[1].lower()).endswith("bot")] mention_users = [(await mention_html("\u2063", admin[0])) for admin in user_admins] mention_users.sort(key=lambda x: x[1]) mention_str = "".join(mention_users) await m.reply_text( ( f"{(await mention_html(m.from_user.first_name, m.from_user.id))}" f" reported the message to admins!{mention_str}" ), ) @Gojo.on_message(command("fullpromote") & promote_filter) async def fullpromote_usr(c: Gojo, m: Message): global ADMIN_CACHE if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text( text="I can't promote nothing! Give me an username or user id or atleast reply to that user" ) return try: user_id, user_first_name, user_name = await extract_user(c, m) except Exception: return bot = await c.get_chat_member(m.chat.id, Config.BOT_ID) if user_id == Config.BOT_ID: await m.reply_text("Huh, how can I even promote myself?") return if not bot.privileges.can_promote_members: return await m.reply_text( "I don't have enough permissions!", ) # This should be here user = await c.get_chat_member(m.chat.id, m.from_user.id) if m.from_user.id != OWNER_ID and user.status != CMS.OWNER: return await m.reply_text("This command can only be used by chat owner.") # If user is alreay admin try: admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admin_list = { i[0] for i in (await admin_cache_reload(m, "promote_cache_update")) } if user_id in admin_list: await m.reply_text( "This user is already an admin, how am I supposed to re-promote them?", ) return try: await m.chat.promote_member( user_id=user_id, can_change_info=bot.privileges.can_change_info, can_invite_users=bot.privileges.can_invite_users, can_delete_messages=bot.privileges.can_delete_messages, can_restrict_members=bot.privileges.can_restrict_members, can_pin_messages=bot.privileges.can_pin_messages, can_promote_members=bot.privileges.can_promote_members, can_manage_chat=bot.privileges.can_manage_chat, can_manage_video_chats=bot.privileges.can_manage_video_chats, ) title = "" if len(m.text.split()) == 3 and not m.reply_to_message: title = m.text.split()[2] elif len(m.text.split()) == 2 and m.reply_to_message: title = m.text.split()[1] if title and len(title) > 16: title = title[0:16] # trim title to 16 characters elif not title: title = "Gojo" try: await c.set_administrator_title(m.chat.id, user_id, title) except RPCError as e: LOGGER.error(e) LOGGER.info( f"{m.from_user.id} fullpromoted {user_id} in {m.chat.id} with title '{title}'", ) await m.reply_text( ("{promoter} promoted {promoted} in chat {chat_title}!").format( promoter=(await mention_html(m.from_user.first_name, m.from_user.id)), promoted=(await mention_html(user_first_name, user_id)), chat_title=f"{escape(m.chat.title)} title set to {title}" if title else f"{escape(m.chat.title)} title set to Gojo", ), ) # If user is approved, disapprove them as they willbe promoted and get # even more rights if Approve(m.chat.id).check_approve(user_id): Approve(m.chat.id).remove_approve(user_id) # ----- Add admin to temp cache ----- try: inp1 = user_name or user_first_name admins_group = ADMIN_CACHE[m.chat.id] admins_group.append((user_id, inp1)) ADMIN_CACHE[m.chat.id] = admins_group except KeyError: await admin_cache_reload(m, "promote_key_error") except ChatAdminRequired: await m.reply_text(text="I'm not admin or I don't have rights......") except RightForbidden: await m.reply_text(text="I don't have enough rights to promote this user.") except UserAdminInvalid: await m.reply_text( text="Cannot act on this user, maybe I wasn't the one who changed their permissions." ) except RPCError as e: await m.reply_text( text=f"Some error occured, report to @{SUPPORT_GROUP} \n Error: {e}" ) LOGGER.error(e) LOGGER.error(format_exc()) return @Gojo.on_message(command("promote") & promote_filter) async def promote_usr(c: Gojo, m: Message): global ADMIN_CACHE if len(m.text.split()) == 1 and not m.reply_to_message: await m.reply_text( text="I can't promote nothing!......reply to user to promote him/her...." ) return try: user_id, user_first_name, user_name = await extract_user(c, m) except Exception: return bot = await c.get_chat_member(m.chat.id, Config.BOT_ID) if user_id == Config.BOT_ID: await m.reply_text("Huh, how can I even promote myself?") return if not bot.privileges.can_promote_members: return await m.reply_text( "I don't have enough permissions", ) # This should be here # If user is alreay admin try: admin_list = {i[0] for i in ADMIN_CACHE[m.chat.id]} except KeyError: admin_list = { i[0] for i in (await admin_cache_reload(m, "promote_cache_update")) } if user_id in admin_list: await m.reply_text( "This user is already an admin, how am I supposed to re-promote them?", ) return try: await m.chat.promote_member( user_id=user_id, can_change_info=bot.privileges.can_change_info, can_invite_users=bot.privileges.can_invite_users, can_delete_messages=bot.privileges.can_delete_messages, can_restrict_members=bot.privileges.can_restrict_members, can_pin_messages=bot.privileges.can_pin_messages, can_manage_chat=bot.privileges.can_manage_chat, can_manage_video_chats=bot.privileges.can_manage_video_chats, ) title = "" # Deafult title if len(m.text.split()) == 3 and not m.reply_to_message: title = m.text.split()[2] elif len(m.text.split()) == 2 and m.reply_to_message: title = m.text.split()[1] if title and len(title) > 16: title = title[0:16] # trim title to 16 characters if not title: title = "Itadori" try: await c.set_administrator_title(m.chat.id, user_id, title) except RPCError as e: LOGGER.error(e) LOGGER.info( f"{m.from_user.id} promoted {user_id} in {m.chat.id} with title '{title}'", ) await m.reply_text( ("{promoter} promoted {promoted} in chat {chat_title}!").format( promoter=(await mention_html(m.from_user.first_name, m.from_user.id)), promoted=(await mention_html(user_first_name, user_id)), chat_title=f"{escape(m.chat.title)} title set to {title}" if title else f"{escape(m.chat.title)} title set to Itadori", ), ) # If user is approved, disapprove them as they willbe promoted and get # even more rights if Approve(m.chat.id).check_approve(user_id): Approve(m.chat.id).remove_approve(user_id) # ----- Add admin to temp cache ----- try: inp1 = user_name or user_first_name admins_group = ADMIN_CACHE[m.chat.id] admins_group.append((user_id, inp1)) ADMIN_CACHE[m.chat.id] = admins_group except KeyError: await admin_cache_reload(m, "promote_key_error") except ChatAdminRequired: await m.reply_text(text="I'm not admin or I don't have rights.") except RightForbidden: await m.reply_text(text="I don't have enough rights to promote this user.") except UserAdminInvalid: await m.reply_text( text="Cannot act on this user, maybe I wasn't the one who changed their permissions." ) except RPCError as e: await m.reply_text( text=f"Some error occured, report to @{SUPPORT_GROUP} \n Error: {e}" ) LOGGER.error(e) LOGGER.error(format_exc()) return @Gojo.on_message(command("invitelink")) async def get_invitelink(c: Gojo, m: Message): # Bypass the bot devs, sudos and owner if m.from_user.id not in DEV_LEVEL: user = await m.chat.get_member(m.from_user.id) if not user.privileges.can_invite_users and user.status != CMS.OWNER: await m.reply_text(text="You don't have rights to invite users....") return False try: link = await c.export_chat_invite_link(m.chat.id) await m.reply_text( text=f"Invite Link for Chat {m.chat.id}: {link}", disable_web_page_preview=True, ) LOGGER.info(f"{m.from_user.id} exported invite link in {m.chat.id}") except ChatAdminRequired: await m.reply_text(text="I'm not admin or I don't have rights.") except ChatAdminInviteRequired: await m.reply_text(text="I don't have permission for invite link!") except RightForbidden: await m.reply_text(text="You don't have permissions to invite users.") except RPCError as ef: await m.reply_text( text=f"Some error occured, report to @{SUPPORT_GROUP} \n Error: {ef}" ) LOGGER.error(ef) LOGGER.error(format_exc()) return @Gojo.on_message(command("setgtitle") & admin_filter) async def setgtitle(_, m: Message): user = await m.chat.get_member(m.from_user.id) if not user.privileges.can_change_info and user.status != CMS.OWNER: await m.reply_text( "You don't have enough permission to use this command!", ) return False if len(m.command) < 1: return await m.reply_text("Please read /help for using it!") gtit = m.text.split(None, 1)[1] try: await m.chat.set_title(gtit) except Exception as e: return await m.reply_text(f"Error: {e}") return await m.reply_text( f"Successfully Changed Group Title From {m.chat.title} To {gtit}", ) @Gojo.on_message(command("setgdes") & admin_filter) async def setgdes(_, m: Message): user = await m.chat.get_member(m.from_user.id) if not user.privileges.can_change_info and user.status != CMS.OWNER: await m.reply_text( "You don't have enough permission to use this command!", ) return False if len(m.command) < 1: return await m.reply_text("Please read /help for using it!") desp = m.text.split(None, 1)[1] try: await m.chat.set_description(desp) except Exception as e: return await m.reply_text(f"Error: {e}") return await m.reply_text( f"Successfully Changed Group description From {m.chat.description} To {desp}", ) @Gojo.on_message(command("title") & admin_filter) async def set_user_title(c: Gojo, m: Message): user = await m.chat.get_member(m.from_user.id) if not user.privileges.can_promote_members and user.status != CMS.OWNER: await m.reply_text( "You don't have enough permission to use this command!", ) return False if len(m.text.split()) == 1 and not m.reply_to_message: return await m.reply_text("To whom??") if m.reply_to_message: if len(m.text.split()) >= 2: reason = m.text.split(None, 1)[1] else: if len(m.text.split()) >= 3: reason = m.text.split(None, 2)[2] try: user_id, _, _ = await extract_user(c, m) except Exception: return if not user_id: return await m.reply_text("Cannot find user!") if user_id == Config.BOT_ID: return await m.reply_text("Huh, why ?") if not reason: return await m.reply_text("Read /help please!") from_user = await c.get_users(user_id) title = reason try: await c.set_administrator_title(m.chat.id, from_user.id, title) except Exception as e: return await m.reply_text(f"Error: {e}") return await m.reply_text( f"Successfully Changed {from_user.mention}'s Admin Title To {title}", ) @Gojo.on_message(command("setgpic") & admin_filter) async def setgpic(c: Gojo, m: Message): user = await m.chat.get_member(m.from_user.id) if not user.privileges.can_change_info and user.status != CMS.OWNER: await m.reply_text( "You don't have enough permission to use this command!", ) return False if not m.reply_to_message: return await m.reply_text("Reply to a photo to set it as chat photo") if not m.reply_to_message.photo and not m.reply_to_message.document: return await m.reply_text("Reply to a photo to set it as chat photo") photo = await m.reply_to_message.download() try: await m.chat.set_photo(photo) except Exception as e: remove(photo) return await m.reply_text(f"Error: {e}") await m.reply_text("Successfully Changed Group Photo!") remove(photo) __PLUGIN__ = "admin" __alt_name__ = [ "admins", "promote", "demote", "adminlist", "setgpic", "title", "setgtitle", "fullpromote", "invitelink", "setgdes", "zombies", ] __HELP__ = """ **Admin** **User Commands:** • /adminlist: List all the admins in the Group. **Admin only:** • /invitelink: Gets chat invitelink. • /promote: Promotes the user replied to or tagged (supports with title). • /fullpromote: Fully Promotes the user replied to or tagged (supports with title). • /demote: Demotes the user replied to or tagged. • /admincache: Reloads the List of all the admins in the Group. • /zombies: Bans all the deleted accounts. (owner only) • /title: sets a custom title for an admin that the bot promoted. • /disable : Stop users from using "commandname" in this group. • /enable : Allow users from using "commandname" in this group. • /disableable: List all disableable commands. • /disabledel : Delete disabled commands when used by non-admins. • /disabled: List the disabled commands in this chat. • /enableall: enable all disabled commands. **Example:** `/promote @username`: this promotes a user to admin."""