diff --git a/bot/cogs/blacklist.py b/bot/cogs/blacklist.py index e4ea34b..2e719f5 100644 --- a/bot/cogs/blacklist.py +++ b/bot/cogs/blacklist.py @@ -1,20 +1,20 @@ -from discord.ext import commands +from discord.ext.commands import Cog, Bot, command, Context from ..storage import storage from .moderation import is_admin -class Blacklist(commands.Cog): +class Blacklist(Cog): """ Cog для управления чёрным списком слов. """ - def __init__(self, bot: commands.Bot) -> None: - self.bot: commands.Bot = bot + def __init__(self, bot: Bot) -> None: + self.bot: Bot = bot - @commands.command() + @command() @is_admin() - async def blacklist_show(self, ctx: commands.Context) -> None: + async def blacklist_show(self, ctx: Context) -> None: """ Показать текущий чёрный список слов. @@ -25,9 +25,9 @@ class Blacklist(commands.Cog): else: await ctx.send("Чёрный список:\n" + ", ".join(storage.blacklist)) - @commands.command() + @command() @is_admin() - async def blacklist_add(self, ctx: commands.Context, *, word: str) -> None: + async def blacklist_add(self, ctx: Context, *, word: str) -> None: """ Добавить слово в чёрный список. @@ -43,9 +43,9 @@ class Blacklist(commands.Cog): storage.save_blacklist() await ctx.send(f"Слово `{word_lower}` добавлено в чёрный список.") - @commands.command() + @command() @is_admin() - async def blacklist_remove(self, ctx: commands.Context, *, word: str) -> None: + async def blacklist_remove(self, ctx: Context, *, word: str) -> None: """ Удалить слово из чёрного списка. @@ -62,5 +62,5 @@ class Blacklist(commands.Cog): await ctx.send(f"Слово `{word_lower}` удалено из чёрного списка.") -async def setup(bot: commands.Bot) -> None: +async def setup(bot: Bot) -> None: await bot.add_cog(Blacklist(bot)) diff --git a/bot/cogs/events.py b/bot/cogs/events.py index 3d2fded..80b9a3e 100644 --- a/bot/cogs/events.py +++ b/bot/cogs/events.py @@ -1,7 +1,8 @@ -import datetime +from datetime import datetime import discord -from discord.ext import commands, tasks +from discord.ext import tasks +from discord.ext.commands import Bot, Cog from discord.utils import get from configs import settings @@ -9,16 +10,16 @@ from middleware import logger from ..storage import storage, Reminder -class Events(commands.Cog): +class Events(Cog): """ Cog с обработчиками событий и фоновой задачей напоминаний. """ - def __init__(self, bot: commands.Bot) -> None: - self.bot: commands.Bot = bot + def __init__(self, bot: Bot) -> None: + self.bot: Bot = bot self.check_reminders.start() - @commands.Cog.listener() + @Cog.listener() async def on_ready(self) -> None: """ Событие запуска бота. @@ -28,7 +29,7 @@ class Events(commands.Cog): storage.load_all() await self.ensure_roles_exist() - @commands.Cog.listener() + @Cog.listener() async def on_member_join(self, member: discord.Member) -> None: """ Событие вступления нового участника на сервер. @@ -45,7 +46,7 @@ class Events(commands.Cog): if isinstance(channel, discord.TextChannel): await channel.send(f"Приветствуем {member.mention} на сервере!") - @commands.Cog.listener() + @Cog.listener() async def on_message(self, message: discord.Message) -> None: """ Событие получения сообщения. Проверяет чёрный список слов. @@ -97,7 +98,7 @@ class Events(commands.Cog): Фоновая задача, которая каждые 30 секунд проверяет напоминания и отправляет просроченные. """ - now: float = datetime.datetime.now().timestamp() + now: float = datetime.now().timestamp() to_remove: list[Reminder] = [] for rem in storage.reminders: @@ -120,7 +121,7 @@ class Events(commands.Cog): await self.bot.wait_until_ready() -async def setup(bot: commands.Bot) -> None: +async def setup(bot: Bot) -> None: """ Функция для загрузки Cog. diff --git a/bot/cogs/moderation.py b/bot/cogs/moderation.py index 96ff2fb..75b8cec 100644 --- a/bot/cogs/moderation.py +++ b/bot/cogs/moderation.py @@ -1,11 +1,11 @@ from __future__ import annotations from typing import Callable, Awaitable, Optional - -import datetime +from datetime import datetime import discord -from discord.ext import commands +from discord.app_commands.checks import has_permissions +from discord.ext.commands import Bot, Context, Cog, check, command from discord.utils import get from configs import settings @@ -13,7 +13,7 @@ from ..storage import storage # Тип предиката для check (для читаемости, но не обязателен) -CheckPredicate = Callable[[commands.Context], Awaitable[bool]] +CheckPredicate = Callable[[Context], Awaitable[bool]] def is_admin(): @@ -23,7 +23,7 @@ def is_admin(): либо у пользователя есть флаг администратора сервера. """ - async def predicate(ctx: commands.Context) -> bool: + async def predicate(ctx: Context) -> bool: author = ctx.author if not isinstance(author, discord.Member): return False @@ -31,10 +31,10 @@ def is_admin(): admin_role = get(author.roles, name=settings.ADMIN_ROLE_NAME) return bool(admin_role) or author.guild_permissions.administrator - return commands.check(predicate) + return check(predicate) -def require_guild(ctx: commands.Context) -> Optional[discord.Guild]: +def require_guild(ctx: Context) -> Optional[discord.Guild]: """ Безопасно получить guild из контекста. @@ -43,21 +43,21 @@ def require_guild(ctx: commands.Context) -> Optional[discord.Guild]: return ctx.guild -class Moderation(commands.Cog): +class Moderation(Cog): """ Cog с модерационными командами: rules, kick, ban, unban, mute, unmute, warn, warnings, clear. """ - def __init__(self, bot: commands.Bot) -> None: + def __init__(self, bot: Bot) -> None: """ :param bot: Экземпляр бота, к которому привязан cog. """ - self.bot: commands.Bot = bot + self.bot: Bot = bot - @commands.command() + @command() @is_admin() - async def rules(self, ctx: commands.Context) -> None: + async def rules(self, ctx: Context) -> None: """ Показать правила сервера. @@ -73,11 +73,11 @@ class Moderation(commands.Cog): ) await ctx.send(rules_text) - @commands.command() + @command() @is_admin() async def kick( self, - ctx: commands.Context, + ctx: Context, member: discord.Member, *, reason: Optional[str] = None, @@ -97,11 +97,11 @@ class Moderation(commands.Cog): except discord.HTTPException: await ctx.send(f"Не удалось исключить {member} из-за ошибки Discord.") - @commands.command() + @command() @is_admin() async def ban( self, - ctx: commands.Context, + ctx: Context, member: discord.Member, *, reason: Optional[str] = None, @@ -121,9 +121,9 @@ class Moderation(commands.Cog): except discord.HTTPException: await ctx.send(f"Не удалось забанить {member} из-за ошибки Discord.") - @commands.command() - @commands.has_permissions(ban_members=True) - async def unban(self, ctx: commands.Context, *, member_name: str) -> None: + @command() + @has_permissions(ban_members=True) + async def unban(self, ctx: Context, *, member_name: str) -> None: """ Разбанить пользователя по имени или тегу. @@ -190,11 +190,11 @@ class Moderation(commands.Cog): msg_lines.append(f"- {user.name}#{user.discriminator}") await ctx.send("\n".join(msg_lines)) - @commands.command() + @command() @is_admin() async def mute( self, - ctx: commands.Context, + ctx: Context, member: discord.Member, *, reason: Optional[str] = None, @@ -224,9 +224,9 @@ class Moderation(commands.Cog): except discord.HTTPException: await ctx.send("Не удалось выдать мут из-за ошибки Discord.") - @commands.command() + @command() @is_admin() - async def unmute(self, ctx: commands.Context, member: discord.Member) -> None: + async def unmute(self, ctx: Context, member: discord.Member) -> None: """ Снять мут с участника. @@ -251,11 +251,11 @@ class Moderation(commands.Cog): except discord.HTTPException: await ctx.send("Не удалось снять мут из-за ошибки Discord.") - @commands.command() + @command() @is_admin() async def warn( self, - ctx: commands.Context, + ctx: Context, member: discord.Member, *, reason: Optional[str] = None, @@ -271,7 +271,7 @@ class Moderation(commands.Cog): storage.user_warnings.setdefault(user_id, []).append( { "reason": reason or "Без причины", - "date": datetime.datetime.now().isoformat( + "date": datetime.now().isoformat( sep=" ", timespec="seconds" ), } @@ -281,8 +281,8 @@ class Moderation(commands.Cog): f"{member} получил предупреждение. Причина: {reason or 'Без причины'}" ) - @commands.command() - async def warnings(self, ctx: commands.Context, member: discord.Member) -> None: + @command() + async def warnings(self, ctx: Context, member: discord.Member) -> None: """ Показать предупреждения участника. @@ -300,9 +300,9 @@ class Moderation(commands.Cog): lines.append(f"{i}. {w['reason']} ({w['date']})") await ctx.send("\n".join(lines)) - @commands.command() + @command() @is_admin() - async def clear(self, ctx: commands.Context, amount: int) -> None: + async def clear(self, ctx: Context, amount: int) -> None: """ Очистить указанное количество сообщений в канале. @@ -320,7 +320,7 @@ class Moderation(commands.Cog): ) -async def setup(bot: commands.Bot) -> None: +async def setup(bot: Bot) -> None: """ Зарегистрировать cog в боте. diff --git a/bot/cogs/reminders.py b/bot/cogs/reminders.py index 7dce5f5..baa22ad 100644 --- a/bot/cogs/reminders.py +++ b/bot/cogs/reminders.py @@ -1,21 +1,21 @@ from datetime import datetime, timedelta -from discord.ext import commands +from discord.ext.commands import Cog, Bot, Context, group from ..storage import storage, Reminder from .moderation import is_admin -class Reminders(commands.Cog): +class Reminders(Cog): """ Cog для управления напоминаниями: add, list, remove. """ - def __init__(self, bot: commands.Bot) -> None: - self.bot: commands.Bot = bot + def __init__(self, bot: Bot) -> None: + self.bot: Bot = bot - @commands.group() + @group() @is_admin() - async def reminder(self, ctx: commands.Context) -> None: + async def reminder(self, ctx: Context) -> None: """ Группа команд напоминаний. @@ -29,7 +29,7 @@ class Reminders(commands.Cog): @reminder.command(name="add") async def reminder_add( - self, ctx: commands.Context, minutes: int, *, text: str + self, ctx: Context, minutes: int, *, text: str ) -> None: """ Добавить новое напоминание. @@ -55,7 +55,7 @@ class Reminders(commands.Cog): await ctx.send(f"Напоминание добавлено через {minutes} минут: {text}") @reminder.command(name="list") - async def reminder_list(self, ctx: commands.Context) -> None: + async def reminder_list(self, ctx: Context) -> None: """ Показать список активных напоминаний. @@ -74,7 +74,7 @@ class Reminders(commands.Cog): await ctx.send(msg) @reminder.command(name="remove") - async def reminder_remove(self, ctx: commands.Context, number: int) -> None: + async def reminder_remove(self, ctx: Context, number: int) -> None: """ Удалить напоминание по номеру. @@ -90,5 +90,5 @@ class Reminders(commands.Cog): await ctx.send(f"Удалено напоминание: {removed.text}") -async def setup(bot: commands.Bot) -> None: +async def setup(bot: Bot) -> None: await bot.add_cog(Reminders(bot))