From 2728c7c6d7f4424b91cf567ae87f7cd970d56fbf Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 06:58:01 -0500 Subject: [PATCH 01/22] Custom permissions has been changed to save the value instead --- cogs/mod.py | 61 ++++++++++++++++++++++---------------------- cogs/utils/checks.py | 20 +++++++++++++++ 2 files changed, 51 insertions(+), 30 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index bfb1841..ac8e2a7 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -88,52 +88,55 @@ class Mod: If you want to open the command to everyone, provide 'none' as the permission""" command = " ".join(msg[0:len(msg) - 1]) permissions = msg[len(msg) - 1] + + #If a user can run the command, they have to have send_messages permissions; so use this as the base if permissions.lower() == "none": permissions = "send_messages" - msg = msg[0:len(msg) - 1] - count = 0 - cmd = self.bot.commands.get(msg[count]) - while isinstance(cmd, commands.Group): - count += 1 + + #Convert the string to an int value of the permissions obj, based on the required permission + perm_obj = discord.Permissions.none() + setattr(perm_obj,permissions,True) + perm_value = perm_obj.value + + cmd = None + for part in permissions: try: - cmd = cmd.commands.get(msg[count]) - except: + if cmd is None: + cmd = self.bot.commands.get(part) + else: + cmd = cmd.commands.get(part) + except AttributeError: break + + if cmd is None: + await self.bot.say("That command does not exist! You can't have custom permissions on a non-existant command....") + return for check in cmd.checks: if "isOwner" == check.__name__ or re.search("has_permissions", str(check)) is not None: await self.bot.say("This command cannot have custom permissions setup!") return - if getattr(discord.Permissions, permissions, None) is None and not permissions.lower() == "none": + if getattr(discord.Permissions, permissions, None) is None: await self.bot.say("{} does not appear to be a valid permission! Valid permissions are: ```{}```" .format(permissions, "\n".join(valid_perms))) return - custom_perms = config.getContent('custom_permissions') - if custom_perms is None: - custom_perms = {} - server_perms = custom_perms.get(ctx.message.server.id) - if server_perms is None: - custom_perms[ctx.message.server.id] = {command: permissions} - else: - server_perms[command] = permissions - custom_perms[ctx.message.server.id] = server_perms - if config.saveContent('custom_permissions', custom_perms): - await self.bot.say("I have just added your custom permissions; " - "you now need to have `{}` permissions to use the command `{}`".format(permissions, command)) - else: - await self.bot.say("I was unable to save this data") + custom_perms = config.getContent('custom_permissions') or {} + server_perms = custom_perms.get(ctx.message.server.id) or {} + server_perms[command] = perm_value + custom_perms[ctx.message.server.id] = server_perms + + config.saveContent('custom_permissions', custom_perms) + await self.bot.say("I have just added your custom permissions; " + "you now need to have `{}` permissions to use the command `{}`".format(permissions, command)) @perms.command(name="remove", aliases=["delete"], pass_context=True, no_pm=True) @commands.has_permissions(manage_server=True) async def remove_perms(self, ctx, *command: str): """Removes the custom permissions setup on the command specified""" cmd = " ".join(command) - custom_perms = config.getContent('custom_permissions') - if custom_perms is None: - await self.bot.say("You do not have custom permissions setup on this server yet!") - return + custom_perms = config.getContent('custom_permissions') or {} server_perms = custom_perms.get(ctx.message.server.id) if server_perms is None: await self.bot.say("There are no custom permissions setup on this server yet!") @@ -143,10 +146,8 @@ class Mod: await self.bot.say("You do not have custom permissions setup on this command yet!") return del custom_perms[ctx.message.server.id][cmd] - if config.saveContent('custom_permissions', custom_perms): - await self.bot.say("I have just removed the custom permissions for {}!".format(cmd)) - else: - await self.bot.say("I was unable to save this data") + config.saveContent('custom_permissions', custom_perms) + await self.bot.say("I have just removed the custom permissions for {}!".format(cmd)) def setup(bot): diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index 0e50508..445d5b1 100644 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -1,4 +1,5 @@ from discord.ext import commands +import discord from . import config @@ -23,6 +24,25 @@ def customPermsOrRole(perm): return getattr(ctx.message.author.permissions_in(ctx.message.channel), _perm) return commands.check(predicate) + +def customPermsOrRole(**perms): + def predicate(ctx): + if ctx.message.channel.is_private: + return False + + member_perms = ctx.message.author.permissions_in(ctx.message.channel) + default_perms = discord.Permissions.none() + for perm,setting in perms.items(): + setattr(default_perms,perm,setting) + + try: + required_perm = config.getContent('custom_permissions')[ctx.message.server.id][ctx.command.qualified_name] + except KeyError: + required_perm = default_perms + return member_perms >= required_perm + + + return commands.check(predicate) def isPM(): From 70be37b770242115375b892b524b19c1ce8e3ea4 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 07:30:28 -0500 Subject: [PATCH 02/22] Changed the checks on all commands to use the revised custom format --- cogs/core.py | 10 +++++----- cogs/interaction.py | 12 ++++++------ cogs/links.py | 6 +++--- cogs/mod.py | 10 +++++----- cogs/overwatch.py | 6 +++--- cogs/playlist.py | 22 +++++++++++----------- cogs/stats.py | 8 ++++---- cogs/tags.py | 8 ++++---- cogs/twitch.py | 12 ++++++------ 9 files changed, 47 insertions(+), 47 deletions(-) diff --git a/cogs/core.py b/cogs/core.py index 9bc7236..f799a14 100644 --- a/cogs/core.py +++ b/cogs/core.py @@ -21,7 +21,7 @@ class Core: await self.bot.say((await self.bot.application_info()).id) @commands.command() - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def calendar(self, month: str=None, year: int=None): """Provides a printout of the current month's calendar Provide month and year to print the calendar of that year and month""" @@ -52,7 +52,7 @@ class Core: await self.bot.say("```{}```".format(cal)) @commands.command() - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def addbot(self): """Provides a link that you can use to add me to a server""" perms = discord.Permissions.none() @@ -69,7 +69,7 @@ class Core: .format(discord.utils.oauth_url('183748889814237186', perms))) @commands.command(pass_context=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def doggo(self, ctx): """Use this to print a random doggo image. Doggo is love, doggo is life.""" @@ -79,7 +79,7 @@ class Core: await self.bot.upload(f) @commands.command() - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def joke(self): """Prints a random riddle""" fortuneCommand = "/usr/bin/fortune riddles" @@ -88,7 +88,7 @@ class Core: @commands.command(pass_context=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def roll(self, ctx, notation: str="d6"): """Rolls a die based on the notation given Format should be #d#""" diff --git a/cogs/interaction.py b/cogs/interaction.py index 685a32f..7c5e261 100644 --- a/cogs/interaction.py +++ b/cogs/interaction.py @@ -18,10 +18,10 @@ def userBattling(ctx): battling = config.getContent('battling') if battling is None: return False - if ctx.message.author.id in battling or ctx.message.author.id in battling.values(): + if ctx.message.author.id in battling.values() or ctx.message.author.id in battling.keys(): return True if str(ctx.command) == 'battle': - return ctx.message.mentions[0].id in battling.values() + return ctx.message.mentions[0].id in battling.values() or ctx.message.mentions[0].id in battling.keys(): return False @@ -75,7 +75,7 @@ class Interaction: self.bot = bot @commands.group(pass_context=True, no_pm=True,invoke_without_command=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def battle(self, ctx, player2: discord.Member): """Challenges the mentioned user to a battle""" if len(ctx.message.mentions) == 0: @@ -105,7 +105,7 @@ class Interaction: @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def accept(self, ctx): """Accepts the battle challenge""" if not userBattling(ctx): @@ -134,7 +134,7 @@ class Interaction: battlingOff(ctx.message.author.id) @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def decline(self, ctx): """Declines the battle challenge""" if not userBattling(ctx): @@ -156,7 +156,7 @@ class Interaction: @commands.command(pass_context=True, no_pm=True) @commands.cooldown(1,180,BucketType.user) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def boop(self, ctx, boopee: discord.Member): """Boops the mentioned person""" booper = ctx.message.author diff --git a/cogs/links.py b/cogs/links.py index 027e951..a0f8886 100644 --- a/cogs/links.py +++ b/cogs/links.py @@ -13,7 +13,7 @@ class Links: self.bot = bot @commands.command() - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def urban(self, *msg: str): """Pulls the top urbandictionary.com definition for a term""" url = "http://api.urbandictionary.com/v0/define?term={}".format('+'.join(msg)) @@ -31,7 +31,7 @@ class Links: await self.bot.say('```Error: Definition is too long for me to send```') @commands.command(pass_context=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def derpi(self, ctx, *search: str): """Provides a random image from the first page of derpibooru.org for the following term""" if len(search) > 0: @@ -64,7 +64,7 @@ class Links: @commands.command(pass_context=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def e621(self, ctx, *, tags: str): """Searches for a random image from e621.net Format for the search terms need to be 'search term 1, search term 2, etc.' diff --git a/cogs/mod.py b/cogs/mod.py index ac8e2a7..d6ca482 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -20,7 +20,7 @@ class Mod: await self.bot.say('Invalid subcommand passed: {0.subcommand_passed}'.format(ctx)) @nsfw.command(name="add", pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def nsfw_add(self, ctx): """Registers this channel as a 'nsfw' channel""" nsfw_channels = config.getContent('nsfw_channels') @@ -32,7 +32,7 @@ class Mod: await self.bot.say("This channel has just been registered as 'nsfw'! Have fun you naughties ;)") @nsfw.command(name="remove", aliases=["delete"], pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def nsfw_remove(self, ctx): """Removes this channel as a 'nsfw' channel""" nsfw_channels = config.getContent('nsfw_channels') @@ -44,21 +44,21 @@ class Mod: await self.bot.say("This channel has just been unregistered as a nsfw channel") @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("manage_server") + @checks.customPermsOrRole(manage_server=True) async def leave(self, ctx): """Forces the bot to leave the server""" 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, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def say(self, ctx, *, msg: str): """Tells the bot to repeat what you say""" await self.bot.say(msg) await self.bot.delete_message(ctx.message) @commands.group(pass_context=True, invoke_without_command=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def perms(self, ctx, *, command: str): """This command can be used to print the current allowed permissions on a specific command This supports groups as well as subcommands; pass no argument to print a list of available permissions""" diff --git a/cogs/overwatch.py b/cogs/overwatch.py index fd777ee..80aec4c 100644 --- a/cogs/overwatch.py +++ b/cogs/overwatch.py @@ -28,7 +28,7 @@ class Overwatch: pass @ow.command(name="stats", pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def ow_stats(self, ctx, user: discord.Member = None, hero: str = ""): """Prints out a basic overview of a member's stats Provide a hero after the member to get stats for that specific hero""" @@ -74,7 +74,7 @@ class Overwatch: .format(user.name, hero.title(), fmt.title().replace("_", " "))) @ow.command(pass_context=True, name="add", no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def add(self, ctx, bt: str): """Saves your battletag for looking up information""" bt = bt.replace("#", "-") @@ -96,7 +96,7 @@ class Overwatch: await self.bot.say("I was unable to save this data") @ow.command(pass_context=True, name="delete", aliases=['remove'], no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def delete(self, ctx): """Removes your battletag from the records""" result = config.getContent('overwatch') diff --git a/cogs/playlist.py b/cogs/playlist.py index 1143b36..1a1ae12 100644 --- a/cogs/playlist.py +++ b/cogs/playlist.py @@ -97,7 +97,7 @@ class Music: pass @commands.command(no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def join(self, *, channel: discord.Channel): """Joins a voice channel.""" try: @@ -113,7 +113,7 @@ class Music: await self.bot.say('Ready to play audio in ' + channel.name) @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def summon(self, ctx): """Summons the bot to join your voice channel.""" summoned_channel = ctx.message.author.voice_channel @@ -129,7 +129,7 @@ class Music: return True @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def play(self, ctx, *, song: str): """Plays a song. If there is a song currently in the queue, then it is @@ -156,7 +156,7 @@ class Music: await state.songs.put(entry) @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def volume(self, ctx, value: int): """Sets the volume of the currently playing song.""" @@ -167,7 +167,7 @@ class Music: await self.bot.say('Set the volume to {:.0%}'.format(player.volume)) @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def pause(self, ctx): """Pauses the currently played song.""" state = self.get_voice_state(ctx.message.server) @@ -176,7 +176,7 @@ class Music: player.pause() @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def resume(self, ctx): """Resumes the currently played song.""" state = self.get_voice_state(ctx.message.server) @@ -185,7 +185,7 @@ class Music: player.resume() @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def stop(self, ctx): """Stops playing audio and leaves the voice channel. This also clears the queue. @@ -205,14 +205,14 @@ class Music: pass @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def queuelength(self, ctx): """Prints the length of the queue""" 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) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def skip(self, ctx): """Vote to skip a song. The song requester can automatically skip. 3 skip votes are needed for the song to be skipped. @@ -239,7 +239,7 @@ class Music: await self.bot.say('You have already voted to skip this song.') @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def modskip(self, ctx): """Forces a song skip, can only be used by a moderator""" state = self.get_voice_state(ctx.message.server) @@ -251,7 +251,7 @@ class Music: await self.bot.say('Song has just been skipped.') @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def playing(self, ctx): """Shows info about the currently played song.""" diff --git a/cogs/stats.py b/cogs/stats.py index 5f73687..1e057f0 100644 --- a/cogs/stats.py +++ b/cogs/stats.py @@ -13,7 +13,7 @@ class Stats: self.bot = bot @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def mostboops(self, ctx): """Shows the person you have 'booped' the most, as well as how many times""" boops = config.getContent('boops') @@ -33,7 +33,7 @@ class Stats: ctx.message.author.mention, member.mention, most_boops)) @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def listboops(self, ctx): """Lists all the users you have booped and the amount of times""" members = ctx.message.server.members @@ -50,7 +50,7 @@ class Stats: await self.bot.say("You have booped:```{}```".format(output)) @commands.command(pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def leaderboard(self, ctx): """Prints a leaderboard of everyone in the server's battling record""" battles = config.getContent('battle_records') @@ -71,7 +71,7 @@ class Stats: @commands.command(pass_context=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def stats(self, ctx, member: discord.Member=None): """Prints the battling stats for you, or the user provided""" member = member or ctx.message.author diff --git a/cogs/tags.py b/cogs/tags.py index 77ae258..7100e06 100644 --- a/cogs/tags.py +++ b/cogs/tags.py @@ -9,7 +9,7 @@ class Tags: self.bot = bot @commands.command(pass_context=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def tags(self, ctx): """Prints all the custom tags that this server currently has""" tags = config.getContent('tags') @@ -17,7 +17,7 @@ class Tags: await self.bot.say('```{}```'.format(fmt)) @commands.group(pass_context=True, invoke_without_command=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def tag(self, ctx, *, tag: str): """This can be used to call custom tags The format to call a custom tag is !tag """ @@ -29,7 +29,7 @@ class Tags: await self.bot.say("{}".format(result[0]['result'])) @tag.command(name='add', aliases=['create', 'start'], pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def add_tag(self, ctx, *, result: str): """Use this to add a new tag that can be used in this server Format to add a tag is !tag add - """ @@ -54,7 +54,7 @@ class Tags: await self.bot.say("I was unable to save this data") @tag.command(name='delete', aliases=['remove', 'stop'], pass_context=True, no_pm=True) - @checks.customPermsOrRole("kick_members") + @checks.customPermsOrRole(kick_members=True) async def del_tag(self, ctx, *, tag: str): """Use this to remove a tag that from use for this server Format to delete a tag is !tag delete """ diff --git a/cogs/twitch.py b/cogs/twitch.py index cdbb662..648329c 100644 --- a/cogs/twitch.py +++ b/cogs/twitch.py @@ -52,7 +52,7 @@ class Twitch: await asyncio.sleep(30) @commands.group(no_pm=True, invoke_without_command=True, pass_context=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def twitch(self, ctx, *, member: discord.Member=None): """Use this command to check the twitch info of a user""" if member is None: @@ -78,7 +78,7 @@ class Twitch: await self.bot.say("```{}```".format(fmt)) @twitch.command(name='add', pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def add_twitch_url(self, ctx, url: str): """Saves your user's twitch URL""" try: @@ -107,7 +107,7 @@ class Twitch: await self.bot.say("I have just saved your twitch url {}".format(ctx.message.author.mention)) @twitch.command(name='remove', aliases=['delete'], pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def remove_twitch_url(self, ctx): """Removes your twitch URL""" twitch = config.getContent('twitch') @@ -121,13 +121,13 @@ class Twitch: ctx.message.author.mention)) @twitch.group(pass_context=True, no_pm=True, invoke_without_command=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def notify(self, ctx): """This can be used to turn notifications on or off""" pass @notify.command(name='on', aliases=['start,yes'], pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def notify_on(self, ctx): """Turns twitch notifications on""" twitch = config.getContent('twitch') @@ -146,7 +146,7 @@ class Twitch: ctx.message.author.mention)) @notify.command(name='off', aliases=['stop,no'], pass_context=True, no_pm=True) - @checks.customPermsOrRole("send_messages") + @checks.customPermsOrRole(send_messages=True) async def notify_off(self, ctx): """Turns twitch notifications off""" twitch = config.getContent('twitch') From acdab526a9366e9b20841c5e4b89ad6fcb29fcb8 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 07:31:55 -0500 Subject: [PATCH 03/22] corrected syntax error --- cogs/interaction.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/interaction.py b/cogs/interaction.py index 7c5e261..7f9bca7 100644 --- a/cogs/interaction.py +++ b/cogs/interaction.py @@ -21,7 +21,7 @@ def userBattling(ctx): if ctx.message.author.id in battling.values() or ctx.message.author.id in battling.keys(): return True if str(ctx.command) == 'battle': - return ctx.message.mentions[0].id in battling.values() or ctx.message.mentions[0].id in battling.keys(): + return ctx.message.mentions[0].id in battling.values() or ctx.message.mentions[0].id in battling.keys() return False From ad6fdac4d122c8aa1347170bd867a89729d1249e Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 07:39:10 -0500 Subject: [PATCH 04/22] corrected syntax error --- cogs/mod.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/mod.py b/cogs/mod.py index d6ca482..0c126c2 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -99,7 +99,7 @@ class Mod: perm_value = perm_obj.value cmd = None - for part in permissions: + for part in msg[0:len(msg) - 1]: try: if cmd is None: cmd = self.bot.commands.get(part) From d544e711041cd63bfbcf9b351a0122078ce2d25b Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 07:44:43 -0500 Subject: [PATCH 05/22] Printing the command in permissions checking, as it seems to be failing. --- cogs/mod.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/mod.py b/cogs/mod.py index 0c126c2..09ab6bd 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -65,7 +65,6 @@ class Mod: if command is None or len(command) == 0: await self.bot.say("Valid permissions are: ```{}```".format("\n".join("{}".format(i) for i in valid_perms))) return - command = " ".join(command) custom_perms = config.getContent('custom_permissions') or {} server_perms = custom_perms.get(ctx.message.server.id) @@ -74,6 +73,7 @@ class Mod: return command_perms = server_perms.get(command) + await self.bot.say("`{}` is type `{}`".format(command,type(command))) if command_perms is None: await self.bot.say("That command has no custom permissions setup on it!") else: From 06caedb4a4830b4476614397d15c08e899246a05 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 07:55:26 -0500 Subject: [PATCH 06/22] Corrected the permissions printing, to show the actual permission instead of the value --- cogs/mod.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index 09ab6bd..7b947be 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -72,13 +72,14 @@ class Mod: await self.bot.say("There are no custom permissions setup on this server yet!") return - command_perms = server_perms.get(command) - await self.bot.say("`{}` is type `{}`".format(command,type(command))) - if command_perms is None: + perms_value = server_perms.get(command) + if perms_value is None: await self.bot.say("That command has no custom permissions setup on it!") else: + permissions = discord.Permissions(perms_value) + needed_perm = [perm[0] for perm in permissions._perm_iterator() if perm[1]][0] await self.bot.say("You need to have the permission `{}` " - "to use the command `{}` in this server".format(command_perms, command)) + "to use the command `{}` in this server".format(needed_perm, command)) @perms.command(name="add", aliases=["setup,create"], pass_context=True, no_pm=True) @commands.has_permissions(manage_server=True) From a4b9ce01e87239c13115f58db9bf03d43c97b3e8 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 09:17:18 -0500 Subject: [PATCH 07/22] Added a cooldown to battling --- cogs/interaction.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/interaction.py b/cogs/interaction.py index 7f9bca7..61420ee 100644 --- a/cogs/interaction.py +++ b/cogs/interaction.py @@ -75,6 +75,7 @@ class Interaction: self.bot = bot @commands.group(pass_context=True, no_pm=True,invoke_without_command=True) + @commands.cooldown(1,180,BucketType.user) @checks.customPermsOrRole(send_messages=True) async def battle(self, ctx, player2: discord.Member): """Challenges the mentioned user to a battle""" From 6983cf8d6bb7eb7000a0ac19b5dcacad288ee321 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 09:59:35 -0500 Subject: [PATCH 08/22] Added an uptime command to the bot --- bot.py | 10 ++++++++++ cogs/core.py | 22 +++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/bot.py b/bot.py index ca4bd46..e845748 100644 --- a/bot.py +++ b/bot.py @@ -2,6 +2,8 @@ import discord import traceback +import logging +import datetime from discord.ext import commands from cogs.utils import config @@ -17,7 +19,13 @@ extensions = ['cogs.interaction', 'cogs.tags'] bot = commands.Bot(command_prefix=config.commandPrefix, description=config.botDescription, pm_help=None) +discord_logger = logging.getLogger('discord') +discord_logger.setLevel(logging.WARNING) +log = logging.getLogger() +log.setLevel(logging.INFO) +handler = logging.FileHandler(filename='bonfire.log', encoding='utf-8', mode='a') +log.addHandler(handler) # Bot event overrides @bot.event @@ -29,6 +37,8 @@ async def on_ready(): destination = discord.utils.find(lambda m: m.id == channel_id, bot.get_all_channels()) await bot.send_message(destination, "I have just finished restarting!") config.saveContent('restart_server', 0) + if not hasattr(bot, 'uptime'): + bot.uptime = datetime.datetime.utcnow() @bot.event diff --git a/cogs/core.py b/cogs/core.py index f799a14..154df47 100644 --- a/cogs/core.py +++ b/cogs/core.py @@ -16,9 +16,19 @@ class Core: def __init__(self, bot): self.bot = bot - @commands.command() - async def test(self): - await self.bot.say((await self.bot.application_info()).id) + + def get_bot_uptime(self): + now = datetime.datetime.utcnow() + delta = now - self.bot.uptime + hours, remainder = divmod(int(delta.total_seconds()), 3600) + minutes, seconds = divmod(remainder, 60) + days, hours = divmod(hours, 24) + if days: + fmt = '{d} days, {h} hours, {m} minutes, and {s} seconds' + else: + fmt = '{h} hours, {m} minutes, and {s} seconds' + + return fmt.format(d=days, h=hours, m=minutes, s=seconds) @commands.command() @checks.customPermsOrRole(send_messages=True) @@ -50,6 +60,12 @@ class Core: year = datetime.datetime.today().year cal = calendar.TextCalendar().formatmonth(year, month) await self.bot.say("```{}```".format(cal)) + + @commands.command() + @checks.customPermsOrRole(send_messages=True) + async def uptime(self): + """Provides a printout of the current bot's uptime""" + awayt self.bot.say("Uptime = ```{}```".format(get_bot_uptime())) @commands.command() @checks.customPermsOrRole(send_messages=True) From 945e3ef8784e6dc8cadff05347753f7804ca0a8e Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 10:00:51 -0500 Subject: [PATCH 09/22] corrected syntax error --- cogs/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/core.py b/cogs/core.py index 154df47..b6501b0 100644 --- a/cogs/core.py +++ b/cogs/core.py @@ -65,7 +65,7 @@ class Core: @checks.customPermsOrRole(send_messages=True) async def uptime(self): """Provides a printout of the current bot's uptime""" - awayt self.bot.say("Uptime = ```{}```".format(get_bot_uptime())) + await self.bot.say("Uptime = ```{}```".format(get_bot_uptime())) @commands.command() @checks.customPermsOrRole(send_messages=True) From c29b9f6aeadd71e1790cf3b86fff3e3596ff655c Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 10:01:48 -0500 Subject: [PATCH 10/22] corrected syntax error --- cogs/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/core.py b/cogs/core.py index b6501b0..05956cf 100644 --- a/cogs/core.py +++ b/cogs/core.py @@ -65,7 +65,7 @@ class Core: @checks.customPermsOrRole(send_messages=True) async def uptime(self): """Provides a printout of the current bot's uptime""" - await self.bot.say("Uptime = ```{}```".format(get_bot_uptime())) + await self.bot.say("Uptime = ```{}```".format(self.get_bot_uptime())) @commands.command() @checks.customPermsOrRole(send_messages=True) From 226b47453e96db7cb071481f0fb4502595f59d9a Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 12:25:01 -0500 Subject: [PATCH 11/22] corrected the detection of when the songs' queue is full --- cogs/core.py | 2 +- cogs/playlist.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/core.py b/cogs/core.py index 05956cf..4ab0cbc 100644 --- a/cogs/core.py +++ b/cogs/core.py @@ -65,7 +65,7 @@ class Core: @checks.customPermsOrRole(send_messages=True) async def uptime(self): """Provides a printout of the current bot's uptime""" - await self.bot.say("Uptime = ```{}```".format(self.get_bot_uptime())) + await self.bot.say("Uptime: ```{}```".format(self.get_bot_uptime())) @commands.command() @checks.customPermsOrRole(send_messages=True) diff --git a/cogs/playlist.py b/cogs/playlist.py index 1a1ae12..66310ef 100644 --- a/cogs/playlist.py +++ b/cogs/playlist.py @@ -27,7 +27,7 @@ class VoiceState: self.voice = None self.bot = bot self.play_next_song = asyncio.Event() - self.songs = asyncio.Queue() + self.songs = asyncio.Queue(maxsize=10) self.skip_votes = set() # a set of user_ids that voted self.audio_player = self.bot.loop.create_task(self.audio_player_task()) self.opts = { From d854362304551c2a0c15e4bbf434a48539f6baaf Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 12:28:53 -0500 Subject: [PATCH 12/22] corrected the detection of when the songs' queue is full --- cogs/playlist.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/playlist.py b/cogs/playlist.py index 66310ef..eab38bf 100644 --- a/cogs/playlist.py +++ b/cogs/playlist.py @@ -145,7 +145,7 @@ class Music: if not success: return - if len(state.songs) >= self.max_songs: + if state.songs.full(): await self.bot.say("The queue is currently full! You'll need to wait to add a new song") return From 04a9ce1ce1163d8a5c428105daae4356090dff36 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:11:42 -0500 Subject: [PATCH 13/22] removed not used variable --- cogs/playlist.py | 1 - 1 file changed, 1 deletion(-) diff --git a/cogs/playlist.py b/cogs/playlist.py index eab38bf..564dc75 100644 --- a/cogs/playlist.py +++ b/cogs/playlist.py @@ -72,7 +72,6 @@ class Music: def __init__(self, bot): self.bot = bot self.voice_states = {} - self.max_songs = 10 def get_voice_state(self, server): state = self.voice_states.get(server.id) From ac025a5ddb285e4902f851a9297bc64cb29f08e8 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:11:56 -0500 Subject: [PATCH 14/22] Added a rules command, to add custom rules per server --- cogs/mod.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index 7b947be..238d68d 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -149,7 +149,59 @@ class Mod: del custom_perms[ctx.message.server.id][cmd] config.saveContent('custom_permissions', custom_perms) await self.bot.say("I have just removed the custom permissions for {}!".format(cmd)) - - + + @commands.group(aliases=['rule'], pass_context=True, no_pm=True, invoke_without_command=True) + @checks.customPermsOrRole(send_messages=True) + async def rules(self, ctx): + """This command can be used to view the current rules on the server""" + rules = config.getContent('rules') or {} + server_rules = rules.get(ctx.message.server.id) + if server_rules is None: + await self.bot.say("This server currently has no rules on it! I see you like to live dangerously...") + return + fmt = "\n".join("{}) {}".format(num+1,rule) for num,rule in enumerate(server_rules)) + await self.bot.say('```{}```'.format(fmt)) + + @rules.command(name='add', aliases=['create'], pass_context=True, no_pm=True) + @checks.customPermsOrRole(manage_server=True) + async def rules_add(self, ctx, *, rule: str) + """Adds a rule to this server's rules""" + rules = config.getContent('rules') or {} + server_rules = rules.get(ctx.message.server.id) or [] + server_rules.append(rule) + rules[ctx.message.server.id] = server_rules + config.saveContent('rules',rules) + await self.bot.say("I have just saved your new rule, use the rules command to view this server's current rules") + + @rules.command(name='remove', aliases=['delete'], pass_context=True, no_pm=True) + @checks.customPermsOrRole(manage_server=True) + async def rules_delete(self, ctx, rule: int=None) + """Removes one of the rules from the list of this server's rules""" + rules = config.getContent('rules') or {} + server_rules = rules.get(ctx.message.server.id) + if server_rules is None: + await self.bot.say("This server currently has no rules on it! Can't remove something that doesn't exist bro") + return + list_rules = "\n".join("{}) {}".format(num+1,rule) for num,rule in enumerate(server_rules)) + + if rule is None: + await self.bot.say("Your rules are:\n```{}```".format(list_rules)) + for i in range(3): + msg = await self.bot.await_for_message(timeout=60.0, author=ctx.message.author, channel = ctx.message.channel, check = lambda m: m.content.isdigit()) + if msg is None: + await self.bot.say("You took too long...it's just a number, seriously? Try typing a bit quicker") + return + del server_rules[int(msg)-1] + rules[ctx.message.server.id] = server_rules + config.saveContent('rules',rules) + + try: + del server_rules[rule-1] + rules[ctx.message.server.id] = server_rules + config.saveContent('rules',rules) + except IndexError: + await self.bot.say"That is not a valid rule number! Your current rules are:\n```{}```".format(list_rules) + + def setup(bot): bot.add_cog(Mod(bot)) From f1c8c13de47f721c77f0fd29d05e0e438cc9bc33 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:12:35 -0500 Subject: [PATCH 15/22] Added a rules command, to add custom rules per server --- cogs/mod.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index 238d68d..b57c214 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -164,7 +164,7 @@ class Mod: @rules.command(name='add', aliases=['create'], pass_context=True, no_pm=True) @checks.customPermsOrRole(manage_server=True) - async def rules_add(self, ctx, *, rule: str) + async def rules_add(self, ctx, *, rule: str): """Adds a rule to this server's rules""" rules = config.getContent('rules') or {} server_rules = rules.get(ctx.message.server.id) or [] @@ -175,7 +175,7 @@ class Mod: @rules.command(name='remove', aliases=['delete'], pass_context=True, no_pm=True) @checks.customPermsOrRole(manage_server=True) - async def rules_delete(self, ctx, rule: int=None) + async def rules_delete(self, ctx, rule: int=None): """Removes one of the rules from the list of this server's rules""" rules = config.getContent('rules') or {} server_rules = rules.get(ctx.message.server.id) From 94ce23575321bfa44ad9e3acb3f095a398f1d58c Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:12:54 -0500 Subject: [PATCH 16/22] Added a rules command, to add custom rules per server --- cogs/mod.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cogs/mod.py b/cogs/mod.py index b57c214..fb3a1bf 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -200,7 +200,7 @@ class Mod: rules[ctx.message.server.id] = server_rules config.saveContent('rules',rules) except IndexError: - await self.bot.say"That is not a valid rule number! Your current rules are:\n```{}```".format(list_rules) + await self.bot.say("That is not a valid rule number! Your current rules are:\n```{}```".format(list_rules)) def setup(bot): From b8f46426f829040a4b4b465dddd947d0ebc9b201 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:14:46 -0500 Subject: [PATCH 17/22] Added a rules command, to add custom rules per server --- cogs/mod.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index fb3a1bf..f020871 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -187,7 +187,7 @@ class Mod: if rule is None: await self.bot.say("Your rules are:\n```{}```".format(list_rules)) for i in range(3): - msg = await self.bot.await_for_message(timeout=60.0, author=ctx.message.author, channel = ctx.message.channel, check = lambda m: m.content.isdigit()) + msg = await self.bot.wait_for_message(timeout=60.0, author=ctx.message.author, channel = ctx.message.channel, check = lambda m: m.content.isdigit()) if msg is None: await self.bot.say("You took too long...it's just a number, seriously? Try typing a bit quicker") return @@ -200,7 +200,7 @@ class Mod: rules[ctx.message.server.id] = server_rules config.saveContent('rules',rules) except IndexError: - await self.bot.say("That is not a valid rule number! Your current rules are:\n```{}```".format(list_rules)) + await self.bot.say("That is not a valid rule number, try running the command again. Your current rules are:\n```{}```".format(list_rules)) def setup(bot): From 183932ca1fd711d85dc3030bdc4940775cf15aba Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:15:45 -0500 Subject: [PATCH 18/22] Added a rules command, to add custom rules per server --- cogs/mod.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index f020871..abd45b1 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -185,13 +185,13 @@ class Mod: list_rules = "\n".join("{}) {}".format(num+1,rule) for num,rule in enumerate(server_rules)) if rule is None: - await self.bot.say("Your rules are:\n```{}```".format(list_rules)) + await self.bot.say("Your rules are:\n```{}```Please provide the rule number you would like to remove (just the number)".format(list_rules)) for i in range(3): msg = await self.bot.wait_for_message(timeout=60.0, author=ctx.message.author, channel = ctx.message.channel, check = lambda m: m.content.isdigit()) if msg is None: await self.bot.say("You took too long...it's just a number, seriously? Try typing a bit quicker") return - del server_rules[int(msg)-1] + del server_rules[int(msg.content)-1] rules[ctx.message.server.id] = server_rules config.saveContent('rules',rules) From 67476c3e2fac164e87c82dc61e5f759ddce8f927 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:16:58 -0500 Subject: [PATCH 19/22] Added a message for the bot to send when a rule is removed successfully --- cogs/mod.py | 1 + 1 file changed, 1 insertion(+) diff --git a/cogs/mod.py b/cogs/mod.py index abd45b1..7d28cae 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -199,6 +199,7 @@ class Mod: del server_rules[rule-1] rules[ctx.message.server.id] = server_rules config.saveContent('rules',rules) + await self.bot.say("I have just removed that rule from your list of rules!") except IndexError: await self.bot.say("That is not a valid rule number, try running the command again. Your current rules are:\n```{}```".format(list_rules)) From c914fcc6b91ddcb93e56781de1a30a59f88cd392 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:17:36 -0500 Subject: [PATCH 20/22] Removed the counter for the deletion of rules --- cogs/mod.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index 7d28cae..f8639b0 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -186,14 +186,14 @@ class Mod: if rule is None: await self.bot.say("Your rules are:\n```{}```Please provide the rule number you would like to remove (just the number)".format(list_rules)) - for i in range(3): - msg = await self.bot.wait_for_message(timeout=60.0, author=ctx.message.author, channel = ctx.message.channel, check = lambda m: m.content.isdigit()) - if msg is None: - await self.bot.say("You took too long...it's just a number, seriously? Try typing a bit quicker") - return - del server_rules[int(msg.content)-1] - rules[ctx.message.server.id] = server_rules - config.saveContent('rules',rules) + + msg = await self.bot.wait_for_message(timeout=60.0, author=ctx.message.author, channel = ctx.message.channel, check = lambda m: m.content.isdigit()) + if msg is None: + await self.bot.say("You took too long...it's just a number, seriously? Try typing a bit quicker") + return + del server_rules[int(msg.content)-1] + rules[ctx.message.server.id] = server_rules + config.saveContent('rules',rules) try: del server_rules[rule-1] From c3b73b1dfba1b958c38d8c6d7f29fc3df871a8d2 Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:18:49 -0500 Subject: [PATCH 21/22] Added a rules command, to add custom rules per server --- cogs/mod.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cogs/mod.py b/cogs/mod.py index f8639b0..7f27a61 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -156,7 +156,7 @@ class Mod: """This command can be used to view the current rules on the server""" rules = config.getContent('rules') or {} server_rules = rules.get(ctx.message.server.id) - if server_rules is None: + if server_rules is None or len(server_rules) == 0: await self.bot.say("This server currently has no rules on it! I see you like to live dangerously...") return fmt = "\n".join("{}) {}".format(num+1,rule) for num,rule in enumerate(server_rules)) @@ -179,7 +179,7 @@ class Mod: """Removes one of the rules from the list of this server's rules""" rules = config.getContent('rules') or {} server_rules = rules.get(ctx.message.server.id) - if server_rules is None: + if server_rules is None or len(server_rules) == 0: await self.bot.say("This server currently has no rules on it! Can't remove something that doesn't exist bro") return list_rules = "\n".join("{}) {}".format(num+1,rule) for num,rule in enumerate(server_rules)) From 9b9a044a2784ba4e2160dacdcab4c28a017a2d6a Mon Sep 17 00:00:00 2001 From: Phxntxm Date: Sat, 30 Jul 2016 14:20:31 -0500 Subject: [PATCH 22/22] Changed up description of removing rulres --- cogs/mod.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cogs/mod.py b/cogs/mod.py index 7f27a61..d1d9533 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -176,7 +176,9 @@ class Mod: @rules.command(name='remove', aliases=['delete'], pass_context=True, no_pm=True) @checks.customPermsOrRole(manage_server=True) async def rules_delete(self, ctx, rule: int=None): - """Removes one of the rules from the list of this server's rules""" + """Removes one of the rules from the list of this server's rules + Provide a number to delete that rule; if no number is provided + I'll print your current rules and ask for a number""" rules = config.getContent('rules') or {} server_rules = rules.get(ctx.message.server.id) if server_rules is None or len(server_rules) == 0: