Esempio n. 1
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.message.mentions) < 1:
                    return CommandResult.args_error("Пользователь не указан.")

                role = ctx.message.guild.get_role(MUTED_ROLE_ID)

                if role is None:
                    return CommandResult.error("Роль мута с ID %s не найдена!" % MUTED_ROLE_ID)

                if role not in ctx.message.mentions[0].roles:
                    return CommandResult.error("Этот пользователь не в муте!")

                await ctx.message.mentions[0].remove_roles(role, reason="Unmute")

                await ctx.send_embed(EmbedType.OK, "%s снял мут с %s." % (
                    ctx.message.author.mention, ctx.message.mentions[0].mention), "Наказания",
                                     self.module.bot.get_channel(MODLOG_CHANNEL_ID), sign=False)

                for user in list(self.module.bot.module_handler.params["moderation_mutes"]):
                    if user.user_id == ctx.message.mentions[0].id:
                        self.module.bot.module_handler.params["moderation_mutes"].remove(user)
                        self.module.bot.module_handler.save_params()

                        for role_id in user.roles:
                            if ctx.message.guild.get_role(role_id):
                                await ctx.message.mentions[0].add_roles(ctx.message.guild.get_role(role_id))
                        return CommandResult.ok()

                return CommandResult.ok()
Esempio n. 2
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.clean_args) < 1:
                    return CommandResult.args_error()

                query = " ".join(ctx.clean_args)

                nf_the_search = wikipedia.search(query, results=1)

                if len(nf_the_search) == 0:
                    return CommandResult.error(
                        "По запросу \"%s\" ничего не найдено." % query)

                title = nf_the_search[0]

                while True:
                    try:
                        text = wikipedia.summary(title, sentences=4)
                    except wikipedia.DisambiguationError as e:
                        title = e.options[0]
                    else:
                        break

                page = wikipedia.page(title)

                embed: discord.Embed = ctx.get_embed(EmbedType.INFO, text,
                                                     page.title)
                if len(page.images) > 0:
                    embed.set_image(url=page.images[0])

                await ctx.message.channel.send(embed=embed)

                return CommandResult.ok()
Esempio n. 3
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if SearchModule.cx is None or SearchModule.api_key is None:
                    return CommandResult.error(
                        "Команда не работает, так как API ключ и/или CX "
                        "недоступны. Возможно, бот запущен не в продакшн-среде."
                    )

                if len(ctx.clean_args) < 1:
                    return CommandResult.args_error()

                index = None
                try:
                    index = int(ctx.keys["index"])
                except ValueError:
                    pass
                except KeyError:
                    pass
                # if len(ctx.raw_keys) != 0 and ctx.raw_keys[0].startswith("index="):
                #     try:
                #         index = int(ctx.raw_keys[0].split("index=")[1])
                #     except ValueError:
                #         pass

                await self.module.bot.module_handler.add_background_task(
                    self.image_task(ctx, " ".join(ctx.clean_args), index),
                    self.module)

                return CommandResult.ok(wait_emoji=True)
