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()
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()
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)
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])
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)
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()
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("")
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()
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()
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()
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()
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()
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()
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()
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), "сообщение", "сообщения", "сообщений")))
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()
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()
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()
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()
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()
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()
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()
async def execute(self, ctx: CommandContext) -> CommandResult: await self.module.bot.close() return CommandResult.ok()