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() 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.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 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: 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: 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: 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: 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 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.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()