From c00b7d446dd98c3adf7c76992ba3361970b4422c Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 9 Jul 2016 07:57:25 -0500 Subject: [PATCH] Added universal exception handling, removed most exception handling from the commands themselves --- bot.py | 3 + cogs/core.py | 77 ++++++++----------- cogs/interaction.py | 174 ++++++++++++++++++++----------------------- cogs/mod.py | 18 ++--- cogs/owner.py | 78 +++++++------------ cogs/playlist.py | 7 +- cogs/utils/config.py | 6 ++ 7 files changed, 153 insertions(+), 210 deletions(-) diff --git a/bot.py b/bot.py index a5277eb..88fc006 100644 --- a/bot.py +++ b/bot.py @@ -44,6 +44,9 @@ async def on_member_remove(member): @bot.event async def on_command_error(error, ctx): + if isinstance(error,pymysql.OperationalError): + config.resetConnection() + await bot.say("The connection to the MySQL server was lost! Please try your command one more time {}".format(ctx.message.author.mention) fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' await bot.say(fmt.format(type(e).__name__, e)) diff --git a/cogs/core.py b/cogs/core.py index 424cd9a..80a4052 100644 --- a/cogs/core.py +++ b/cogs/core.py @@ -16,13 +16,9 @@ class Core: @commands.command() async def joke(self): """Prints a random riddle""" - try: - fortuneCommand = "/usr/bin/fortune riddles" - fortune = subprocess.check_output(fortuneCommand.split()).decode("utf-8") - await self.bot.say(fortune) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + fortuneCommand = "/usr/bin/fortune riddles" + fortune = subprocess.check_output(fortuneCommand.split()).decode("utf-8") + await self.bot.say(fortune) @commands.command() async def urban(self, *msg: str): @@ -38,55 +34,44 @@ class Core: await self.bot.say(data['list'][0]['definition']) except discord.HTTPException: await self.bot.say('```Error: Definition is too long for me to send```') - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) @commands.command(pass_context=True) async def derpi(self, ctx, *search: str): """Provides a random image from the first page of derpibooru.org for the following term""" - try: - if len(search) > 0: - url = 'https://derpibooru.org/search.json?q=' - query = '+'.join(search) - url += query - if ctx.message.channel.id in config.nsfwChannels: - url += ",+explicit&filter_id=95938" - # url should now be in the form of url?q=search+terms - # Next part processes the json format, and saves the data in useful lists/dictionaries - response = urllib.request.urlopen(url) - data = json.loads(response.read().decode('utf-8')) - results = data['search'] + if len(search) > 0: + url = 'https://derpibooru.org/search.json?q=' + query = '+'.join(search) + url += query + if ctx.message.channel.id in config.nsfwChannels: + url += ",+explicit&filter_id=95938" + # url should now be in the form of url?q=search+terms + # Next part processes the json format, and saves the data in useful lists/dictionaries + response = urllib.request.urlopen(url) + data = json.loads(response.read().decode('utf-8')) + results = data['search'] - if len(results) > 0: - index = random.randint(0, len(results) - 1) - randImageUrl = results[index].get('representations').get('full')[2:] - randImageUrl = 'http://' + randImageUrl - imageLink = randImageUrl.strip() - else: - await self.bot.say("No results with that search term, {0}!".format(ctx.message.author.mention)) - return + if len(results) > 0: + index = random.randint(0, len(results) - 1) + randImageUrl = results[index].get('representations').get('full')[2:] + randImageUrl = 'http://' + randImageUrl + imageLink = randImageUrl.strip() else: - with urllib.request.urlopen('https://derpibooru.org/images/random') as response: - imageLink = response.geturl() - url = 'https://shpro.link/redirect.php/' - data = urllib.parse.urlencode({'link': imageLink}).encode('ascii') - response = urllib.request.urlopen(url, data).read().decode('utf-8') - await self.bot.say(response) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + await self.bot.say("No results with that search term, {0}!".format(ctx.message.author.mention)) + return + else: + with urllib.request.urlopen('https://derpibooru.org/images/random') as response: + imageLink = response.geturl() + url = 'https://shpro.link/redirect.php/' + data = urllib.parse.urlencode({'link': imageLink}).encode('ascii') + response = urllib.request.urlopen(url, data).read().decode('utf-8') + await self.bot.say(response) @commands.command(pass_context=True) async def roll(self, ctx): """Rolls a six sided die""" - try: - num = random.randint(1, 6) - fmt = '{0.message.author.name} has rolled a die and got the number {1}!' - await self.bot.say(fmt.format(ctx, num)) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + num = random.randint(1, 6) + fmt = '{0.message.author.name} has rolled a die and got the number {1}!' + await self.bot.say(fmt.format(ctx, num)) def setup(bot): diff --git a/cogs/interaction.py b/cogs/interaction.py index cc325b2..de895e3 100644 --- a/cogs/interaction.py +++ b/cogs/interaction.py @@ -62,122 +62,106 @@ class Interaction: @commands.command(pass_context=True, no_pm=True) async def battle(self, ctx, player2: discord.Member): """Challenges the mentioned user to a battle""" - try: - global battleP1 - global battleP2 - global battling - if battling: - return - if len(ctx.message.mentions) == 0: - await self.bot.say("You must mention someone in the room " + ctx.message.author.mention + "!") - return - if len(ctx.message.mentions) > 1: - await self.bot.say("You cannot battle more than one person at once!") - return - if ctx.message.author.id == player2.id: - await self.bot.say("Why would you want to battle yourself? Suicide is not the answer") - return - if self.bot.user.id == player2.id: - await self.bot.say("I always win, don't even try it.") - return - fmt = "{0.mention} has challenged you to a battle {1.mention}\n!accept or !decline" - battleP1 = ctx.message.author - battleP2 = player2 - await self.bot.say(fmt.format(ctx.message.author, player2)) - t = Timer(180, battlingOff) - t.start() - battling = True - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + global battleP1 + global battleP2 + global battling + if battling: + return + if len(ctx.message.mentions) == 0: + await self.bot.say("You must mention someone in the room " + ctx.message.author.mention + "!") + return + if len(ctx.message.mentions) > 1: + await self.bot.say("You cannot battle more than one person at once!") + return + if ctx.message.author.id == player2.id: + await self.bot.say("Why would you want to battle yourself? Suicide is not the answer") + return + if self.bot.user.id == player2.id: + await self.bot.say("I always win, don't even try it.") + return + fmt = "{0.mention} has challenged you to a battle {1.mention}\n!accept or !decline" + battleP1 = ctx.message.author + battleP2 = player2 + await self.bot.say(fmt.format(ctx.message.author, player2)) + t = Timer(180, battlingOff) + t.start() + battling = True @commands.command(no_pm=True) @checks.battled(battleP2) async def accept(self): """Accepts the battle challenge""" - try: - if not battling: - return - num = random.randint(1, 100) - fmt = config.battleWins[random.randint(0, len(config.battleWins) - 1)] - if num <= 50: - await self.bot.say(fmt.format(battleP1.mention, battleP2.mention)) - updateBattleRecords(battleP1, battleP2) - elif num > 50: - await self.bot.say(fmt.format(battleP2.mention, battleP1.mention)) - updateBattleRecords(battleP2, battleP1) - battlingOff() - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) - + if not battling: + return + num = random.randint(1, 100) + fmt = config.battleWins[random.randint(0, len(config.battleWins) - 1)] + if num <= 50: + await self.bot.say(fmt.format(battleP1.mention, battleP2.mention)) + updateBattleRecords(battleP1, battleP2) + elif num > 50: + await self.bot.say(fmt.format(battleP2.mention, battleP1.mention)) + updateBattleRecords(battleP2, battleP1) + battlingOff() + @commands.command(no_pm=True) @checks.battled(battleP2) async def decline(self): """Declines the battle challenge""" - try: - if not battling: - return - await self.bot.say("{0} has chickened out! {1} wins by default!".format(battleP2.mention, battleP1.mention)) - updateBattleRecords(battleP1, battleP2) - battlingOff() - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + if not battling: + return + await self.bot.say("{0} has chickened out! {1} wins by default!".format(battleP2.mention, battleP1.mention)) + updateBattleRecords(battleP1, battleP2) + battlingOff() @commands.command(pass_context=True, no_pm=True) async def boop(self, ctx, boopee: discord.Member): """Boops the mentioned person""" - try: - booper = ctx.message.author - if len(ctx.message.mentions) == 0: - await self.bot.say("You must mention someone in the room " + ctx.message.author.mention + "!") - return - if len(ctx.message.mentions) > 1: - await self.bot.say("You cannot boop more than one person at once!") - return - if boopee.id == booper.id: - await self.bot.say("You can't boop yourself! Silly...") - return - if boopee.id == self.bot.user.id: - await self.bot.say("Why the heck are you booping me? Get away from me >:c") - return + booper = ctx.message.author + if len(ctx.message.mentions) == 0: + await self.bot.say("You must mention someone in the room " + ctx.message.author.mention + "!") + return + if len(ctx.message.mentions) > 1: + await self.bot.say("You cannot boop more than one person at once!") + return + if boopee.id == booper.id: + await self.bot.say("You can't boop yourself! Silly...") + return + if boopee.id == self.bot.user.id: + await self.bot.say("Why the heck are you booping me? Get away from me >:c") + return - cursor = config.connection.cursor() - cursor.execute('use {0}'.format(config.db_boops)) - sql = "show tables like '" + str(booper.id) + "'" + cursor = config.connection.cursor() + cursor.execute('use {0}'.format(config.db_boops)) + sql = "show tables like '" + str(booper.id) + "'" + cursor.execute(sql) + result = cursor.fetchone() + amount = 1 + # Booper's table exists, continue + if result is not None: + sql = "select `amount` from `" + booper.id + "` where id='" + str(boopee.id) + "'" cursor.execute(sql) result = cursor.fetchone() - amount = 1 - # Booper's table exists, continue + # Boopee's entry exists, continue if result is not None: - sql = "select `amount` from `" + booper.id + "` where id='" + str(boopee.id) + "'" + amount = result.get('amount') + 1 + sql = "update `" + str(booper.id) + "` set amount = " + str(amount) + " where id=" + str( + boopee.id) cursor.execute(sql) - result = cursor.fetchone() - # Boopee's entry exists, continue - if result is not None: - amount = result.get('amount') + 1 - sql = "update `" + str(booper.id) + "` set amount = " + str(amount) + " where id=" + str( - boopee.id) - cursor.execute(sql) - # Boopee does not exist, need to create the field for it - else: - sql = "insert into `" + str(booper.id) + "` (id,amount) values ('" + str(boopee.id) + "',1)" - cursor.execute(sql) - # Booper's table does not exist, need to create the table + # Boopee does not exist, need to create the field for it else: - sql = "create table `" + str(booper.id) + \ - "` (`id` varchar(255) not null,`amount` int(11) not null" + \ - ",primary key (`id`)) engine=InnoDB default charset=utf8 collate=utf8_bin" - cursor.execute(sql) sql = "insert into `" + str(booper.id) + "` (id,amount) values ('" + str(boopee.id) + "',1)" cursor.execute(sql) - fmt = "{0.mention} has just booped you {1.mention}! That's {2} times now!" - await self.bot.say(fmt.format(booper, boopee, amount)) - config.connection.commit() - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + # Booper's table does not exist, need to create the table + else: + sql = "create table `" + str(booper.id) + \ + "` (`id` varchar(255) not null,`amount` int(11) not null" + \ + ",primary key (`id`)) engine=InnoDB default charset=utf8 collate=utf8_bin" + cursor.execute(sql) + sql = "insert into `" + str(booper.id) + "` (id,amount) values ('" + str(boopee.id) + "',1)" + cursor.execute(sql) + fmt = "{0.mention} has just booped you {1.mention}! That's {2} times now!" + await self.bot.say(fmt.format(booper, boopee, amount)) + config.connection.commit() def setup(bot): diff --git a/cogs/mod.py b/cogs/mod.py index 4501cb7..273aa88 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -11,24 +11,16 @@ class Mod: @checks.isAdmin() async def leave(self, ctx): """Forces the bot to leave the server""" - try: - await self.bot.say('Why must I leave? Hopefully I can come back :c') - await self.bot.leave_server(ctx.message.server) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + await self.bot.say('Why must I leave? Hopefully I can come back :c') + await self.bot.leave_server(ctx.message.server) @commands.command(pass_context=True) @checks.isMod() async def say(self, ctx, *msg: str): """Tells the bot to repeat what you say""" - try: - msg = ' '.join(msg) - await self.bot.say(msg) - await self.bot.delete_message(ctx.message) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + msg = ' '.join(msg) + await self.bot.say(msg) + await self.bot.delete_message(ctx.message) def setup(bot): diff --git a/cogs/owner.py b/cogs/owner.py index ac2c245..77efb06 100644 --- a/cogs/owner.py +++ b/cogs/owner.py @@ -19,7 +19,6 @@ class Owner: @checks.isOwner() async def restart(self, ctx): """Forces the bot to restart""" - try: cursor = config.connection.cursor() cursor.execute('use {0}'.format(config.db_default)) sql = "update restart_server set channel_id={0} where id=1".format(ctx.message.channel.id) @@ -28,83 +27,60 @@ class Owner: await self.bot.say("Restarting; see you in the next life {0}!".format(ctx.message.author.mention)) python = sys.executable os.execl(python, python, *sys.argv) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) @commands.command(pass_context=True) @checks.isOwner() async def py(self, ctx): """Executes code""" - try: - match_single = getter.findall(ctx.message.content) - match_multi = multi.findall(ctx.message.content) - if not match_single and not match_multi: - return + match_single = getter.findall(ctx.message.content) + match_multi = multi.findall(ctx.message.content) + if not match_single and not match_multi: + return + else: + if not match_multi: + result = eval(match_single[0]) + await self.bot.say("```{0}```".format(result)) else: - if not match_multi: - result = eval(match_single[0]) - await self.bot.say("```{0}```".format(result)) - else: - def r(v): - config.loop.create_task(self.bot.say("```{0}```".format(v))) + def r(v): + config.loop.create_task(self.bot.say("```{0}```".format(v))) - exec(match_multi[0]) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + exec(match_multi[0]) @commands.command(pass_context=True) @checks.isOwner() async def shutdown(self, ctx): """Shuts the bot down""" - try: - fmt = 'Shutting down, I will miss you {0.author.name}' - await self.bot.say(fmt.format(ctx.message)) - await self.bot.logout() - await self.bot.close() - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + fmt = 'Shutting down, I will miss you {0.author.name}' + await self.bot.say(fmt.format(ctx.message)) + await self.bot.logout() + await self.bot.close() @commands.command() @checks.isOwner() async def avatar(self, content: str): """Changes the avatar for the bot to the filename following the command""" - try: - file = '/home/phxntx5/public_html/bot/images/' + content - with open(file, 'rb') as fp: - await self.bot.edit_profile(avatar=fp.read()) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + file = '/home/phxntx5/public_html/bot/images/' + content + with open(file, 'rb') as fp: + await self.bot.edit_profile(avatar=fp.read()) @commands.command() @checks.isOwner() async def name(self, newNick: str): """Changes the bot's name""" - try: - await self.bot.edit_profile(username=newNick) - await self.bot.say('Changed username to ' + newNick) - # Restart the bot after this, as profile changes are not immediate - python = sys.executable - os.execl(python, python, *sys.argv) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + await self.bot.edit_profile(username=newNick) + await self.bot.say('Changed username to ' + newNick) + # Restart the bot after this, as profile changes are not immediate + python = sys.executable + os.execl(python, python, *sys.argv) @commands.command() @checks.isOwner() async def status(self, *stat: str): """Changes the bot's 'playing' status""" - try: - newStatus = ' '.join(stat) - game = discord.Game(name=newStatus, type=0) - await self.bot.change_status(game) - await self.bot.say("Just changed my status to '{0}'!".format(newStatus)) - except Exception as e: - fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```' - await self.bot.say(fmt.format(type(e).__name__, e)) + newStatus = ' '.join(stat) + game = discord.Game(name=newStatus, type=0) + await self.bot.change_status(game) + await self.bot.say("Just changed my status to '{0}'!".format(newStatus)) def setup(bot): diff --git a/cogs/playlist.py b/cogs/playlist.py index d27ee06..f76ac55 100644 --- a/cogs/playlist.py +++ b/cogs/playlist.py @@ -198,11 +198,8 @@ class Music: @commands.command(pass_context=True, no_pm=True) async def queuelength(self, ctx): """Prints the length of the queue""" - try: - await self.bot.say("There are a total of {} songs in the queue" - .format(str(self.get_voice_state(ctx.message.server).songs.qsize()))) - except: - await self.bot.say(traceback.format_exc()) + await self.bot.say("There are a total of {} songs in the queue" + .format(str(self.get_voice_state(ctx.message.server).songs.qsize()))) @commands.command(pass_context=True, no_pm=True) async def skip(self, ctx): diff --git a/cogs/utils/config.py b/cogs/utils/config.py index fcbddcc..edc2400 100644 --- a/cogs/utils/config.py +++ b/cogs/utils/config.py @@ -27,3 +27,9 @@ adminCommands = global_config.get("adminCommands", {}) openCommands = global_config.get("openCommands", {}) ownerCommands = global_config.get("ownerCommands", {}) voiceCommands = global_config.get("voiceCommands", {}) + +def resetConnection() + global connection + connection = pymysql.connect(host=global_config.get("db_host"), user=global_config.get("db_user"), + password=global_config.get("db_user_pass"), charset='utf8mb4', + cursorclass=pymysql.cursors.DictCursor)