Esempio n. 4
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.clean_args) < 1:
                    return CommandResult.args_error()

                if StatsModule.github_token is None:
                    return CommandResult.error("Команда не работает, т.к. не указан Github токен.")

                g = Github(StatsModule.github_token)

                try:
                    time_now = datetime.datetime.utcnow()

                    commits = ["%s - **%s** (*%s*)" % (x.message.split("\n\n")[0], x.author.name, (
                            LanguageUtils.formatted_duration(
                                int((time_now - x.committer.date).total_seconds()), 0) + " назад"))
                               for x in
                               [i.commit for i in
                                g.get_repo(
                                    ctx.clean_args[0]).get_commits()[0:5]]]

                    embed: discord.Embed = ctx.get_embed(EmbedType.INFO, "",
                                                         "Статистика коммитов по репозиторию %s" % ctx.clean_args[0])
                    embed.add_field(name="**Всего коммитов:**",
                                    value=str(g.get_repo(ctx.clean_args[0]).get_commits().totalCount),
                                    inline=False)

                    if "search-by" in ctx.keys:
                        comm_msg = ctx.keys["search-by"].lower()

                        commits = []
                        start_time = time.time()

                        for commit in g.get_repo(ctx.clean_args[0]).get_commits():
                            message = commit.commit.message.split("\n\n")[0]

                            if time.time() - start_time >= 3:
                                break

                            if comm_msg in message.lower():
                                commits.append(message)

                                if len(commits) == 5:
                                    break

                        if len(commits) == 0:
                            return CommandResult.error("Не удалось найти коммиты с таким сообщением.")

                        message = "**Последние коммиты с cообщением \"%s\":**" % comm_msg
                    else:
                        message = "**Последние коммиты:**"

                    embed.add_field(name=message, value="\n\n".join(commits[0:5]),
                                    inline=False)

                    await ctx.message.channel.send(embed=embed)
                    return CommandResult.ok()
                except UnknownObjectException:
                    return CommandResult.error("Репозитория %s не существует!" % ctx.clean_args[0])
Esempio n. 5
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if not len(ctx.message.attachments):
                    return CommandResult.args_error("Нет изображения.")

                attachment = ctx.message.attachments[0]

                if not attachment.filename.lower().endswith(("jpg", "gif", "png")):
                    return CommandResult.args_error("Приклеплённое вами вложение не является изображением.")

                await self.module.bot.module_handler.add_background_task(self.image_scan_task(attachment.url, ctx),
                                                                         self.module)

                return CommandResult.ok(wait_emoji=True)
Esempio n. 6
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.args) < 1:
                    return CommandResult.args_error()

                keyword = " ".join(ctx.clean_args)

                results = self.YoutubeSearch(keyword, max_results=1).to_dict()

                if len(results) < 1:
                    return CommandResult.error("Видео по этому запросу не найдено.")

                await ctx.message.channel.send("Видео по запросу \"%s\": (запросил: %s)\n%s" % (
                    keyword, ctx.message.author.mention, "https://youtube.com/" + results[0]["url_suffix"]))
                return CommandResult.ok()
Esempio n. 7
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                await ctx.message.channel.send(
                    embed=ctx.get_embed(EmbedType.ERROR, "", "До связи."))

                await self.module.bot.close()

                return CommandResult.ok("")
Esempio n. 8
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.args) < 1:
                    return CommandResult.args_error()
                elif len(ctx.args) > 1:
                    if ctx.clean_args[1].lower() not in ["video", "music"]:
                        return CommandResult.error(
                            "Второй аргумент должен быть <video> или <music>")

                try:
                    response = self.parse_link_coub(
                        ctx.clean_args[0], ctx.clean_args[1]
                        if len(ctx.clean_args) > 1 else "video")
                except ValueError:
                    return CommandResult.error("Указанная ссылка не работает.")
                except KeyError:
                    return CommandResult.error("Указанная ссылка не работает.")

                try:
                    self.download_coub(response)
                except requests.RequestException:
                    return CommandResult.error("Ошибка скачивания коуба.")
                except OSError:
                    return CommandResult.error("Ошибка записи коуба.")

                await ctx.message.channel.send(
                    "Коуб успешно преобразован.\n{}\n(Заказал: {})".format(
                        response["title"], ctx.message.author.mention),
                    file=discord.File("file." + response["type"]))

                DownloadModule.delete_file(response["type"])

                return CommandResult.ok()
Esempio n. 9
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.args) < 1:
                    return CommandResult.args_error()

                command = self.module.bot.command_handler.find_command(
                    ctx.args[0].lower())

                if not command:
                    return CommandResult.error(
                        "Команда с таким именем не найдена.")

                embed: discord.Embed = ctx.get_embed(EmbedType.INFO, "",
                                                     "Информация о команде")
                embed.add_field(name=command.get_detailed_name(),
                                value=command.description)

                await ctx.message.channel.send(embed=embed)

                return CommandResult.ok()
