From 4bc1cdaae280b0f55a0dac252b6765709686dd56 Mon Sep 17 00:00:00 2001 From: ekzyis Date: Sat, 25 Sep 2021 21:30:51 +0200 Subject: [PATCH 1/2] Use embeds --- src/bot.py | 29 ++++++++++++++++++++++------- src/error.py | 5 ++++- src/message/__init__.py | 32 ++++++++++++++++++++++++++++++++ test/test_bot.py | 10 ++++------ 4 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 src/message/__init__.py diff --git a/src/bot.py b/src/bot.py index a21b94d..63a6e95 100644 --- a/src/bot.py +++ b/src/bot.py @@ -1,6 +1,7 @@ import os import sys import asyncio +from dataclasses import dataclass import discord from discord.ext import commands, tasks @@ -8,6 +9,7 @@ from dotenv import load_dotenv import youtube_dl from error import ErrorHandler +from message import NowPlayingMessage, QueuedMessage load_dotenv() @@ -15,6 +17,13 @@ load_dotenv() youtube_dl.utils.bug_reports_message = lambda: '' +@dataclass +class Song: + title: str + webpage_url: str + audio_url: str + + class Music(commands.Cog): def __init__(self, bot): self._bot = bot @@ -49,8 +58,8 @@ class Music(commands.Cog): async def _handle_playback(self): while True: await self._queue_lock.acquire() - ctx, url, title = await self._queue.get() - audio = discord.FFmpegPCMAudio(url, **self._ffmpeg_options) + ctx, song = await self._queue.get() + audio = discord.FFmpegPCMAudio(song.audio_url, **self._ffmpeg_options) def after(err): if err: @@ -58,7 +67,9 @@ class Music(commands.Cog): self._queue.task_done() self._queue_lock.release() ctx.voice_client.play(audio, after=after) - await ctx.send(f"Now playing: {title}") + + embed = NowPlayingMessage(title=song.title, url=song.webpage_url) + await ctx.send(embed=embed) @_handle_playback.before_loop async def before_handle_playback(self): @@ -70,11 +81,15 @@ class Music(commands.Cog): data = self._ytdl.extract_info(query, download=False) if 'entries' in data: data = data['entries'][0] - title = data.get('title') - url = data.get('url') - await self._queue.put((ctx, url, title)) + song = Song( + title=data.get('title'), + audio_url=data.get('url'), + webpage_url=data.get('webpage_url') + ) + await self._queue.put((ctx, song)) if ctx.voice_client.is_playing(): - await ctx.send(f"Queued: {title}") + embed = QueuedMessage(title=song.title, url=song.webpage_url) + await ctx.send(embed=embed) @commands.command() async def skip(self, ctx): diff --git a/src/error.py b/src/error.py index 7f1009e..5bf9470 100644 --- a/src/error.py +++ b/src/error.py @@ -1,5 +1,7 @@ from discord.ext import commands +from message import ErrorMessage + class ErrorHandler(commands.Cog): """A cog for global error handling.""" @@ -20,7 +22,8 @@ class ErrorHandler(commands.Cog): else: message = "Oh no! Something went wrong while running the command!" - await ctx.send(message) + embed = ErrorMessage(message) + await ctx.send(embed=embed) def setup(bot: commands.Bot): diff --git a/src/message/__init__.py b/src/message/__init__.py new file mode 100644 index 0000000..472127f --- /dev/null +++ b/src/message/__init__.py @@ -0,0 +1,32 @@ +import discord + + +class BotMessage(discord.Embed): + pass + + +class ErrorMessage(BotMessage): + def __init__(self, message): + super().__init__( + title="Error", + description=message, + color=discord.Color.red() + ) + + +class NowPlayingMessage(BotMessage): + def __init__(self, title, url): + super().__init__( + title=f"Now playing: {title}", + description=url, + color=discord.Color.green() + ) + + +class QueuedMessage(BotMessage): + def __init__(self, title, url): + super().__init__( + title=f"Queued: {title}", + description=url, + color=discord.Color.blue() + ) diff --git a/test/test_bot.py b/test/test_bot.py index 20d9225..a597913 100644 --- a/test/test_bot.py +++ b/test/test_bot.py @@ -64,9 +64,8 @@ async def test_bot_playback(mbot, ctx): assert \ ctx.voice_client.play.call_args.args == (deliver_us_audio,), \ "Did not playback correct audio" - assert \ - ctx.send.call_args.args == (f"Now playing: {title}",), \ - "Did not send 'Now playing:' message" + embed = ctx.send.call_args.kwargs["embed"] + assert embed.title == f"Now playing: {title}", "Did not send 'Now playing:' message" # TEST: Following songs are put inside a queue ctx.voice_client.is_playing.return_value = True @@ -86,9 +85,8 @@ async def test_bot_playback(mbot, ctx): assert \ not ctx.voice_client.play.call_args.args == (time_of_dying_audio,), \ "Did immediately playback audio instead of being queued" - assert \ - ctx.send.call_args.args == (f"Queued: {title}",), \ - "Did not send 'Queued:' message" + embed = ctx.send.call_args.kwargs["embed"] + assert embed.title == f"Queued: {title}", "Did not send 'Queued:' message" await asyncio.sleep(0) # Assert that there is still no playback because previous song is not finished yet assert \ From fbb51bb0e156aa3fbda288f2eadf3090153142d5 Mon Sep 17 00:00:00 2001 From: ekzyis Date: Sat, 25 Sep 2021 21:34:46 +0200 Subject: [PATCH 2/2] Improve error messages --- src/bot.py | 4 ++-- src/message/__init__.py | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/bot.py b/src/bot.py index 63a6e95..ac85f26 100644 --- a/src/bot.py +++ b/src/bot.py @@ -95,7 +95,7 @@ class Music(commands.Cog): async def skip(self, ctx): async with ctx.typing(): if ctx.voice_client is None or not ctx.voice_client.is_playing(): - raise commands.CommandError("Cannot skip: No song playing") + raise commands.CommandError("No song playing") ctx.voice_client.stop() @commands.command() @@ -108,7 +108,7 @@ class Music(commands.Cog): if ctx.author.voice: await ctx.author.voice.channel.connect() else: - raise commands.CommandError("Author not connected to a voice channel.") + raise commands.CommandError("Author not connected to a voice channel") if __name__ == "__main__": diff --git a/src/message/__init__.py b/src/message/__init__.py index 472127f..6998ef0 100644 --- a/src/message/__init__.py +++ b/src/message/__init__.py @@ -8,8 +8,7 @@ class BotMessage(discord.Embed): class ErrorMessage(BotMessage): def __init__(self, message): super().__init__( - title="Error", - description=message, + title=f"Error: {message}", color=discord.Color.red() )