From 245431bf1d5e30836493bf2ebe3d10ad3588f4c5 Mon Sep 17 00:00:00 2001 From: Roxedus Date: Sun, 14 Jun 2020 17:34:33 +0200 Subject: [PATCH 1/9] Add leavetimer? Hard to test, as the bug it is intended to fix is hard to reproduce --- cogs/musicevents.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cogs/musicevents.py b/cogs/musicevents.py index 7110505..a5efda4 100644 --- a/cogs/musicevents.py +++ b/cogs/musicevents.py @@ -5,8 +5,9 @@ A cog to separate events from regular music commands # Discord Packages import lavalink import lavalink.events -from discord.ext import commands +from discord.ext import commands, tasks +import asyncio import codecs import yaml @@ -17,6 +18,7 @@ from .utils.mixplayer import MixPlayer class MusicEvents(commands.Cog): def __init__(self, bot): self.bot = bot + self.leave_timer.start() # TODO: maybe only load when Music loads if not hasattr(bot, 'lavalink'): # This ensures the client isn't overwritten during cog reloads. bot.lavalink = lavalink.Client(bot.user.id, player=MixPlayer) @@ -80,6 +82,18 @@ class MusicEvents(commands.Cog): await player.stop() await self.connect_to(guild.id, None) + async def leave_check(self): + if len(self.bot.lavalink.player_manager.players) != 0: + for player_id in self.bot.lavalink.player_manager.players: + await self.check_leave_voice(player_id) + return + return + + @tasks.loop(seconds=10.0) + async def leave_timer(self): + await self.leave_check() + await asyncio.sleep(10) + def setup(bot): bot.add_cog(MusicEvents(bot)) From 1f15abba6ae78571ce2e4e650670908ea4084ba3 Mon Sep 17 00:00:00 2001 From: Roxedus Date: Sun, 14 Jun 2020 17:43:06 +0200 Subject: [PATCH 2/9] Add error handling to give feedback to the user --- bot.py | 39 +------------------- cogs/errors.py | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 38 deletions(-) create mode 100644 cogs/errors.py diff --git a/bot.py b/bot.py index e70b4df..5ac7611 100644 --- a/bot.py +++ b/bot.py @@ -12,15 +12,14 @@ import aiohttp import yaml # Bot Utilities -from cogs.helpformatter import commandhelper from cogs.utils.alias import Aliaser from cogs.utils.context import Context from cogs.utils.localizer import Localizer, LocalizerWrapper from cogs.utils.logger import BotLogger -from cogs.utils.paginator import Scroller from cogs.utils.settingsmanager import Settings initial_extensions = [ + 'cogs.errors', 'cogs.cogs', 'cogs.settings', 'cogs.misc', @@ -64,42 +63,6 @@ class Bot(commands.Bot): except Exception: self.logger.exception("Loading of extension %s failed" % extension) - async def on_command_error(self, ctx, err): - if not self.debug: - if (isinstance(err, commands.MissingRequiredArgument) or - isinstance(err, commands.BadArgument)): - paginator = commandhelper(ctx, ctx.command, ctx.invoker, include_subcmd=False) - scroller = Scroller(ctx, paginator) - await scroller.start_scrolling() - - if isinstance(err, commands.CommandInvokeError): - self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err)) - pass - - elif isinstance(err, commands.NoPrivateMessage): - self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err)) - await ctx.send('That command is not available in DMs') - - elif isinstance(err, commands.CommandOnCooldown): - await ctx.send(f"{ctx.message.author.mention} Command is on cooldown. " - f"Try again in `{err.retry_after:.1f}` seconds.") - - elif isinstance(err, RuntimeError): - self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err)) - pass - - elif isinstance(err, commands.CheckFailure): - self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err)) - pass - - elif isinstance(err, commands.CommandNotFound): - pass - else: - tb = err.__traceback__ - traceback.print_tb(tb) - print(err) - self.logger.debug("Error running command: %s\n Traceback: %s" % (ctx.command, err)) - async def on_message(self, message): if message.author.bot: return diff --git a/cogs/errors.py b/cogs/errors.py new file mode 100644 index 0000000..7403955 --- /dev/null +++ b/cogs/errors.py @@ -0,0 +1,96 @@ +# Discord Packages +import discord +from discord.ext import commands + +import traceback + +# Bot Utilities +from cogs.helpformatter import commandhelper +from cogs.utils.paginator import Scroller + + +class Errors(commands.Cog): + def __init__(self, bot): + self.bot = bot + self.logger = self.bot.main_logger.bot_logger.getChild("Errors") + + async def base_msg(self, ctx, state: int = 0xFCBA03): + embed = discord.Embed(color=state) + embed.title = '{errors.error_occurred}' + embed.set_footer(icon_url=ctx.author.avatar_url, + text=f'{ctx.author.name}#{ctx.author.discriminator}') + return embed + + @commands.Cog.listener() + async def on_command_error(self, ctx, err): + ignored = (commands.CommandNotFound) + + if isinstance(err, ignored): + return + + if isinstance(err, commands.CommandInvokeError) and (err.original == 'Join a voicechannel first.'): + embed = await self.base_msg(ctx, state=0xFC0303) + embed.description = '{errors.join_voice_first}' + embed = ctx.localizer.format_embed(embed) + return await ctx.send(embed=embed) + elif isinstance(err, commands.CommandInvokeError) and (err.original == 'Not connected.'): + embed = await self.base_msg(ctx, state=0xFC0303) + embed.description = '{errors.not_connected}' + embed = ctx.localizer.format_embed(embed) + return await ctx.send(embed=embed) + elif isinstance(err, commands.CommandInvokeError) and (err.original == + 'I need the `CONNECT` and `SPEAK` permissions.'): + embed = await self.base_msg(ctx, state=0xFC0303) + embed.description = '{errors.need_permission}' + embed = ctx.localizer.format_embed(embed) + return await ctx.send(embed=embed) + elif isinstance(err, commands.CommandInvokeError) and (err.original == + 'You need to be in the right voice channel'): + embed = await self.base_msg(ctx, state=0xFC0303) + embed.description = '{errors.right_channel}' + embed = ctx.localizer.format_embed(embed) + return await ctx.send(embed=embed) + elif isinstance(err, commands.CommandInvokeError) and (err.original == 'You need to be in my voicechannel.'): + embed = await self.base_msg(ctx, state=0xFC0303) + embed.description = '{errors.my_channel}' + embed = ctx.localizer.format_embed(embed) + return await ctx.send(embed=embed) + if not self.bot.debug: + if (isinstance(err, commands.MissingRequiredArgument) or + isinstance(err, commands.BadArgument)): + paginator = commandhelper(ctx, ctx.command, ctx.invoker, include_subcmd=False) + scroller = Scroller(ctx, paginator) + await scroller.start_scrolling() + + if isinstance(err, commands.CommandInvokeError): + self.logger.debug( + "Error running command: %s\nTraceback: %s" % (ctx.command, err)) + pass + + elif isinstance(err, commands.NoPrivateMessage): + self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) + await ctx.send('That command is not available in DMs') + + elif isinstance(err, commands.CommandOnCooldown): + await ctx.send(f"{ctx.message.author.mention} Command is on cooldown. " + f"Try again in `{err.retry_after:.1f}` seconds.") + + elif isinstance(err, RuntimeError): + self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) + pass + + elif isinstance(err, commands.CheckFailure): + self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) + pass + + elif isinstance(err, commands.CommandNotFound): + pass + else: + tb = err.__traceback__ + traceback.print_tb(tb) + print(err) + self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) + + +def setup(bot): + bot.add_cog(Errors(bot)) From 0133a34f9e3f9f682d683e85ce711b0253713f3a Mon Sep 17 00:00:00 2001 From: Roxedus Date: Sun, 14 Jun 2020 17:43:18 +0200 Subject: [PATCH 3/9] Properly catch error --- cogs/cogs.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/cogs.py b/cogs/cogs.py index fd78a2c..cc3bbff 100644 --- a/cogs/cogs.py +++ b/cogs/cogs.py @@ -23,8 +23,8 @@ class Cogs(commands.Cog): try: self.bot.load_extension(f'cogs.{module}') await ctx.send(f'{module} loaded') - except Exception as e: - await ctx.send(f'```py\n{traceback.format_exc(e)}\n```') + except Exception: + await ctx.send(f'```py\n{traceback.format_exc()}\n```') @_cogs.command() @commands.is_owner() From a2db13611d77b15042a0c85c767b210efd2c9ee1 Mon Sep 17 00:00:00 2001 From: Roxedus Date: Sun, 14 Jun 2020 17:43:37 +0200 Subject: [PATCH 4/9] Add localizations --- localization/en_en/music.yaml | 7 +++++++ localization/nb_no/music.yaml | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/localization/en_en/music.yaml b/localization/en_en/music.yaml index 2afafbb..d13dedf 100644 --- a/localization/en_en/music.yaml +++ b/localization/en_en/music.yaml @@ -74,3 +74,10 @@ history: settings_check: textchannel: "You can't use music commands in this channel.\nTry in: " voicechannel: 'I can only play music in: ' +errors: + error_occurred: An error occurred + join_voice_first: You need to join a voicechannel first + not_connected: Not connected + need_permission: I need the `CONNECT` and `SPEAK` permissions + right_channel: You need to be in the right voice channel + my_channel: You need to be in my voicechannel diff --git a/localization/nb_no/music.yaml b/localization/nb_no/music.yaml index 42c6c61..d91492f 100644 --- a/localization/nb_no/music.yaml +++ b/localization/nb_no/music.yaml @@ -74,3 +74,10 @@ history: settings_check: textchannel: "Du kan ikke bruke musikkommandoer i denne kanalen.\nPrøv i: " voicechannel: 'Jeg kan bare spille musikk i: ' +errors: + error_occurred: En feil oppstod + join_voice_first: Du må være i en stemmekanal + not_connected: Ikke tilkoblet + need_permission: Jeg trenger tillgang til `CONNECT` og `SPEAK` + right_channel: Du må være i riktig kanal + my_channel: Du må være i samme stemmekanal som meg From f5b6a17d9d0cf92b5f220e7e8056db3b0de73356 Mon Sep 17 00:00:00 2001 From: Roxedus Date: Sun, 14 Jun 2020 17:47:21 +0200 Subject: [PATCH 5/9] Rename module --- cogs/music.py | 12 ++++++------ cogs/utils/{RoxUtils.py => thumbnailer.py} | 0 2 files changed, 6 insertions(+), 6 deletions(-) rename cogs/utils/{RoxUtils.py => thumbnailer.py} (100%) diff --git a/cogs/music.py b/cogs/music.py index f64d053..6aa0e0a 100644 --- a/cogs/music.py +++ b/cogs/music.py @@ -17,7 +17,7 @@ from typing import Optional import yaml from bs4 import BeautifulSoup -from .utils import RoxUtils, checks, timeformatter +from .utils import checks, thumbnailer, timeformatter from .utils.mixplayer import MixPlayer from .utils.paginator import QueuePaginator, Scroller, TextPaginator from .utils.selector import Selector @@ -147,7 +147,7 @@ class Music(commands.Cog): if player.current: song = f'**[{player.current.title}]({player.current.uri})**' embed = discord.Embed(color=ctx.me.color, description=song, title='{now}') - thumbnail_url = await RoxUtils.ThumbNailer.identify(self, player.current.identifier, player.current.uri) + thumbnail_url = await thumbnailer.ThumbNailer.identify(self, player.current.identifier, player.current.uri) member = ctx.guild.get_member(player.current.requester) if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) @@ -217,7 +217,7 @@ class Music(commands.Cog): member = ctx.guild.get_member(player.current.requester) embed = discord.Embed(color=ctx.me.color, description=song, title='{now}') - thumbnail_url = await RoxUtils.ThumbNailer.identify(self, player.current.identifier, player.current.uri) + thumbnail_url = await thumbnailer.ThumbNailer.identify(self, player.current.identifier, player.current.uri) if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) @@ -337,7 +337,7 @@ class Music(commands.Cog): # Create a nice embed explaining what happened song = f'**[{moved.title}]({moved.uri})**' embed = discord.Embed(color=ctx.me.color, description=song, title='{moved.moved}') - thumbnail_url = await RoxUtils.ThumbNailer.identify(self, moved.identifier, moved.uri) + thumbnail_url = await thumbnailer.ThumbNailer.identify(self, moved.identifier, moved.uri) member = ctx.guild.get_member(moved.requester) if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) @@ -563,7 +563,7 @@ class Music(commands.Cog): description = ctx.localizer.format_str("{history.current}", _title=track.title, _uri=track.uri, _id=track.requester) + '\n\n' description += ctx.localizer.format_str("{history.previous}", _len=len(history)-1) + '\n' - thumb_url = await RoxUtils.ThumbNailer.identify(self, track.identifier, track.uri) + thumb_url = await thumbnailer.ThumbNailer.identify(self, track.identifier, track.uri) for index, track in enumerate(history[1:], start=1): description += ctx.localizer.format_str("{history.track}", _index=-index, _title=track.title, _uri=track.uri, _id=track.requester) + '\n' @@ -796,7 +796,7 @@ class Music(commands.Cog): embed.add_field(name="{enqueue.playing_in}", value=f"`{until_play} ({{enqueue.estimated}})`", inline=True) embed.title = '{enqueue.enqueued}' - thumb_url = await RoxUtils.ThumbNailer.identify(self, track.identifier, track.uri) + thumb_url = await thumbnailer.ThumbNailer.identify(self, track.identifier, track.uri) if thumb_url: embed.set_thumbnail(url=thumb_url) diff --git a/cogs/utils/RoxUtils.py b/cogs/utils/thumbnailer.py similarity index 100% rename from cogs/utils/RoxUtils.py rename to cogs/utils/thumbnailer.py From 0b0210b8bbb1b96b0448633b559f458d5b847aaf Mon Sep 17 00:00:00 2001 From: Roxedus Date: Sun, 14 Jun 2020 18:06:04 +0200 Subject: [PATCH 6/9] Add thumbnail url to extra less lookups overall --- cogs/music.py | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/cogs/music.py b/cogs/music.py index 6aa0e0a..81670ae 100644 --- a/cogs/music.py +++ b/cogs/music.py @@ -81,13 +81,17 @@ class Music(commands.Cog): numtracks = 0 for track in tracks: if track['info']['length'] <= maxlength: - track = lavalink.models.AudioTrack(track, ctx.author.id) + thumbnail_url = await thumbnailer.ThumbNailer.identify( + self, track['info']['identifier'], track['info']['uri']) + track = lavalink.models.AudioTrack(track, ctx.author.id, thumbnail_url=thumbnail_url) player.add(requester=ctx.author.id, track=track) numtracks += 1 else: numtracks = len(tracks) for track in tracks: - track = lavalink.models.AudioTrack(track, ctx.author.id) + thumbnail_url = await thumbnailer.ThumbNailer.identify( + self, track['info']['identifier'], track['info']['uri']) + track = lavalink.models.AudioTrack(track, ctx.author.id, thumbnail_url=thumbnail_url) player.add(requester=ctx.author.id, track=track) embed.title = '{playlist_enqued}' @@ -96,7 +100,9 @@ class Music(commands.Cog): await ctx.send(embed=embed) else: track = results['tracks'][0] - track = lavalink.models.AudioTrack(track, ctx.author.id) + thumbnail_url = await thumbnailer.ThumbNailer.identify( + self, track['info']['identifier'], track['info']['uri']) + track = lavalink.models.AudioTrack(track, ctx.author.id, thumbnail_url=thumbnail_url) await self.enqueue(ctx, track, embed) embed = ctx.localizer.format_embed(embed) await ctx.send(embed=embed) @@ -147,7 +153,7 @@ class Music(commands.Cog): if player.current: song = f'**[{player.current.title}]({player.current.uri})**' embed = discord.Embed(color=ctx.me.color, description=song, title='{now}') - thumbnail_url = await thumbnailer.ThumbNailer.identify(self, player.current.identifier, player.current.uri) + thumbnail_url = player.current.extra["thumbnail_url"] member = ctx.guild.get_member(player.current.requester) if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) @@ -217,7 +223,7 @@ class Music(commands.Cog): member = ctx.guild.get_member(player.current.requester) embed = discord.Embed(color=ctx.me.color, description=song, title='{now}') - thumbnail_url = await thumbnailer.ThumbNailer.identify(self, player.current.identifier, player.current.uri) + thumbnail_url = player.current.extra["thumbnail_url"] if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) @@ -337,7 +343,7 @@ class Music(commands.Cog): # Create a nice embed explaining what happened song = f'**[{moved.title}]({moved.uri})**' embed = discord.Embed(color=ctx.me.color, description=song, title='{moved.moved}') - thumbnail_url = await thumbnailer.ThumbNailer.identify(self, moved.identifier, moved.uri) + thumbnail_url = moved.extra["thumbnail_url"] member = ctx.guild.get_member(moved.requester) if thumbnail_url: embed.set_thumbnail(url=thumbnail_url) @@ -563,7 +569,7 @@ class Music(commands.Cog): description = ctx.localizer.format_str("{history.current}", _title=track.title, _uri=track.uri, _id=track.requester) + '\n\n' description += ctx.localizer.format_str("{history.previous}", _len=len(history)-1) + '\n' - thumb_url = await thumbnailer.ThumbNailer.identify(self, track.identifier, track.uri) + thumbnail_url = track.extra["thumbnail_url"] for index, track in enumerate(history[1:], start=1): description += ctx.localizer.format_str("{history.track}", _index=-index, _title=track.title, _uri=track.uri, _id=track.requester) + '\n' @@ -571,8 +577,8 @@ class Music(commands.Cog): embed = discord.Embed(title=ctx.localizer.format_str('{history.title}'), color=ctx.me.color, description=description) - if thumb_url: - embed.set_thumbnail(url=thumb_url) + if thumbnail_url: + embed.set_thumbnail(url=thumbnail_url) await ctx.send(embed=embed) @commands.cooldown(1, 5, commands.BucketType.guild) @@ -796,10 +802,10 @@ class Music(commands.Cog): embed.add_field(name="{enqueue.playing_in}", value=f"`{until_play} ({{enqueue.estimated}})`", inline=True) embed.title = '{enqueue.enqueued}' - thumb_url = await thumbnailer.ThumbNailer.identify(self, track.identifier, track.uri) + thumbnail_url = track.extra["thumbnail_url"] - if thumb_url: - embed.set_thumbnail(url=thumb_url) + if thumbnail_url: + embed.set_thumbnail(url=thumbnail_url) duration = timeformatter.format_ms(int(track.duration)) embed.description = f'[{track.title}]({track.uri})\n**{duration}**' From 00b6d110410c0b9eb69d5e293a07908df488698f Mon Sep 17 00:00:00 2001 From: Ev-1 <33662061+Ev-1@users.noreply.github.com> Date: Wed, 26 Aug 2020 23:12:30 +0200 Subject: [PATCH 7/9] update to new d.py and lavalink --- bot.py | 5 +++-- cogs/cogs.py | 2 +- cogs/misc.py | 2 +- cogs/music.py | 3 ++- cogs/utils/checks.py | 2 +- localization/en_en/music.yaml | 2 +- requirements.txt | 5 ++--- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/bot.py b/bot.py index c07e3a6..d6b3035 100644 --- a/bot.py +++ b/bot.py @@ -49,8 +49,6 @@ class Bot(commands.Bot): self.localizer = Localizer(conf.get('locale path', "./localization"), conf.get('locale', 'en_en')) self.aliaser = Aliaser(conf.get('locale path', "./localization"), conf.get('locale', 'en_en')) - self.session = aiohttp.ClientSession(loop=self.loop) - self.datadir = datadir self.debug = debug self.main_logger = logger @@ -121,6 +119,9 @@ class Bot(commands.Bot): async def on_ready(self): if not hasattr(self, 'uptime'): self.uptime = time.time() + + self.session = aiohttp.ClientSession(loop=self.loop) + for extension in on_ready_extensions: try: self.logger.debug("Loading extension %s" % extension) diff --git a/cogs/cogs.py b/cogs/cogs.py index e07b7cd..a5b9fac 100644 --- a/cogs/cogs.py +++ b/cogs/cogs.py @@ -63,7 +63,7 @@ class Cogs(commands.Cog): @commands.is_owner() async def _shutdown(self, ctx): """Logs out and stops.""" - self.bot.lavalink.players.clear() + self.bot.lavalink.player_manager.players.clear() await self.bot.logout() diff --git a/cogs/misc.py b/cogs/misc.py index 1d600a0..7de75c7 100644 --- a/cogs/misc.py +++ b/cogs/misc.py @@ -51,7 +51,7 @@ class Misc(commands.Cog): lavalink = self.bot.lavalink listeners = 0 - for guild, player in lavalink.player_manager.players: + for guild, player in lavalink.player_manager.players.items(): listeners += len(player.listeners) embed.add_field(name='{music.players}', value=f'{len(lavalink.player_manager.players)}') diff --git a/cogs/music.py b/cogs/music.py index 8fb9446..19e997d 100644 --- a/cogs/music.py +++ b/cogs/music.py @@ -195,7 +195,8 @@ class Music(commands.Cog): player.queue.clear() await player.stop() - await ctx.send(ctx.localizer.format_str("{stop}")) + embed = discord.Embed(color=ctx.me.color, title='{stop}') + await ctx.send(embed=ctx.localizer.format_embed(embed)) @commands.command(name='now') async def _now(self, ctx): diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index 3925184..1358097 100644 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -60,7 +60,7 @@ def is_dj(ctx): def dj_or(alone: bool = False, track_requester: bool = False): async def predicate(ctx): try: - player = ctx.bot.lavalink.players.get(ctx.guild.id) + player = ctx.bot.lavalink.player_manager.get(ctx.guild.id) is_alone = (ctx.author in player.listeners and len(player.listeners) == 1) and alone requester = (player.current.requester == ctx.author.id) and track_requester diff --git a/localization/en_en/music.yaml b/localization/en_en/music.yaml index 2afafbb..97d0797 100644 --- a/localization/en_en/music.yaml +++ b/localization/en_en/music.yaml @@ -15,7 +15,7 @@ skip_to: invalid_pos: Invalid specified position. exceeds_queue: The position exceeds the queue\'s length. skipped_to: skipped to `{_title}` at position `{_pos}` -stop: "⏹ | Stopped." +stop: "Stopped." live: "\U0001F534 LIVE" now: Now Playing queue: diff --git a/requirements.txt b/requirements.txt index 58c9768..9f1d579 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ -discord.py >= 1.3 -git+https://github.com/Devoxin/Lavalink.py@b614a5389e3cf5ea7c444041428a05b084ca15ec +discord.py +git+https://github.com/Devoxin/Lavalink.py@dev asyncio pyyaml BeautifulSoup4 -aiohttp<3.5.0,>=3.3.0 \ No newline at end of file From ffa9e5e1a99146ce28addce81e850a5c1b7ddc33 Mon Sep 17 00:00:00 2001 From: Ev-1 <33662061+Ev-1@users.noreply.github.com> Date: Thu, 27 Aug 2020 15:09:49 +0200 Subject: [PATCH 8/9] Fix logic error, move repeated code to function. --- cogs/errors.py | 96 ++++++++++++++++++++++---------------------------- 1 file changed, 42 insertions(+), 54 deletions(-) diff --git a/cogs/errors.py b/cogs/errors.py index 7403955..f0ea6da 100644 --- a/cogs/errors.py +++ b/cogs/errors.py @@ -23,73 +23,61 @@ class Errors(commands.Cog): @commands.Cog.listener() async def on_command_error(self, ctx, err): - ignored = (commands.CommandNotFound) - if isinstance(err, ignored): + # Help commands + if (isinstance(err, commands.MissingRequiredArgument) or + isinstance(err, commands.BadArgument)): + paginator = commandhelper(ctx, ctx.command, ctx.invoker, include_subcmd=False) + scroller = Scroller(ctx, paginator) + await scroller.start_scrolling() + + if isinstance(err, (commands.CommandNotFound)): return - if isinstance(err, commands.CommandInvokeError) and (err.original == 'Join a voicechannel first.'): + async def send_error_embed(description): embed = await self.base_msg(ctx, state=0xFC0303) - embed.description = '{errors.join_voice_first}' + embed.description = description embed = ctx.localizer.format_embed(embed) return await ctx.send(embed=embed) - elif isinstance(err, commands.CommandInvokeError) and (err.original == 'Not connected.'): - embed = await self.base_msg(ctx, state=0xFC0303) - embed.description = '{errors.not_connected}' - embed = ctx.localizer.format_embed(embed) - return await ctx.send(embed=embed) - elif isinstance(err, commands.CommandInvokeError) and (err.original == - 'I need the `CONNECT` and `SPEAK` permissions.'): - embed = await self.base_msg(ctx, state=0xFC0303) - embed.description = '{errors.need_permission}' - embed = ctx.localizer.format_embed(embed) - return await ctx.send(embed=embed) - elif isinstance(err, commands.CommandInvokeError) and (err.original == - 'You need to be in the right voice channel'): - embed = await self.base_msg(ctx, state=0xFC0303) - embed.description = '{errors.right_channel}' - embed = ctx.localizer.format_embed(embed) - return await ctx.send(embed=embed) - elif isinstance(err, commands.CommandInvokeError) and (err.original == 'You need to be in my voicechannel.'): - embed = await self.base_msg(ctx, state=0xFC0303) - embed.description = '{errors.my_channel}' - embed = ctx.localizer.format_embed(embed) - return await ctx.send(embed=embed) - if not self.bot.debug: - if (isinstance(err, commands.MissingRequiredArgument) or - isinstance(err, commands.BadArgument)): - paginator = commandhelper(ctx, ctx.command, ctx.invoker, include_subcmd=False) - scroller = Scroller(ctx, paginator) - await scroller.start_scrolling() - if isinstance(err, commands.CommandInvokeError): - self.logger.debug( - "Error running command: %s\nTraceback: %s" % (ctx.command, err)) - pass + # Music related errors + if isinstance(err, commands.CommandInvokeError): + if (err.original == 'Join a voicechannel first.'): + return await send_error_embed('{errors.join_voice_first}') - elif isinstance(err, commands.NoPrivateMessage): - self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) - await ctx.send('That command is not available in DMs') + elif (err.original == 'Not connected.'): + return await send_error_embed('{errors.not_connected}') - elif isinstance(err, commands.CommandOnCooldown): - await ctx.send(f"{ctx.message.author.mention} Command is on cooldown. " - f"Try again in `{err.retry_after:.1f}` seconds.") + elif (err.original == 'I need the `CONNECT` and `SPEAK` permissions.'): + return await send_error_embed('{errors.need_permission}') - elif isinstance(err, RuntimeError): - self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) - pass + elif (err.original == 'You need to be in the right voice channel'): + return await send_error_embed('{errors.right_channel}') - elif isinstance(err, commands.CheckFailure): - self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) - pass + elif (err.original == 'You need to be in my voicechannel.'): + return await send_error_embed('{errors.my_channel}') + + + if isinstance(err, commands.CommandOnCooldown): + await ctx.send(f"{ctx.message.author.mention} Command is on cooldown. " + f"Try again in `{err.retry_after:.1f}` seconds.") + + elif isinstance(err, commands.NoPrivateMessage): + await ctx.send('That command is not available in DMs') - elif isinstance(err, commands.CommandNotFound): - pass else: - tb = err.__traceback__ - traceback.print_tb(tb) - print(err) - self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) + # Log all exceptions if the bot is in debug mode + if self.bot.debug: + tb = err.__traceback__ + traceback.print_tb(tb) + self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) + + else: + to_log = (RuntimeError, commands.CheckFailure, commands.CommandInvokeError, + commands.NoPrivateMessage) + + if isinstance(err, to_log): + self.logger.debug("Error running command: %s\nTraceback: %s" % (ctx.command, err)) def setup(bot): From 3a776eba1487fd467524e858e332ab76271064da Mon Sep 17 00:00:00 2001 From: Ev-1 <33662061+Ev-1@users.noreply.github.com> Date: Thu, 27 Aug 2020 16:22:27 +0200 Subject: [PATCH 9/9] Fix bug in check_leave_voice call This is why statically typed languages are nice sometimes. --- cogs/musicevents.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/cogs/musicevents.py b/cogs/musicevents.py index a5efda4..e7de29c 100644 --- a/cogs/musicevents.py +++ b/cogs/musicevents.py @@ -19,6 +19,8 @@ class MusicEvents(commands.Cog): def __init__(self, bot): self.bot = bot self.leave_timer.start() + self.logger = self.bot.main_logger.bot_logger.getChild("Errors") + # TODO: maybe only load when Music loads if not hasattr(bot, 'lavalink'): # This ensures the client isn't overwritten during cog reloads. bot.lavalink = lavalink.Client(bot.user.id, player=MixPlayer) @@ -83,16 +85,15 @@ class MusicEvents(commands.Cog): await self.connect_to(guild.id, None) async def leave_check(self): - if len(self.bot.lavalink.player_manager.players) != 0: - for player_id in self.bot.lavalink.player_manager.players: - await self.check_leave_voice(player_id) - return - return + for player_id in self.bot.lavalink.player_manager.players: + await self.check_leave_voice(self.bot.get_guild(player_id)) @tasks.loop(seconds=10.0) async def leave_timer(self): - await self.leave_check() - await asyncio.sleep(10) + try: + await self.leave_check() + except Exception as err: + self.logger.debug("Error in leave_timer loop.\nTraceback: %s" % (err)) def setup(bot):