diff --git a/cogs/admin.py b/cogs/admin.py index 76da7ad..4e3a778 100644 --- a/cogs/admin.py +++ b/cogs/admin.py @@ -1,4 +1,5 @@ import logging +import sys from discord import ApplicationContext, Embed, User, option, slash_command from discord import utils as ds_utils @@ -14,9 +15,12 @@ logger = logging.getLogger(__name__) class Admin(commands.Cog): + """Cog with utility commands for admins.""" + def __init__(self, client: PycordBot): self.client = client + # Disabled because warning functionality is temporarily not needed # @slash_command( # name="warning", # description="Попередити юзера про порушення правил", @@ -119,42 +123,49 @@ class Admin(commands.Cog): amount, ctx.channel.id, ) + await ctx.respond( embed=Embed(description="Видаляю..."), ephemeral=True, delete_after=2.0 ) - if user == None: + + if user is None: await ctx.channel.purge(limit=amount) else: await ctx.channel.purge( limit=amount, check=lambda msg: msg.author == user ) - else: - 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 = 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, - ), + + 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 = 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="reboot", @@ -163,6 +174,7 @@ class Admin(commands.Cog): ) async def reboot_cmd(self, ctx: ApplicationContext): 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( @@ -173,34 +185,37 @@ class Admin(commands.Cog): ) scheduler.shutdown() await self.client.close() - exit() - else: - 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 = 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, - ), + 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 = 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, + ), + ) def setup(client: PycordBot): diff --git a/cogs/analytics.py b/cogs/analytics.py index e08d204..ebb6a13 100644 --- a/cogs/analytics.py +++ b/cogs/analytics.py @@ -17,8 +17,8 @@ class Analytics(commands.Cog): async def on_message(self, message: Message): if ( (message.author != self.client.user) - and (message.author.bot == False) - and (message.author.system == False) + and (message.author.bot is False) + and (message.author.system is False) ): stickers = [] for sticker in message.stickers: diff --git a/cogs/custom_channels.py b/cogs/custom_channels.py index 14c04a7..7006ca0 100644 --- a/cogs/custom_channels.py +++ b/cogs/custom_channels.py @@ -37,46 +37,8 @@ class CustomChannels(commands.Cog): ): holo_user_ctx = HoloUser(ctx.user) - if holo_user_ctx.customchannel == None: - await ctx.defer() - created_channel = await ctx.user.guild.create_text_channel( - name=name, - reason=f"Користувач {guild_name(ctx.user)} отримав власний приватний канал", - category=ds_utils.get( - ctx.author.guild.categories, - id=await config_get("customchannels", "categories"), - ), - ) - await created_channel.set_permissions( - ctx.user.guild.default_role, - send_messages=False, - add_reactions=reactions, - create_public_threads=threads, - create_private_threads=threads, - ) - await created_channel.set_permissions( - ctx.user, - attach_files=True, - manage_messages=True, - send_messages=True, - embed_links=True, - manage_channels=True, - ) - holo_user_ctx.set("customchannel", created_channel.id) - await ctx.respond( - embed=Embed( - title="Створено канал", - description=f"Вітаємо! Ви створили канал {created_channel.mention}. Для керування ним користуйтесь меню налаштувань каналу а також командою `/customchannel edit`", - color=Color.success, - ) - ) - bots = await config_get("bots") - for bot in bots: - await created_channel.set_permissions( - ds_utils.get(ctx.user.guild.roles, id=bots[bot]["role"]), - view_channel=False, - ) - else: + # Return if the user already has a custom channel + if holo_user_ctx.customchannel is not None: await ctx.defer(ephemeral=True) await ctx.respond( embed=Embed( @@ -85,6 +47,52 @@ class CustomChannels(commands.Cog): color=Color.fail, ) ) + return + + await ctx.defer() + + created_channel = await ctx.user.guild.create_text_channel( + name=name, + reason=f"Користувач {guild_name(ctx.user)} отримав власний приватний канал", + category=ds_utils.get( + ctx.author.guild.categories, + id=await config_get("customchannels", "categories"), + ), + ) + + await created_channel.set_permissions( + ctx.user.guild.default_role, + send_messages=False, + add_reactions=reactions, + create_public_threads=threads, + create_private_threads=threads, + ) + await created_channel.set_permissions( + ctx.user, + attach_files=True, + manage_messages=True, + send_messages=True, + embed_links=True, + manage_channels=True, + ) + + holo_user_ctx.set("customchannel", created_channel.id) + + await ctx.respond( + embed=Embed( + title="Створено канал", + description=f"Вітаємо! Ви створили канал {created_channel.mention}. Для керування ним користуйтесь меню налаштувань каналу а також командою `/customchannel edit`", + color=Color.success, + ) + ) + + bots = await config_get("bots") + + for bot in bots: + await created_channel.set_permissions( + ds_utils.get(ctx.user.guild.roles, id=bots[bot]["role"]), + view_channel=False, + ) @customchannel.command( name="edit", @@ -102,6 +110,8 @@ class CustomChannels(commands.Cog): custom_channel = ds_utils.get( ctx.guild.channels, id=holo_user_ctx.customchannel ) + + # Return if the channel was not found if custom_channel is None: await ctx.respond( embed=Embed( @@ -111,6 +121,7 @@ class CustomChannels(commands.Cog): ) ) return + await custom_channel.edit(name=name) await custom_channel.set_permissions( ctx.user.guild.default_role, @@ -119,6 +130,7 @@ class CustomChannels(commands.Cog): create_public_threads=threads, create_private_threads=threads, ) + await ctx.respond( embed=Embed( title="Канал змінено", @@ -138,40 +150,8 @@ class CustomChannels(commands.Cog): ): holo_user_ctx = HoloUser(ctx.user) - if holo_user_ctx.customchannel is not None: - await ctx.defer() - custom_channel = ds_utils.get( - ctx.guild.channels, id=holo_user_ctx.customchannel - ) - if custom_channel is None: - await ctx.respond( - embed=Embed( - title="Канал не знайдено", - description="Канал, вказаний як ваш, не існує. Можливо, його було вручну видалено раніше.", - color=Color.fail, - ) - ) - holo_user_ctx.set("customchannel", None) - return - if not confirm: - await ctx.respond( - embed=Embed( - title="Підтвердження не надано", - description="Для підтвердження операції додайте до команди параметр `confirm` зі значенням `True`.", - color=Color.fail, - ) - ) - return - await custom_channel.delete(reason="Власник запросив видалення") - holo_user_ctx.set("customchannel", None) - await ctx.respond( - embed=Embed( - title="Канал знищено", - description="Ви відмовились від каналу та видалили його.", - color=Color.default, - ) - ) - else: + # Return if the user does not have a custom channel + if holo_user_ctx.customchannel is None: await ctx.defer(ephemeral=True) await ctx.respond( embed=Embed( @@ -180,6 +160,48 @@ class CustomChannels(commands.Cog): color=Color.fail, ) ) + return + + await ctx.defer() + + custom_channel = ds_utils.get( + ctx.guild.channels, id=holo_user_ctx.customchannel + ) + + # Return if the channel was not found + if custom_channel is None: + await ctx.respond( + embed=Embed( + title="Канал не знайдено", + description="Канал, вказаний як ваш, не існує. Можливо, його було вручну видалено раніше.", + color=Color.fail, + ) + ) + holo_user_ctx.set("customchannel", None) + return + + # Return if the confirmation is missing + if not confirm: + await ctx.respond( + embed=Embed( + title="Підтвердження не надано", + description="Для підтвердження операції додайте до команди параметр `confirm` зі значенням `True`.", + color=Color.fail, + ) + ) + return + + await custom_channel.delete(reason="Власник запросив видалення") + + holo_user_ctx.set("customchannel", None) + + await ctx.respond( + embed=Embed( + title="Канал знищено", + description="Ви відмовились від каналу та видалили його.", + color=Color.default, + ) + ) def setup(client: PycordBot): diff --git a/cogs/data.py b/cogs/data.py index f7249f5..98fe97d 100644 --- a/cogs/data.py +++ b/cogs/data.py @@ -35,38 +35,16 @@ class Data(commands.Cog): async def data_export_cmd(self, ctx: ApplicationContext, kind: str): await ctx.defer() holo_user = HoloUser(ctx.author) - if (ctx.user.id in self.client.owner_ids) or ( + + # Return if the user is not an owner and not in the council + if (ctx.user.id not in self.client.owner_ids) and not ( await holo_user.is_council(ctx.author) ): - logging.info( - "Moderator %s exported current users list", guild_name(ctx.user) - ) - makedirs("tmp", exist_ok=True) - uuid = str(uuid4()) - - if kind == "Користувачі": - users = [] - - for member in ctx.guild.members: - users.append( - { - "id": member.id, - "nick": member.nick, - "username": f"{member.name}#{member.discriminator}", - "bot": member.bot, - } - ) - - json_write_sync(users, str(Path(f"tmp/{uuid}"))) - - await ctx.respond( - file=File(str(Path(f"tmp/{uuid}")), filename="users.json") - ) - else: logging.info( "User %s tried to use /export but permission denied", guild_name(ctx.user), ) + await ctx.respond( embed=Embed( title="Відмовлено в доступі", @@ -74,6 +52,7 @@ class Data(commands.Cog): color=Color.fail, ) ) + mod_role = ds_utils.get( ctx.user.guild.roles, id=await config_get("moderators", "roles") ) @@ -81,6 +60,7 @@ class Data(commands.Cog): ctx.user.guild.channels, id=await config_get("adminchat", "channels", "text"), ) + await admin_chan.send( content=f"{mod_role.mention}", embed=Embed( @@ -90,6 +70,33 @@ class Data(commands.Cog): ), ) + return + + logging.info("Moderator %s exported current users list", guild_name(ctx.user)) + + makedirs("tmp", exist_ok=True) + + uuid = str(uuid4()) + + if kind == "Користувачі": + users = [] + + for member in ctx.guild.members: + users.append( + { + "id": member.id, + "nick": member.nick, + "username": f"{member.name}#{member.discriminator}", + "bot": member.bot, + } + ) + + json_write_sync(users, str(Path(f"tmp/{uuid}"))) + + await ctx.respond( + file=File(str(Path(f"tmp/{uuid}")), filename="users.json") + ) + @data.command( name="migrate", description="Мігрувати всіх користувачів до бази", @@ -100,45 +107,18 @@ class Data(commands.Cog): ) async def data_migrate_cmd(self, ctx: ApplicationContext, kind: str): await ctx.defer() + holo_user = HoloUser(ctx.author) - if (ctx.user.id in self.client.owner_ids) or ( + + # Return if the user is not an owner and not in the council + if (ctx.user.id not in self.client.owner_ids) and not ( await holo_user.is_council(ctx.author) ): - logging.info( - "Moderator %s started migration of all members to the database", - guild_name(ctx.user), - ) - - if kind == "Користувачі": - for member in ctx.guild.members: - if member.bot: - continue - if col_users.find_one({"user": member.id}) is None: - user = {} - defaults = await config_get("user", "defaults") - - user["user"] = member.id - - for key in defaults: - user[key] = defaults[key] - - col_users.insert_one(document=user) - logging.info( - "Added DB record for user %s during migration", member.id - ) - - await ctx.respond( - embed=Embed( - title="Міграцію завершено", - description="Всім користувачам сервера було створено записи в базі даних.", - color=Color.success, - ) - ) - else: logging.info( "User %s tried to use /migrate but permission denied", guild_name(ctx.user), ) + await ctx.respond( embed=Embed( title="Відмовлено в доступі", @@ -146,6 +126,7 @@ class Data(commands.Cog): color=Color.fail, ) ) + mod_role = ds_utils.get( ctx.user.guild.roles, id=await config_get("moderators", "roles") ) @@ -153,6 +134,7 @@ class Data(commands.Cog): ctx.user.guild.channels, id=await config_get("adminchat", "channels", "text"), ) + await admin_chan.send( content=f"{mod_role.mention}", embed=Embed( @@ -162,6 +144,41 @@ class Data(commands.Cog): ), ) + return + + logging.info( + "Moderator %s started migration of all members to the database", + guild_name(ctx.user), + ) + + if kind == "Користувачі": + for member in ctx.guild.members: + if member.bot: + continue + + if col_users.find_one({"user": member.id}) is None: + user = {} + defaults = await config_get("user", "defaults") + + user["user"] = member.id + + for key in defaults: + user[key] = defaults[key] + + col_users.insert_one(document=user) + + logging.info( + "Added DB record for user %s during migration", member.id + ) + + await ctx.respond( + embed=Embed( + title="Міграцію завершено", + description="Всім користувачам сервера було створено записи в базі даних.", + color=Color.success, + ) + ) + def setup(client: PycordBot): client.add_cog(Data(client)) diff --git a/cogs/logger.py b/cogs/logger.py index a3d3d61..ab62b3a 100644 --- a/cogs/logger.py +++ b/cogs/logger.py @@ -15,8 +15,8 @@ class Logger(commands.Cog): async def on_message(self, message: Message): if ( (message.author != self.client.user) - and (message.author.bot == False) - and (message.author.system == False) + and (message.author.bot is False) + and (message.author.system is False) ): if col_users.find_one({"user": message.author.id}) is None: user = {} @@ -42,8 +42,8 @@ class Logger(commands.Cog): if ( (member != self.client.user) - and (member.bot == False) - and (member.system == False) + and (member.bot is False) + and (member.system is False) ): await welcome_chan.send( content=(await config_get("welcome", "messages")).format(