async def fetch_dict_from_message(ctx, message_link, required_keys=[], enforce_numeric_values=False): message = await fetch_message(ctx, message_link) if not message: await ctx.send(embed=create_basic_embed(TEXT_INVALID_MESSAGE_LINK, EMOJI_ERROR)) return try: content = message.content message_dict = loads(content[content.index("{"):content.rindex("}") + 1]) except ValueError: await ctx.send(embed=create_basic_embed('Please make sure the message is properly formatted.', EMOJI_ERROR)) return None clean_dict = {} for key in required_keys: if key in message_dict: value = message_dict[key] if enforce_numeric_values and not isinstance(value, numbers.Number): await ctx.send(embed=create_basic_embed('Please make sure all values are numeric.', EMOJI_ERROR)) return None clean_dict[key] = value else: await ctx.send(embed=create_basic_embed(f'Message is missing required key **{key}**.', EMOJI_ERROR)) return None return clean_dict
async def respond_to_dm(message): log(f'Received a DM from {message.author.name}#{message.author.discriminator}:') for line in message.content.split('\n'): log(line, indent=1) if REGEX_HELP.match(message.content): await message.channel.send(embed=create_basic_embed(TEXT_DM_HELP, EMOJI_ERROR)) else: embed = create_basic_embed(TEXT_DM_RESPONSE) file = File(FILENAME_PUSHEEN, 'image.gif') embed.set_image(url='attachment://image.gif') await message.channel.send(embed=embed, file=file)
async def play_youtube_audio(self, url, voice_channel, text_channel, success_text, skip_seconds): # noinspection PyBroadException try: loop = self.bot.loop or asyncio.get_event_loop() data = await loop.run_in_executor(None, lambda: YoutubeDL(YTDL_OPTIONS).extract_info(url, download=False)) audio_source = FFmpegPCMAudio(data['url'], options=f'-ss {skip_seconds}') voice_client = await voice_channel.connect() voice_client.play(audio_source) await text_channel.send(embed=create_basic_embed(success_text)) except Exception as exception: print(exception) await text_channel.send(embed=create_basic_embed('Error playing YouTube audio.', EMOJI_ERROR))
async def handle_spank_command(message, bot=None): if len(message.mentions) != 1 and not bot: embed = create_basic_embed('Please specify exactly one person to spank.', EMOJI_ERROR) await message.channel.send(embed=embed) return async with message.channel.typing(): spank_image_1 = Image.open(FILENAME_SPANK_1) spank_image_2 = Image.open(FILENAME_SPANK_2) spanker_image = await EasterEggs.get_avatar_image(message.author if not bot else bot.user) spankee_image = await EasterEggs.get_avatar_image(message.mentions[0] if not bot else message.author) if spanker_image: spank_image_1 = EasterEggs.process_image( spanker_image, new_size=(64, 64), apply_mask=True, bg_image=spank_image_1, position=(155, 75)) spank_image_2 = EasterEggs.process_image( spanker_image, new_size=(64, 64), apply_mask=True, bg_image=spank_image_2, position=(142, 75)) if spankee_image: spank_image_1 = EasterEggs.process_image( spankee_image, new_size=(50, 50), apply_mask=True, bg_image=spank_image_1, position=(146, 202)) spank_image_2 = EasterEggs.process_image( spankee_image, new_size=(50, 50), apply_mask=True, bg_image=spank_image_2, position=(141, 202)) with BytesIO() as image_bytes: spank_image_1.save(image_bytes, 'gif', save_all=True, append_images=[spank_image_2], duration=180, loop=0) image_bytes.seek(0) await message.channel.send(file=File(fp=image_bytes, filename='spank.gif'))
def create_game_embed(title: str = '', title_singular: str = '', title_plural_format: str = '', current_progress: int = 0, total_progress: int = ABS_NUMBER_OF_FLASHES, subtitle: str = '', description: str = '', icon_url: str = URL_REVAN_ICON, show_thumbnail: bool = False, players_label: str = '', players: list = [], show_no_players_text: bool = True): if title_singular and len(players) == 1: embed_title = title_singular elif title_plural_format: embed_title = title_plural_format.format(len(players)) else: embed_title = title if current_progress: embed_title += TEXT_GAME_EMOJI_AB_ACTIVE * current_progress embed_title += TEXT_GAME_EMOJI_AB_BLANK * (total_progress - current_progress) embed = create_basic_embed(subtitle + description + players_label) embed.set_author(name=embed_title, icon_url=icon_url) if show_thumbnail: embed.set_thumbnail(url=URL_REVAN_THUMBNAIL) if players or show_no_players_text: embed.description += AbsGame.AbsGameSession.get_players_string(players, mention_players=True) return embed
async def handle_audio_command(self, ctx, audio_emoji, audio_title, audio_url, skip_seconds=0): text_channel = ctx.channel if len(ctx.message.mentions) == 1: user = ctx.message.mentions[0] if user.voice: voice_channel = user.voice.channel success_text = TEXT_SUCCESS_FORMAT.format(audio_emoji, audio_title, voice_channel.name) async with text_channel.typing(): await self.disconnect_voice_clients() await self.play_youtube_audio(audio_url, voice_channel, text_channel, success_text, skip_seconds) else: embed = create_basic_embed(f'**{user.mention}** is not currently in a voice channel.', EMOJI_ERROR) await text_channel.send(embed=embed) else: embed = create_basic_embed('Please specify exactly one person to receive the audio.', EMOJI_ERROR) await text_channel.send(embed=embed)
async def start_game(self, players): async with self.active_channel_lock: if self.active_channel: self.bot.remove_cog(COG_INTRO_SESSION) game_session_cog = AbsGame.AbsGameSession(self.active_channel, players, self.finish_game) self.bot.add_cog(game_session_cog) await game_session_cog.start() else: log(f'ERROR: Attempted to start game with no active channel. This should never happen.') embed_text = 'Something went wrong while trying to start the game. Sorry!' await ctx.channel.send(embed=create_basic_embed(embed_text, EMOJI_ERROR))
async def start(self): embed = create_basic_embed() embed.title = TEXT_INTRO_TITLE embed.set_author(name=TEXT_INTRO_AUTHOR, icon_url=URL_REVAN_ICON, url=URL_ARTIST_CREDIT) embed.set_thumbnail(url=URL_REVAN_THUMBNAIL) embed.set_footer(text=TEXT_INTRO_TIME_FORMAT.format(INTRO_DURATION_SECONDS)) async with self.lock: embed.description = self.get_description_string() self.message = await self.channel.send(embed=embed) log(f'Initializing a new Abs Game in "{self.channel.name}". ' f'Accepting players for {self.time_remaining} seconds!') log(f'STARTING PLAYER: {self.players[0].name}#{self.players[0].discriminator}', indent=1) self.countdown.start()
async def abs(self, ctx): # Only recognize this command in the #revan-abs-game channel for now. if ctx.channel.id != 914637952825573377: return bot_member = ctx.guild.get_member(self.bot.user.id) if not ctx.channel.permissions_for(bot_member).send_messages: log(f'ERROR: Missing permission to send messages in channel "{ctx.channel.name}".') return async with self.active_channel_lock: if self.active_channel: log(f'Already running an Abs Game in "{self.active_channel.name}". ' f'Ignoring command from {ctx.author.name}#{ctx.author.discriminator}.') if ctx.channel.id != self.active_channel.id: embed_text = f'Sorry {ctx.author.mention}, I\'m too busy right now! Please wait a little bit.' await ctx.channel.send(embed=create_basic_embed(embed_text, EMOJI_ERROR)) else: self.active_channel = ctx.channel intro_session_cog = AbsGame.AbsIntroSession(ctx.channel, ctx.author, self.start_game) self.bot.add_cog(intro_session_cog) await intro_session_cog.start()
async def handle_bonk_command(message, sunder=False): if len(message.mentions) != 1: embed = create_basic_embed('Please specify exactly one person to bonk.', EMOJI_ERROR) await message.channel.send(embed=embed) return async with message.channel.typing(): bonk_image = Image.open(FILENAME_BONK) bonker_image = Image.open(FILENAME_SUNDER) if sunder else await EasterEggs.get_avatar_image(message.author) bonkee_image = await EasterEggs.get_avatar_image(message.mentions[0]) if bonker_image: bonk_image = EasterEggs.process_image( bonker_image, new_size=(75, 75), apply_mask=True, bg_image=bonk_image, position=(42, 30)) if bonkee_image: bonk_image = EasterEggs.process_image( bonkee_image, new_size=(100, 32), rotate_angle=28, apply_mask=True, bg_image=bonk_image, position=(270, 94)) with BytesIO() as image_bytes: bonk_image.save(image_bytes, 'png') image_bytes.seek(0) await message.channel.send(file=File(fp=image_bytes, filename='bonk.png'))
async def stopaudio(self, ctx): await self.disconnect_voice_clients() await ctx.channel.send(embed=create_basic_embed('Successfully stopped all audio playback.', EMOJI_SUCCESS))