Esempio n. 10
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.args) < 1:
                    return CommandResult.args_error()

                keyword = " ".join(ctx.clean_args)

                search = SearchVideos(keyword, mode="dict", max_results=1)

                if not search:
                    return CommandResult.error("Не удалось получить видео.")

                results = search.result()["search_result"]

                if len(results) == 0:
                    return CommandResult.error(
                        "Видео по этому запросу не найдено.")

                await ctx.message.channel.send(
                    "Видео по запросу \"%s\": (запросил: %s)\n%s" %
                    (keyword, ctx.message.author.mention, results[0]["link"]))
                return CommandResult.ok()
Esempio n. 11
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if not self.model_loaded:
                    return CommandResult.error("Этот ИИ не загружен.")

                prefix = None

                if len(ctx.clean_args) > 0 and ctx.clean_args[0].startswith(
                        "prefix="):
                    prefix = " ".join(ctx.clean_args)[7:]

                output = self.model.generate(
                    temperature=self.module.bot.module_handler.get_param(
                        "ai_temp"),
                    return_as_list=True,
                    prefix=prefix)[0]

                embed = ctx.get_custom_embed(output, "ИИ %s" % self.title,
                                             self.color)

                await ctx.message.channel.send(embed=embed)
                return CommandResult.ok()
Esempio n. 12
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.message.mentions) < 1:
                    return CommandResult.args_error("Пользователь не указан.")

                if ctx.message.mentions[0] == self.module.bot.user:
                    return CommandResult.error("Меня нельзя замутить :)")

                if ctx.message.mentions[0] == ctx.message.author:
                    return CommandResult.error("Вы не можете замутить самого себя!")

                role = ctx.message.guild.get_role(MUTED_ROLE_ID)

                if role is None:
                    return CommandResult.error("Роль мута с ID %s не найдена!" % MUTED_ROLE_ID)

                if role in ctx.message.mentions[0].roles:
                    return CommandResult.error("Этот пользователь уже в муте!")

                if ctx.message.author.top_role.position < ctx.message.mentions[
                    0].top_role.position and ctx.message.author.guild_permissions > ctx.message.mentions[
                    0].guild_permissions:
                    return CommandResult.error("Вы не можете замутить этого пользователя.")

                reason = "Плохое поведение"
                roles = []

                if len(ctx.args) > 1:
                    reason = " ".join(ctx.args[1:])

                await ctx.message.mentions[0].add_roles(role, reason=reason)

                for member_role in ctx.message.mentions[0].roles:
                    if member_role != role and member_role.id != ctx.message.guild.id:
                        await ctx.message.mentions[0].remove_roles(member_role)
                        roles.append(member_role.id)

                await ctx.send_embed(EmbedType.ERROR, "%s был заткнут %s по причине \"%s\"." % (
                    ctx.message.mentions[0].mention, ctx.message.author.mention, reason),
                                     "Наказания", self.module.bot.get_channel(MODLOG_CHANNEL_ID), sign=False)

                for user in self.module.bot.module_handler.get_param("moderation_mutes"):
                    if user.user_id == ctx.message.mentions[0].id:
                        return CommandResult.ok()

                muted_user = MutedUser(ctx.message.mentions[0].id, ctx.message.author.guild.id,
                                       roles, 0)
                self.module.bot.module_handler.params["moderation_mutes"].append(muted_user)
                self.module.bot.module_handler.save_params()

                return CommandResult.ok()
