import logging import sys from typing import Union from discord import ( ApplicationContext, Embed, User, option, slash_command, Role, TextChannel, ) from discord import utils as ds_utils from discord.ext import commands from libbot import config_get from libbot.pycord.classes import PycordBot from libbot.sync import config_get as sync_config_get from enums import Color from modules.scheduler import scheduler from modules.utils_sync import guild_name from modules.waifu_pics import waifu_pics logger = logging.getLogger(__name__) class Admin(commands.Cog): """Cog with utility commands for admins.""" def __init__(self, client: PycordBot): self.client: PycordBot = client # Disabled because warning functionality is temporarily not needed # @slash_command( # name="warning", # description="Попередити юзера про порушення правил", # guild_ids=[config_get_sync("guild")], # ) # @option("user", description="Користувач") # @option("reason", description="Причина") # async def warn_cmd( # self, # ctx: ApplicationContext, # user: User, # reason: str = "Не вказана", # ): # logging.info(f"User {ctx.user.id} warned {user.id} for {reason}") # await ctx.defer() # jav_user = HoloUser(user) # if ctx.user.id in await config_get("admins"): # logging.info( # f"Moderator {guild_name(ctx.user)} warned {guild_name(user)} for {reason} (has {jav_user.warnings} warns)" # ) # if jav_user.warnings >= 5: # logging.info( # f"User {guild_name(user)} was banned due to a big amount of warns ({jav_user.warnings})" # ) # await user.send( # embed=Embed( # title="Перманентне блокування", # description=f"Вас було заблоковано за неодноразове порушення правил сервера.", # color=Color.fail, # ) # ) # await user.ban(reason=reason) # elif jav_user.warnings >= 2: # logging.info( # f"User {guild_name(user)} was muted due to a big amount of warns ({jav_user.warnings})" # ) # jav_user.warn(reason=reason) # await user.send( # embed=Embed( # title="Тимчасове блокування", # description=f"Причина: `{reason}`\n\nНа вашому рахунку вже {jav_user.warnings} попереджень. Вас було тимчасово заблоковано на **1 годину**.\n\nЯкщо Ви продовжите порушувати правила сервера – згодом Вас заблокують.", # color=0xDED56B, # ) # ) # await user.timeout_for(timedelta(hours=1), reason=reason) # else: # jav_user.warn() # await ctx.respond( # embed=Embed( # title="Попередження", # description=f"{user.mention} Будь ласка, не порушуйте правила. Ви отримали попередження з причини `{reason}`.\n\nЯкщо Ви продовжите порушувати правила – це може призвести до блокування в спільноті.", # color=0xDED56B, # ) # ) # else: # logging.warning( # f"User {guild_name(ctx.user)} tried to use /warn but permission denied" # ) # await ctx.respond( # embed=Embed( # title="Відмовлено в доступі", # description="Здається, це команда лише для модераторів", # color=Color.fail, # ) # ) # mod_role = ds_utils.get( # ctx.user.guild.roles, id=await config_get("moderators", "roles") # ) # admin_chan = ds_utils.get( # ctx.user.guild.channels, # id=await config_get("adminchat", "channels", "text"), # ) # await admin_chan.send( # content=f"{mod_role.mention}", # embed=Embed( # title="Неавторизований запит", # description=f"Користувач {ctx.user.mention} запитав у каналі {ctx.channel.mention} команду, до якої не повинен мати доступу/бачити.", # color=Color.fail, # ), # ) @slash_command( name="clear", description="Видалити деяку кількість повідомлень в каналі", guild_ids=[sync_config_get("guild")], ) @option("amount", description="Кількість") @option("user", description="Користувач", default=None) async def clear_cmd( self, ctx: ApplicationContext, amount: int, user: User, ) -> None: if ctx.user.id in self.client.owner_ids: logging.info( "User %s removed %s message(s) in %s", ctx.user.id, amount, ctx.channel.id, ) await ctx.respond( embed=Embed(description="Видаляю..."), ephemeral=True, delete_after=2.0 ) if user is None: await ctx.channel.purge(limit=amount) else: await ctx.channel.purge( limit=amount, check=lambda msg: msg.author == user ) return logging.warning( "User %s tried to use /clear but permission denied", guild_name(ctx.user), ) await ctx.respond( embed=Embed( title="Відмовлено в доступі", description="Здається, це команда лише для модераторів", color=Color.FAIL, ) ) mod_role: Union[Role, None] = ds_utils.get( ctx.user.guild.roles, id=await config_get("moderators", "roles") ) admin_chan: Union[TextChannel, None] = ds_utils.get( ctx.user.guild.channels, id=await config_get("adminchat", "channels", "text"), ) if admin_chan is not None: await admin_chan.send( content="" if mod_role is None else mod_role.mention, embed=Embed( title="Неавторизований запит", description=f"Користувач {ctx.user.mention} запитав у каналі {ctx.channel.mention} команду, до якої не повинен мати доступу/бачити.", color=Color.FAIL, ), ) @slash_command( name="reboot", description="Перезапустити бота", guild_ids=[sync_config_get("guild")], ) async def reboot_cmd(self, ctx: ApplicationContext) -> None: await ctx.defer(ephemeral=True) if ctx.user.id in self.client.owner_ids: logging.info("Calling shutdown initiated by %s", guild_name(ctx.user)) await ctx.respond( embed=Embed( title="Вимикаюсь...", description="Спробую перезавантажитись за 5 секунд", ) ) scheduler.shutdown() await self.client.close() await waifu_pics._client_session.close() sys.exit() logging.warning( "User %s tried to use /reboot but permission denied", guild_name(ctx.user), ) await ctx.respond( embed=Embed( title="Відмовлено в доступі", description="Здається, це команда лише для модераторів", color=Color.FAIL, ) ) mod_role: Union[Role, None] = ds_utils.get( ctx.user.guild.roles, id=await config_get("moderators", "roles") ) admin_chan: Union[TextChannel, None] = ds_utils.get( ctx.user.guild.channels, id=await config_get("adminchat", "channels", "text"), ) if admin_chan is not None: await admin_chan.send( content="" if mod_role is None else mod_role.mention, embed=Embed( title="Неавторизований запит", description=f"Користувач {ctx.user.mention} запитав у каналі {ctx.channel.mention} команду, до якої не повинен мати доступу/бачити.", color=Color.FAIL, ), ) def setup(client: PycordBot) -> None: client.add_cog(Admin(client))