Esempio n. 13
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                commands_field = ""
                users_field = ""

                if len(stats["command_top"].values()):
                    sorted_top = {k: v for k, v in
                                  sorted(stats["command_top"].items(), key=lambda item: item[1],
                                         reverse=True)}

                    for i, k in enumerate(sorted_top):
                        commands_field += "**%s.** `%s` - %s\n" % (i + 1, k, sorted_top[k])

                        if i > 9:
                            break
                else:
                    commands_field = "Ещё неизвестно."

                top_user_avatar = None

                if len(stats["user_top"].values()):
                    sorted_top = {k: v for k, v in
                                  sorted(stats["user_top"].items(), key=lambda item: item[1]["commands_used"],
                                         reverse=True)}

                    for i, k in enumerate(sorted_top):
                        user = await self.module.bot.fetch_user(int(k))

                        if i == 0 and user is not None:
                            top_user_avatar = user.avatar_url

                        users_field += "**%s.** %s - %s\n" % (
                            i + 1, sorted_top[k]["display_name"] + " (недоступен)" if not user else user.mention,
                            sorted_top[k]["commands_used"])

                        if i > 9:
                            break
                else:
                    users_field = "Еще неизвестно."

                embed: discord.Embed = ctx.get_embed(EmbedType.INFO, "", "Статистика бота %s" % self.module.bot.name)

                embed.add_field(name="**Всего команд обработано:**", value=stats["processed_commands"], inline=False)
                embed.add_field(name="**Топ используемых команд:**",
                                value=commands_field, inline=False)
                embed.add_field(name="**Топ пользователей по командам:**", value=users_field, inline=False)

                if top_user_avatar is not None:
                    embed.set_thumbnail(url=top_user_avatar)

                await ctx.message.channel.send(embed=embed)

                return CommandResult.ok()
Esempio n. 14
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if ctx.message.guild.id not in stats["activity_top"]:
                    return CommandResult.error("Ещё неизвестно!")

                activity_stats = stats["activity_top"][ctx.message.guild.id]

                sorted_top = {k: v for k, v in sorted(activity_stats.items(), key=lambda item: len(item[1]))}

                top_text = ""

                i = 1
                for k, v in sorted_top.items():
                    top_text += "**%s.** %s (%s)\n" % (
                        i, k, LanguageUtils.pluralize(len(v), "пользователь", "пользователя", "пользователей"))

                    i += 1

                embed: discord.Embed = ctx.get_embed(EmbedType.INFO, "", "Статистика активности")
                embed.add_field(name="Топ активностей по кол-ву участников сервера", value=top_text)

                await ctx.message.channel.send(embed=embed)

                return CommandResult.ok()
Esempio n. 15
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.args) < 1:
                    return CommandResult.args_error()

                try:
                    limit = int(ctx.args[0])
                except ValueError:
                    return CommandResult.args_error("Вы указали не число.")

                if limit not in range(101):
                    return CommandResult.args_error("Вы указали число меньше 1 или больше 100.")

                def check(msg):
                    return True if len(ctx.message.mentions) < 1 else msg.author == ctx.message.mentions[0]

                try:
                    await ctx.message.delete()
                except discord.NotFound:
                    pass

                deleted = await ctx.message.channel.purge(limit=limit, check=check)

                await ctx.send_embed(EmbedType.ERROR,
                                     "%s удалил %s из канала %s." % (ctx.message.author.mention,
                                                                     pluralize_russian(
                                                                         len(deleted),
                                                                         "сообщение",
                                                                         "сообщения",
                                                                         "сообщений"),
                                                                     ctx.message.channel), "Очистка сообщений",
                                     self.module.bot.get_channel(MODLOG_CHANNEL_ID), sign=False)

                return CommandResult.ok("Удалено %s." % (
                    LanguageUtils.pluralize(len(deleted),
                                            "сообщение",
                                            "сообщения",
                                            "сообщений")))
Esempio n. 16
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                embed: discord.Embed = ctx.get_embed(
                    EmbedType.INFO,
                    "Всего модулей: %s" %
                    len(self.module.bot.module_handler.modules),
                    title="Список модулей")

                for module in self.module.bot.module_handler.modules:
                    embed.add_field(name=module.name,
                                    value=module.description,
                                    inline=False)

                await ctx.message.channel.send(embed=embed)

                return CommandResult.ok()
Esempio n. 17
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.args) < 1:
                    return CommandResult.args_error()
                elif len(ctx.args) > 1:
                    if ctx.clean_args[1] not in ["video", "music"]:
                        return CommandResult.error(
                            "Второй аргумент должен быть <video> или <music>")

                try:
                    response = self.download_tube(
                        ctx.clean_args[0], ctx.clean_args[1]
                        if len(ctx.clean_args) > 1 else "video")
                except FileTooLarge as e:
                    return CommandResult.error(e.message)
                except pytube.exceptions.LiveStreamError:
                    return CommandResult.error(
                        "Вы отправили ссылку на прямой эфир.")
                except pytube.exceptions.ExtractError:
                    return CommandResult.error(
                        "Не удалось скачать видео/аудио.")
                except pytube.exceptions.HTMLParseError:
                    return CommandResult.error(
                        "Не удалось проанализировать ссылку. Вероятно вы отправили ссылку не на ютуб."
                    )
                except pytube.exceptions.PytubeError:
                    return CommandResult.error("Неизвестная ошибка API.")
                except pytube.exceptions.VideoUnavailable:
                    return CommandResult.error(
                        "Данное видео недоступно. Вероятно вы отправили ссылку на заблокированное или приватное видео."
                    )

                await ctx.message.channel.send(
                    "Видео успешно преобразовано.\n{}\n(Заказал: {})".format(
                        response["title"], ctx.message.author.mention),
                    file=discord.File("file." + response["type"]))

                DownloadModule.delete_file(response["type"])

                return CommandResult.ok()
Esempio n. 18
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.args) > 0 and ctx.args[0].lower() == "set":
                    if len(ctx.args) < 3:
                        return CommandResult.args_error(
                            "Вы указали параметр `set`, но вы не указали ключ и/или значение."
                        )

                    try:
                        param = self.module.bot.module_handler.params[
                            ctx.args[1]]
                    except KeyError:
                        return CommandResult.error("Параметр не найден.")

                    try:
                        value_parsed = self.parse_value_for_type(
                            " ".join(ctx.args[2:]), type(param))
                    except ValueError:
                        return CommandResult.error(
                            "Этот параметр невозможно изменить, так как его тип не позволяет получить значение из "
                            "текста.")

                    if value_parsed is None:
                        return CommandResult.error(
                            "Не удалось привести значение к типу. Проверьте правильность "
                            "значениия.")

                    self.module.bot.module_handler.set_param(
                        ctx.args[1], value_parsed, True)

                    return CommandResult.ok()

                embed: discord.Embed = ctx.get_embed(
                    EmbedType.INFO, "Параметров загружено: %s" %
                    len(self.module.bot.module_handler.params),
                    "Список параметров")

                for key, value in self.module.bot.module_handler.params.items(
                ):
                    embed.add_field(
                        name="%s [тип: %s]" % (key, type(value).__name__),
                        value=value if type(value) not in (dict, list) else
                        "Значение не отображено",
                        inline=False)

                await ctx.message.channel.send(embed=embed)

                return CommandResult.ok()
Esempio n. 19
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                self.module.bot.start_time = time.time()

                out = io.StringIO()
                with redirect_stdout(out):
                    self.module.logger.info("Начата перезагрузка модулей...")

                    for module in list(self.module.bot.module_handler.modules):
                        self.module.bot.module_handler.unload_module(module)
                        self.module.bot.command_handler.unregister_module_commands(
                            module.name)

                    self.module.bot.module_handler.load_modules()

                    await self.module.bot.on_ready()

                await ctx.send_embed(
                    EmbedType.INFO, "```prolog\n%s```" %
                    re.compile(r'\x1b[^m]*m').sub("", out.getvalue()),
                    "Лог перезагрузки")

                return CommandResult.ok()
Esempio n. 20
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                embed: discord.Embed = ctx.get_embed(EmbedType.INFO,
                                                     "",
                                                     title="Список команд")

                count = 0

                for command in list(
                        self.module.bot.command_handler.commands.values()):
                    if command.perm_handler.has_permission(
                            ctx.message.author) or "all" in ctx.raw_keys:
                        count += 1

                        embed.add_field(name=command.get_detailed_name(),
                                        value=command.description,
                                        inline=False)

                embed.description = "Всего команд: %s" % count

                await ctx.message.channel.send(embed=embed)

                return CommandResult.ok()
Esempio n. 21
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                if len(ctx.message.mentions) < 1:
                    return CommandResult.args_error("Пользователь не указан.")

                if ctx.message.mentions[0] == self.module.bot.user:
                    return CommandResult.error("Меня нельзя замутить :)")

                if ctx.message.mentions[0] == ctx.message.author:
                    return CommandResult.error("Вы не можете замутить самого себя!")

                role = ctx.message.guild.get_role(MUTED_ROLE_ID)

                if role is None:
                    return CommandResult.error("Роль мута с ID %s не найдена!" % MUTED_ROLE_ID)

                if role in ctx.message.mentions[0].roles:
                    return CommandResult.error("Этот пользователь уже в муте!")

                if ctx.message.author.top_role.position < ctx.message.mentions[
                    0].top_role.position and ctx.message.author.guild_permissions > ctx.message.mentions[
                    0].guild_permissions:
                    return CommandResult.error("Вы не можете замутить этого пользователя.")

                reason = "Плохое поведение"
                roles = []

                try:
                    duration = int(ctx.args[1])
                except ValueError:
                    return CommandResult.args_error("Вы указали не число.")

                if ctx.args[2].lower() not in self.duration_variants:
                    return CommandResult.args_error("Вы указали неверную единицу времени.")

                deadline = time.time() + duration * self.duration_variants[ctx.args[2].lower()]

                if len(ctx.args) > 3:
                    reason = " ".join(ctx.args[3:])

                await ctx.message.mentions[0].add_roles(role, reason=reason)

                for member_role in ctx.message.mentions[0].roles:
                    if member_role != role and member_role.id != ctx.message.guild.id:
                        await ctx.message.mentions[0].remove_roles(member_role)
                        roles.append(member_role.id)

                declensions = declensions_dict[ctx.args[2].lower()]
                unit = pluralize_russian(duration, declensions[0], declensions[1], declensions[2])

                await ctx.send_embed(EmbedType.ERROR, "%s был заткнут %s по причине \"%s\" на %s %s." % (
                    ctx.message.mentions[0].mention,
                    ctx.message.author.mention,
                    reason,
                    duration,
                    unit),
                                     "Наказания", self.module.bot.get_channel(MODLOG_CHANNEL_ID), sign=False)

                for user in list(self.module.bot.module_handler.params["moderation_mutes"]):
                    if user.user_id == ctx.message.mentions[0].id:
                        self.module.bot.module_handler.params["moderation_mutes"].remove(user)

                muted_user = MutedUser(ctx.message.mentions[0].id, ctx.message.author.guild.id,
                                       roles, deadline)

                self.module.bot.module_handler.params["moderation_mutes"].append(muted_user)
                self.module.bot.module_handler.save_params()

                return CommandResult.ok()
Esempio n. 22
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                # Проверки на аргументы
                if len(ctx.args) == 0:
                    return CommandResult.args_error()

                if ctx.args[0] not in ("create", "add", "remove", "rename"):
                    return CommandResult.args_error()

                # Смотрим че хочет юзер
                if ctx.args[0] == "create":
                    # Не заменять на try-except
                    # Почему? Юзеры скорее всего не будут указывать опциональный канал, а обработка исключения накладна
                    channel = ctx.message.channel_mentions and ctx.message.channel_mentions[
                        0] or ctx.message.channel

                    # Создается структура сервера
                    cache[str(ctx.message.guild.id)] = {
                        CHANNEL_ID: channel.id,
                        MESSAGE_ID: 0,
                        ROLES: []
                    }

                    embed = self.create_embed(ctx)
                    msg: discord.Message = await channel.send(embed=embed)

                    cache[str(ctx.message.guild.id)][MESSAGE_ID] = msg.id
                    save_cache()
                if ctx.args[0] in ("add", "remove", "rename"):
                    # Проверки
                    try:
                        dossier = cache[str(ctx.message.guild.id)]
                    except KeyError:
                        return CommandResult.error(
                            "Вам необходимо создать сообщение заново.")

                    if not ctx.message.role_mentions:
                        return CommandResult.args_error()

                    if ctx.args[0] == "remove":
                        # Удаляются ВСЕ упомянутые роли с сообщения
                        for role in ctx.message.role_mentions:
                            role: discord.Role

                            for i, role_object in enumerate(dossier[ROLES]):
                                another_role_id, description = role_object

                                # Поиск необходимой роли для удаления
                                if another_role_id == role.id:
                                    # Замена на UNDEFINED
                                    dossier[ROLES][i] = UNDEFINED_ROLE

                        while dossier[ROLES] and dossier[ROLES][-1][0] == -1:
                            del dossier[ROLES][-1]
                    elif ctx.args[0] == "add":
                        if next(
                                filter(
                                    lambda x: x[0] == ctx.message.
                                    role_mentions[0].id, dossier[ROLES]),
                                None):
                            return CommandResult.error(
                                "Такая роль уже существует!")

                        added = False

                        # Находим свободное место
                        for i, role_object in enumerate(dossier[ROLES]):
                            if role_object[0] == -1:
                                # Выставляем роль и описание
                                dossier[ROLES][i] = (
                                    ctx.message.role_mentions[0].id,
                                    " ".join(ctx.args[2:]))

                                added = True
                                break

                        if not added:
                            # Тут tuple. лишних скобок нет
                            # Выставляем роль и описание
                            dossier[ROLES].append(
                                (ctx.message.role_mentions[0].id,
                                 " ".join(ctx.args[2:])))
                    elif ctx.args[0] == "rename":
                        if next(
                                filter(
                                    lambda x: x[0] == ctx.message.
                                    role_mentions[0].id, dossier[ROLES]),
                                None) is None:
                            return CommandResult.error(
                                "Такой роли не существует!")

                        for i, role_object in enumerate(dossier[ROLES]):
                            if role_object[0] == ctx.message.role_mentions[
                                    0].id:
                                dossier[ROLES][i] = (
                                    ctx.message.role_mentions[0].id,
                                    " ".join(ctx.args[2:]))

                                break

                    # Сохраняем всё
                    save_cache()

                    # Обновляем сообщение
                    embed = self.create_embed(ctx)
                    guild: discord.Guild = ctx.message.guild
                    channel: discord.TextChannel = guild.get_channel(
                        dossier[CHANNEL_ID])

                    # Проверка на наличие сообщения
                    try:
                        msg: discord.Message = await channel.fetch_message(
                            dossier[MESSAGE_ID])
                    except discord.NotFound:
                        # Обработка отсутствия
                        msg = await channel.send(embed=embed)

                        # Проставляем эмодзи
                        for i in range(len(dossier[ROLES])):
                            emoji = chr(EMOJI_START + i)

                            await msg.add_reaction(emoji)
                        return CommandResult.info(
                            message=
                            "Поскольку сообщение было удалено, автоматически было создано новое.",
                            title=
                            "Произошла ошибка, которая была автоматически разрешена."
                        )
                    else:
                        await msg.edit(embed=embed)
                        # Удаляем лишние реакции

                        for reaction in msg.reactions:
                            reaction: discord.Reaction

                            if reaction.custom_emoji:
                                await reaction.clear()

                            if ord(reaction.emoji) not in range(
                                    EMOJI_START,
                                    EMOJI_START + len(dossier[ROLES])):
                                await reaction.clear()

                        # Проставляем недостающие.
                        for i in range(len(dossier[ROLES])):
                            emoji = chr(EMOJI_START + i)

                            if next(
                                    filter(lambda x: x.emoji == emoji,
                                           msg.reactions), None) is None:
                                await msg.add_reaction(emoji)

                return CommandResult.ok()
Esempio n. 23
0
            async def execute(self, ctx: CommandContext) -> CommandResult:
                await self.module.bot.close()

                return CommandResult.ok()