diff --git a/bot.py b/bot.py index a8f565d..6a4d96f 100644 --- a/bot.py +++ b/bot.py @@ -29,21 +29,14 @@ async def on_ready(): bot.owner = appinfo.owner -@bot.event -async def on_message(message): - if message.author.bot or utils.should_ignore(bot, message): - return - await bot.process_commands(message) - - @bot.event async def on_command_completion(ctx): author = ctx.message.author server = ctx.message.guild command = ctx.command - command_usage = await bot.db.actual_load('command_usage', key=command.qualified_name) or \ - {'command': command.qualified_name} + command_usage = await bot.db.actual_load('command_usage', key=command.qualified_name) \ + or {'command': command.qualified_name} # Add one to the total usage for this command, basing it off 0 to start with (obviously) total_usage = command_usage.get('total_usage', 0) + 1 diff --git a/cogs/admin.py b/cogs/admin.py index 54c4f85..67e0996 100644 --- a/cogs/admin.py +++ b/cogs/admin.py @@ -15,8 +15,7 @@ class Administration: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def battles(self, ctx): """Used to list the server specific battles messages on this server @@ -34,8 +33,7 @@ class Administration: @battles.command(name='add') @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def add_battles(self, ctx, *, message): """Used to add a battle message to the server specific battle messages Use {winner} or {loser} in order to display the winner/loser's display name @@ -65,8 +63,7 @@ class Administration: @battles.command(name='remove', aliases=['delete']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def remove_battles(self, ctx): """Used to remove one of the custom hugs from the server's list of hug messages @@ -113,8 +110,7 @@ class Administration: @battles.command(name='default') @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def default_battles(self, ctx): """Used to toggle if battles should include default messages as well as server-custom messages @@ -136,8 +132,7 @@ class Administration: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def hugs(self, ctx): """Used to list the server specific hug messages on this server @@ -155,8 +150,7 @@ class Administration: @hugs.command(name='add') @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def add_hugs(self, ctx, *, message): """Used to add a hug to the server specific hug messages Use {user} in order to display the user's display name @@ -182,8 +176,7 @@ class Administration: @hugs.command(name='remove', aliases=['delete']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def remove_hugs(self, ctx): """Used to remove one of the custom hugs from the server's list of hug messages @@ -230,8 +223,7 @@ class Administration: @hugs.command(name='default') @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def default_hugs(self, ctx): """Used to toggle if hugs should include default messages as well as server-custom messages @@ -253,8 +245,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def allowbirthdays(self, ctx, setting): """Turns on/off the birthday announcements in this server @@ -274,8 +265,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def allowcolours(self, ctx, setting): """Turns on/off the ability to use colour roles in this server @@ -295,8 +285,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def allowplaylists(self, ctx, setting): """Turns on/off the ability to playlists @@ -316,8 +305,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def restrictions(self, ctx): """Used to list all the current restrictions set @@ -354,8 +342,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def restrict(self, ctx, *options): """ This is an intuitive command to restrict something to/from something @@ -581,8 +568,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def unrestrict(self, ctx, *options): """ This is an intuitive command to unrestrict something to/from something @@ -679,8 +665,7 @@ class Administration: @commands.command(aliases=['nick']) @commands.guild_only() - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def nickname(self, ctx, *, name=None): """Used to set the nickname for Bonfire (provide no nickname and it will reset) @@ -695,8 +680,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def ignore(self, ctx, member_or_channel): """This command can be used to have Bonfire ignore certain members/channels @@ -747,8 +731,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def unignore(self, ctx, member_or_channel): """This command can be used to have Bonfire stop ignoring certain members/channels @@ -796,8 +779,7 @@ class Administration: @commands.command(aliases=['notifications']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def alerts(self, ctx, channel: discord.TextChannel): """This command is used to set a channel as the server's default 'notifications' channel Any notifications (like someone going live on Twitch, or Picarto) will go to that channel by default @@ -819,8 +801,7 @@ class Administration: @commands.group(invoke_without_command=True, aliases=['goodbye']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def welcome(self, ctx, on_off: str): """This command can be used to set whether or not you want user notificaitons to show Provide on, yes, or true to set it on; otherwise it will be turned off @@ -843,8 +824,7 @@ class Administration: @welcome.command(name='alerts', aliases=['notifications']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def _welcome_alerts(self, ctx, *, channel: discord.TextChannel): """A command used to set the override for notifications about users joining/leaving @@ -863,8 +843,7 @@ class Administration: @welcome.command(name='message') @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def _welcome_message(self, ctx, *, msg): """A command to customize the welcome/goodbye message There are a couple things that can be set to customize the message @@ -894,15 +873,13 @@ class Administration: await ctx.send("I have just updated your {} message".format(parent)) @commands.group() - @utils.check_restricted() async def nsfw(self, ctx): """Handles adding or removing a channel as a nsfw channel""" # This command isn't meant to do anything, so just send an error if an invalid subcommand is passed pass @nsfw.command(name="add") - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def nsfw_add(self, ctx): """Registers this channel as a 'nsfw' channel @@ -927,8 +904,7 @@ class Administration: await ctx.send("This channel has just been registered as 'nsfw'! Have fun you naughties ;)") @nsfw.command(name="remove", aliases=["delete"]) - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def nsfw_remove(self, ctx): """Removes this channel as a 'nsfw' channel @@ -955,8 +931,7 @@ class Administration: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def perms(self, ctx, *, command: str = None): """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 @@ -997,9 +972,9 @@ class Administration: perms_value = server_perms.get(cmd.qualified_name) if perms_value is None: # If we don't find custom permissions, get the required permission for a command - # based on what we set in utils.custom_perms, if custom_perms isn't found, we'll get an IndexError + # based on what we set in utils.can_run, if can_run isn't found, we'll get an IndexError try: - custom_perms = [func for func in cmd.checks if "custom_perms" in func.__qualname__][0] + can_run = [func for func in cmd.checks if "can_run" in func.__qualname__][0] except IndexError: # Loop through and check if there is a check called is_owner # If we loop through and don't find one, this means that the only other choice is to be @@ -1013,8 +988,8 @@ class Administration: )) return - # Perms will be an attribute if custom_perms is found no matter what, so no need to check this - perms = "\n".join(attribute for attribute, setting in custom_perms.perms.items() if setting) + # Perms will be an attribute if can_run is found no matter what, so no need to check this + perms = "\n".join(attribute for attribute, setting in can_run.perms.items() if setting) await ctx.send( "You are required to have `{}` permissions to run `{}`".format(perms, cmd.qualified_name)) else: @@ -1029,7 +1004,6 @@ class Administration: @perms.command(name="add", aliases=["setup,create"]) @commands.guild_only() @commands.has_permissions(manage_guild=True) - @utils.check_restricted() async def add_perms(self, ctx, *msg: str): """Sets up custom permissions on the provided command Format must be 'perms add ' @@ -1095,7 +1069,6 @@ class Administration: @perms.command(name="remove", aliases=["delete"]) @commands.guild_only() @commands.has_permissions(manage_guild=True) - @utils.check_restricted() async def remove_perms(self, ctx, *, command: str): """Removes the custom permissions setup on the command specified @@ -1119,8 +1092,7 @@ class Administration: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def prefix(self, ctx, *, prefix: str): """This command can be used to set a custom prefix per server @@ -1149,8 +1121,7 @@ class Administration: @commands.group(aliases=['rule'], invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def rules(self, ctx, rule: int = None): """This command can be used to view the current rules on the server @@ -1179,8 +1150,7 @@ class Administration: @rules.command(name='add', aliases=['create']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def rules_add(self, ctx, *, rule: str): """Adds a rule to this server's rules @@ -1201,8 +1171,7 @@ class Administration: @rules.command(name='remove', aliases=['delete']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def rules_delete(self, ctx, rule: int): """Removes one of the rules from the list of this server's rules Provide a number to delete that rule diff --git a/cogs/birthday.py b/cogs/birthday.py index e758955..afdfe05 100644 --- a/cogs/birthday.py +++ b/cogs/birthday.py @@ -112,8 +112,7 @@ class Birthday: @commands.group(aliases=['birthdays'], invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def birthday(self, ctx, *, member: discord.Member = None): """A command used to view the birthdays on this server; or a specific member's birthday @@ -139,8 +138,7 @@ class Birthday: await ctx.send(str(e)) @birthday.command(name='add') - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def _add_bday(self, ctx, *, date): """Used to link your birthday to your account @@ -162,8 +160,7 @@ class Birthday: await ctx.send("I have just saved your birthday as {}".format(date)) @birthday.command(name='remove') - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def _remove_bday(self, ctx): """Used to unlink your birthday to your account @@ -178,8 +175,7 @@ class Birthday: @birthday.command(name='alerts', aliases=['notifications']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def birthday_alerts_channel(self, ctx, channel: discord.TextChannel): """Sets the notifications channel for birthday notifications diff --git a/cogs/blackjack.py b/cogs/blackjack.py index ff76ae1..ec88f75 100644 --- a/cogs/blackjack.py +++ b/cogs/blackjack.py @@ -38,8 +38,7 @@ class Blackjack: @commands.group(aliases=['bj'], invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def blackjack(self, ctx): """Creates a game/joins the current running game of blackjack @@ -66,8 +65,7 @@ class Blackjack: @blackjack.command(name='leave', aliases=['quit']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def blackjack_leave(self, ctx): """Leaves the current game of blackjack @@ -89,8 +87,7 @@ class Blackjack: @blackjack.command(name='forcestop', aliases=['stop']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def blackjack_stop(self, ctx): """Forces the game to stop, mostly for use if someone has gone afk diff --git a/cogs/chess.py b/cogs/chess.py index d37331a..11a2566 100644 --- a/cogs/chess.py +++ b/cogs/chess.py @@ -118,7 +118,7 @@ class Chess: return game @commands.group(invoke_without_command=True) - @checks.custom_perms(send_messages=True) + @checks.can_run(send_messages=True) async def chess(self, ctx, *, move): """Moves a piece based on the notation provided Notation for normal moves are {piece} to {position} based on the algebraic notation of the board (This is on the picture) @@ -153,7 +153,7 @@ class Chess: await self.bot.upload(link) @commands.command() - @checks.custom_perms(send_messages=True) + @checks.can_run(send_messages=True) async def chess_start(self, ctx, player2: discord.Member): """Starts a chess game with another player You can play one game on a single guild at a time diff --git a/cogs/hangman.py b/cogs/hangman.py index 73117e4..5326d0c 100644 --- a/cogs/hangman.py +++ b/cogs/hangman.py @@ -79,7 +79,7 @@ class Hangman: @commands.group(aliases=['hm'], invoke_without_command=True) @commands.guild_only() @commands.cooldown(1, 7, BucketType.user) - @checks.custom_perms(send_messages=True) + @checks.can_run(send_messages=True) @checks.check_restricted() async def hangman(self, ctx, *, guess): """Makes a guess towards the server's currently running hangman game @@ -128,7 +128,7 @@ class Hangman: @hangman.command(name='create', aliases=['start']) @commands.guild_only() - @checks.custom_perms(send_messages=True) + @checks.can_run(send_messages=True) @checks.check_restricted() async def create_hangman(self, ctx): """This is used to create a new hangman game @@ -180,7 +180,7 @@ class Hangman: @hangman.command(name='delete', aliases=['stop', 'remove', 'end']) @commands.guild_only() - @checks.custom_perms(kick_members=True) + @checks.can_run(kick_members=True) @checks.check_restricted() async def stop_game(self, ctx): """Force stops a game of hangman diff --git a/cogs/images.py b/cogs/images.py index 1742bda..40f5359 100644 --- a/cogs/images.py +++ b/cogs/images.py @@ -13,8 +13,7 @@ class Images: self.bot = bot @commands.command(aliases=['rc']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def cat(self, ctx): """Use this to print a random cat image. @@ -32,8 +31,7 @@ class Images: await ctx.send("I couldn't connect! Sorry no cats right now ;w;") @commands.command(aliases=['dog', 'rd']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def doggo(self, ctx): """Use this to print a random doggo image. @@ -52,8 +50,7 @@ class Images: await ctx.send(file=f) @commands.command(aliases=['snake']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def snek(self, ctx): """Use this to print a random snek image. @@ -74,8 +71,7 @@ class Images: await ctx.send(file=f) @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def horse(self, ctx): """Use this to print a random horse image. @@ -97,8 +93,7 @@ class Images: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def avatar(self, ctx, member: discord.Member = None): """Provides an image for the provided person's avatar (yours if no other member is provided) @@ -128,8 +123,7 @@ class Images: await ctx.send(url) @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(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 @@ -197,8 +191,7 @@ class Images: await ctx.send(image_link) @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(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/interaction.py b/cogs/interaction.py index 22a7695..110cee2 100644 --- a/cogs/interaction.py +++ b/cogs/interaction.py @@ -156,8 +156,7 @@ class Interaction: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def hug(self, ctx, user=None): """Makes me hug a person! @@ -197,8 +196,7 @@ class Interaction: @commands.command(aliases=['1v1']) @commands.guild_only() @commands.cooldown(1, 20, BucketType.user) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def battle(self, ctx, player2=None): """Challenges the mentioned user to a battle @@ -254,8 +252,7 @@ class Interaction: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def accept(self, ctx): """Accepts the battle challenge @@ -335,8 +332,7 @@ class Interaction: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def decline(self, ctx): """Declines the battle challenge @@ -363,8 +359,7 @@ class Interaction: @commands.command() @commands.guild_only() @commands.cooldown(1, 10, BucketType.user) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def boop(self, ctx, boopee: discord.Member = None, *, message=""): """Boops the mentioned person diff --git a/cogs/links.py b/cogs/links.py index 888d8c0..49a9032 100644 --- a/cogs/links.py +++ b/cogs/links.py @@ -16,8 +16,7 @@ class Links: self.bot = bot @commands.command(aliases=['g']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def google(self, ctx, *, query: str): """Searches google for a provided query @@ -71,8 +70,7 @@ class Links: await ctx.send(fmt) @commands.command(aliases=['yt']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def youtube(self, ctx, *, query: str): """Searches youtube for a provided query @@ -107,8 +105,7 @@ class Links: await ctx.send(fmt) @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def wiki(self, ctx, *, query: str): """Pulls the top match for a specific term from wikipedia, and returns the result @@ -147,8 +144,7 @@ class Links: snippet)) @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def urban(self, ctx, *, msg: str): """Pulls the top urbandictionary.com definition for a term diff --git a/cogs/misc.py b/cogs/misc.py index e89f9be..9bc13d5 100644 --- a/cogs/misc.py +++ b/cogs/misc.py @@ -23,8 +23,7 @@ class Miscallaneous: self.process.cpu_percent() @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def help(self, ctx, *, command=None): """This command is used to provide a link to the help URL. This can be called on a command to provide more information about that command @@ -110,8 +109,7 @@ class Miscallaneous: await ctx.send(embed=embed) @commands.command(aliases=["coin"]) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def coinflip(self, ctx): """Flips a coin and responds with either heads or tails @@ -122,8 +120,7 @@ class Miscallaneous: await ctx.send(result) @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def say(self, ctx, *, msg: str): """Tells the bot to repeat what you say @@ -137,8 +134,7 @@ class Miscallaneous: pass @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def calendar(self, ctx, 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 @@ -177,8 +173,7 @@ class Miscallaneous: await ctx.send("```\n{}```".format(cal)) @commands.command(aliases=['about']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def info(self, ctx): """This command can be used to print out some of my information""" # fmt is a dictionary so we can set the key to it's output, then print both @@ -248,8 +243,7 @@ class Miscallaneous: await ctx.send(embed=embed) @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def uptime(self, ctx): """Provides a printout of the current bot's uptime @@ -261,8 +255,7 @@ class Miscallaneous: await ctx.send("I've just restarted and not quite ready yet...gimme time I'm not a morning pony :c") @commands.command(aliases=['invite']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def addbot(self, ctx): """Provides a link that you can use to add me to a server @@ -287,8 +280,7 @@ class Miscallaneous: .format(discord.utils.oauth_url(app_info.id, perms))) @commands.command(enabled=False) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def joke(self, ctx): """Prints a random riddle @@ -298,8 +290,7 @@ class Miscallaneous: pass @commands.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(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/mod.py b/cogs/mod.py index 4f7ed38..5230873 100644 --- a/cogs/mod.py +++ b/cogs/mod.py @@ -14,8 +14,7 @@ class Moderation: @commands.command() @commands.guild_only() - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def kick(self, ctx, member: discord.Member, *, reason=None): """Used to kick a member from this server @@ -29,8 +28,7 @@ class Moderation: @commands.command() @commands.guild_only() - @utils.custom_perms(ban_members=True) - @utils.check_restricted() + @utils.can_run(ban_members=True) async def unban(self, ctx, member_id: int): """Used to unban a member from this server Due to the fact that I cannot find a user without being in a server with them @@ -51,8 +49,7 @@ class Moderation: @commands.command() @commands.guild_only() - @utils.custom_perms(ban_members=True) - @utils.check_restricted() + @utils.can_run(ban_members=True) async def ban(self, ctx, member, *, reason=None): """Used to ban a member This can be used to ban someone preemptively as well. @@ -93,8 +90,7 @@ class Moderation: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_messages=True) - @utils.check_restricted() + @utils.can_run(manage_messages=True) async def purge(self, ctx, limit: int = 100): """This command is used to a purge a number of messages from the channel @@ -116,8 +112,7 @@ class Moderation: @commands.command() @commands.guild_only() - @utils.custom_perms(manage_messages=True) - @utils.check_restricted() + @utils.can_run(manage_messages=True) async def prune(self, ctx, *specifications): """This command can be used to prune messages from certain members Mention any user you want to prune messages from; if no members are mentioned, the messages removed will be mine diff --git a/cogs/osu.py b/cogs/osu.py index a9bf495..489dae3 100644 --- a/cogs/osu.py +++ b/cogs/osu.py @@ -55,8 +55,7 @@ class Osu: self.osu_users[member] = user @commands.group(invoke_without_command=True) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def osu(self, ctx, member: discord.Member = None): """Provides basic information about a specific user @@ -88,8 +87,7 @@ class Osu: await ctx.send(embed=e) @osu.command(name='add', aliases=['create', 'connect']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def osu_add(self, ctx, *, username): """Links an osu account to your discord account @@ -112,8 +110,7 @@ class Osu: await ctx.send("I have just saved your Osu user {}".format(author.display_name)) @osu.command(name='score', aliases=['scores']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def osu_scores(self, ctx, *data): """Find the top x osu scores for a provided member Note: You can only get the top 50 songs for a user diff --git a/cogs/overwatch.py b/cogs/overwatch.py index 91a0a03..9b57594 100644 --- a/cogs/overwatch.py +++ b/cogs/overwatch.py @@ -20,7 +20,6 @@ class Overwatch: self.bot = bot @commands.group() - @utils.check_restricted() async def ow(self, ctx): """Command used to lookup information on your own user, or on another's When adding your battletag, it is quite picky, use the exact format user#xxxx @@ -29,8 +28,7 @@ class Overwatch: pass @ow.command(name="stats") - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(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 @@ -90,8 +88,7 @@ class Overwatch: await ctx.send("Overwatch stats for {}: ```py\n{}```".format(user.name, fmt)) @ow.command(name="add") - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def add(self, ctx, bt: str): """Saves your battletag for looking up information @@ -123,8 +120,7 @@ class Overwatch: await ctx.send("I have just saved your battletag {}".format(ctx.message.author.mention)) @ow.command(name="delete", aliases=['remove']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def delete(self, ctx): """Removes your battletag from the records diff --git a/cogs/owner.py b/cogs/owner.py index 94fbb00..cd36270 100644 --- a/cogs/owner.py +++ b/cogs/owner.py @@ -91,7 +91,7 @@ class Owner: await self.bot.owner.send(embed=embed) @commands.command(hidden=True) - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def repl(self, ctx): msg = ctx.message @@ -184,7 +184,7 @@ class Owner: await ctx.send('Unexpected error: `{}`'.format(e)) @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def sendtochannel(self, ctx, cid: int, *, message): """Sends a message to a provided channel, by ID""" channel = self.bot.get_channel(cid) @@ -195,7 +195,7 @@ class Owner: pass @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def debug(self, ctx, *, body: str): env = { 'bot': self.bot, @@ -246,7 +246,7 @@ class Owner: await ctx.send("Content too large for me to print!") @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def bash(self, ctx, *, cmd: str): """Runs a bash command""" output = subprocess.check_output("{}; exit 0".format(cmd), stderr=subprocess.STDOUT, shell=True) @@ -256,7 +256,7 @@ class Owner: await ctx.send("No output for `{}`".format(cmd)) @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def shutdown(self, ctx): """Shuts the bot down""" fmt = 'Shutting down, I will miss you {0.author.name}' @@ -265,21 +265,21 @@ class Owner: await self.bot.close() @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def name(self, ctx, new_nick: str): """Changes the bot's name""" await self.bot.user.edit(username=new_nick) await ctx.send('Changed username to ' + new_nick) @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def status(self, ctx, *, status: str): """Changes the bot's 'playing' status""" await self.bot.change_presence(activity=discord.Game(name=status, type=0)) await ctx.send("Just changed my status to '{}'!".format(status)) @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def load(self, ctx, *, module: str): """Loads a module""" @@ -297,7 +297,7 @@ class Owner: await ctx.send(fmt.format(type(error).__name__, error)) @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def unload(self, ctx, *, module: str): """Unloads a module""" @@ -310,7 +310,7 @@ class Owner: await ctx.send("I have just unloaded the {} module".format(module)) @commands.command() - @commands.check(utils.is_owner) + @utils.can_run(ownership=True) async def reload(self, ctx, *, module: str): """Reloads a module""" diff --git a/cogs/picarto.py b/cogs/picarto.py index 55b1f2d..d352fd6 100644 --- a/cogs/picarto.py +++ b/cogs/picarto.py @@ -129,8 +129,7 @@ class Picarto: pass @commands.group(invoke_without_command=True) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def picarto(self, ctx, member: discord.Member = None): """This command can be used to view Picarto stats about a certain member @@ -151,8 +150,7 @@ class Picarto: @picarto.command(name='add') @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def add_picarto_url(self, ctx, url: str): """Saves your user's picarto URL @@ -206,8 +204,7 @@ class Picarto: ctx.message.author.mention)) @picarto.command(name='remove', aliases=['delete']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def remove_picarto_url(self, ctx): """Removes your picarto URL""" key = str(ctx.message.author.id) @@ -226,8 +223,7 @@ class Picarto: @picarto.command(name='alerts') @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def picarto_alerts_channel(self, ctx, channel: discord.TextChannel): """Sets the notifications channel for picarto notifications @@ -245,8 +241,7 @@ class Picarto: @picarto.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def notify(self, ctx): """This can be used to turn picarto notifications on or off Call this command by itself, to add this guild to the list of guilds to be notified @@ -274,8 +269,7 @@ class Picarto: @notify.command(name='on', aliases=['start,yes']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def notify_on(self, ctx): """Turns picarto notifications on @@ -296,8 +290,7 @@ class Picarto: @notify.command(name='off', aliases=['stop,no']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def notify_off(self, ctx): """Turns picarto notifications off diff --git a/cogs/polls.py b/cogs/polls.py index 3e55c35..f15737b 100644 --- a/cogs/polls.py +++ b/cogs/polls.py @@ -72,8 +72,7 @@ class Polls: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def poll(self, ctx, *, question): """Sets up a poll based on the question that you have provided. Provide the question on the first line and the options on the following lines diff --git a/cogs/raffle.py b/cogs/raffle.py index cbcffdb..6eaa04f 100644 --- a/cogs/raffle.py +++ b/cogs/raffle.py @@ -98,8 +98,7 @@ class Raffle: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def raffles(self, ctx): """Used to print the current running raffles on the server @@ -124,8 +123,7 @@ class Raffle: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def raffle(self, ctx, raffle_id: int = 0): """Used to enter a raffle running on this server If there is more than one raffle running, provide an ID of the raffle you want to enter @@ -186,8 +184,7 @@ class Raffle: @raffle.command(name='create', aliases=['start', 'begin', 'add']) @commands.guild_only() - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def raffle_create(self, ctx): """This is used in order to create a new server raffle @@ -281,8 +278,7 @@ class Raffle: @raffle.command(name='alerts') @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def raffle_alerts_channel(self, ctx, channel: discord.TextChannel): """Sets the notifications channel for raffle notifications diff --git a/cogs/roles.py b/cogs/roles.py index 4e90e57..d926fad 100644 --- a/cogs/roles.py +++ b/cogs/roles.py @@ -15,8 +15,7 @@ class Roles: @commands.command(aliases=['color']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def colour(self, ctx, role_colour: discord.Colour): """Used to give yourself a role matching the colour given. If the role doesn't exist, it will be created. Names such as red, blue, yellow, etc. can be used. @@ -62,8 +61,7 @@ class Roles: @commands.group(aliases=['roles'], invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def role(self, ctx): """This command can be used to modify the roles on the server. Pass no subcommands and this will print the roles currently available on this server @@ -86,8 +84,7 @@ class Roles: @role.command(name='remove') @commands.guild_only() - @utils.custom_perms(manage_roles=True) - @utils.check_restricted() + @utils.can_run(manage_roles=True) async def remove_role(self, ctx): """Use this to remove roles from a number of members @@ -149,8 +146,7 @@ class Roles: @role.command(name='add', aliases=['give', 'assign']) @commands.guild_only() - @utils.custom_perms(manage_roles=True) - @utils.check_restricted() + @utils.can_run(manage_roles=True) async def add_role(self, ctx): """Use this to add a role to multiple members. Provide the list of members, and I'll ask for the role @@ -206,8 +202,7 @@ class Roles: @role.command(name='delete') @commands.guild_only() - @utils.custom_perms(manage_roles=True) - @utils.check_restricted() + @utils.can_run(manage_roles=True) async def delete_role(self, ctx, *, role: discord.Role = None): """This command can be used to delete one of the roles from the server @@ -249,8 +244,7 @@ class Roles: @role.command(name='create') @commands.guild_only() - @utils.custom_perms(manage_roles=True) - @utils.check_restricted() + @utils.can_run(manage_roles=True) async def create_role(self, ctx): """This command can be used to create a new role for this server A prompt will follow asking what settings you would like for this new role @@ -366,8 +360,7 @@ class Roles: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def assign(self, ctx, *role: discord.Role): """Assigns the provided role(s) to you, if they can be assigned @@ -400,8 +393,7 @@ class Roles: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def unassign(self, ctx, *role: discord.Role): """Unassigns the provided role(s) to you, if they can be assigned @@ -434,8 +426,7 @@ class Roles: @assign.command(name='add') @commands.guild_only() - @utils.custom_perms(manage_roles=True) - @utils.check_restricted() + @utils.can_run(manage_roles=True) async def _add_assigns(self, ctx, *role: discord.Role): """Adds the provided role(s) to the list of available self-assignable roles @@ -464,8 +455,7 @@ class Roles: @assign.command(name='list') @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def _list_assigns(self, ctx): """Lists the roles that can be self-assigned @@ -495,8 +485,7 @@ class Roles: @assign.command(name='remove', aliases=['delete']) @commands.guild_only() - @utils.custom_perms(manage_roles=True) - @utils.check_restricted() + @utils.can_run(manage_roles=True) async def _delete_assigns(self, ctx, *role: discord.Role): """Removes the provided role(s) from the list of available self-assignable roles diff --git a/cogs/roulette.py b/cogs/roulette.py index e4af6c6..e78d564 100644 --- a/cogs/roulette.py +++ b/cogs/roulette.py @@ -36,8 +36,7 @@ class Roulette: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def roulette(self, ctx): """Joins the current running roulette @@ -56,8 +55,7 @@ class Roulette: @roulette.command(name='start', aliases=['create']) @commands.guild_only() - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def roulette_start(self, ctx, time: int=5): """Starts a roulette, that will end in one of the entrants being kicked from the server By default, the roulette will end in 5 minutes; provide a number (up to 30) diff --git a/cogs/spotify.py b/cogs/spotify.py index acf6c81..aac3331 100644 --- a/cogs/spotify.py +++ b/cogs/spotify.py @@ -45,8 +45,7 @@ class Spotify: return data.get("expires_in") @commands.group(invoke_without_command=True) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def spotify(self, ctx, *, query): """Searches Spotify for a song, giving you the link you can use to listen in. Give the query to search for and it will search by title/artist for the best match @@ -65,8 +64,7 @@ class Spotify: await ctx.send("Couldn't find a song for:\n{}".format(query)) @spotify.command() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def playlist(self, ctx, *, query): """Searches Spotify for a playlist, giving you the link you can use to listen in. Give the query to search for and it will search for the best match diff --git a/cogs/stats.py b/cogs/stats.py index c616c64..36aa8bb 100644 --- a/cogs/stats.py +++ b/cogs/stats.py @@ -62,8 +62,7 @@ class Stats: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def serverinfo(self, ctx): """Provides information about the server @@ -96,8 +95,7 @@ class Stats: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def userinfo(self, ctx, *, user: discord.Member = None): """Provides information about a provided member @@ -130,15 +128,13 @@ class Stats: await ctx.send(embed=embed) @commands.group() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def command(self, ctx): pass @command.command(name="stats") @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def command_stats(self, ctx, *, command): """This command can be used to view some usage stats about a specific command @@ -176,8 +172,7 @@ class Stats: await ctx.send(fmt) @command.command(name="leaderboard") - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def command_leaderboard(self, ctx, option="server"): """This command can be used to print a leaderboard of commands Provide 'server' to print a leaderboard for this server @@ -236,8 +231,7 @@ class Stats: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def mostboops(self, ctx): """Shows the person you have 'booped' the most, as well as how many times @@ -269,8 +263,7 @@ class Stats: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def listboops(self, ctx): """Lists all the users you have booped and the amount of times @@ -306,8 +299,7 @@ class Stats: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def leaderboard(self, ctx): """Prints a leaderboard of everyone in the server's battling record @@ -345,8 +337,7 @@ class Stats: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def battlestats(self, ctx, member: discord.Member = None): """Prints the battling stats for you, or the user provided @@ -372,8 +363,7 @@ class Stats: await ctx.send('```\n{}```'.format(fmt)) @commands.command(aliases=['donators']) - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def patrons(self, ctx): """Prints a list of all the patrons for Bonfire diff --git a/cogs/tags.py b/cogs/tags.py index 28ad46f..610ee60 100644 --- a/cogs/tags.py +++ b/cogs/tags.py @@ -14,8 +14,7 @@ class Tags: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def tags(self, ctx): """Prints all the custom tags that this server currently has @@ -31,8 +30,7 @@ class Tags: @commands.command() @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def mytags(self, ctx): """Prints all the custom tags that this server that you own @@ -51,8 +49,7 @@ class Tags: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(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 @@ -72,8 +69,7 @@ class Tags: @tag.command(name='add', aliases=['create', 'setup']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def add_tag(self, ctx): """Use this to add a new tag that can be used in this server @@ -152,8 +148,7 @@ class Tags: @tag.command(name='edit') @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def edit_tag(self, ctx, *, tag: str): """This will allow you to edit a tag that you have created EXAMPLE: !tag edit this tag @@ -198,8 +193,7 @@ class Tags: @tag.command(name='delete', aliases=['remove', 'stop']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def del_tag(self, ctx, *, tag: str): """Use this to remove a tag from use for this server Format to delete a tag is !tag delete diff --git a/cogs/tictactoe.py b/cogs/tictactoe.py index 3bc672a..e05a4cd 100644 --- a/cogs/tictactoe.py +++ b/cogs/tictactoe.py @@ -110,8 +110,7 @@ class TicTacToe: @commands.group(aliases=['tic', 'tac', 'toe'], invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def tictactoe(self, ctx, *, option: str): """Updates the current server's tic-tac-toe board You obviously need to be one of the players to use this @@ -208,8 +207,7 @@ class TicTacToe: @tictactoe.command(name='start', aliases=['challenge', 'create']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def start_game(self, ctx, player2: discord.Member): """Starts a game of tictactoe with another player @@ -244,8 +242,7 @@ class TicTacToe: @tictactoe.command(name='delete', aliases=['stop', 'remove', 'end']) @commands.guild_only() - @utils.custom_perms(kick_members=True) - @utils.check_restricted() + @utils.can_run(kick_members=True) async def stop_game(self, ctx): """Force stops a game of tictactoe This should realistically only be used in a situation like one player leaves diff --git a/cogs/tutorial.py b/cogs/tutorial.py index 171ae7e..68da52c 100644 --- a/cogs/tutorial.py +++ b/cogs/tutorial.py @@ -10,8 +10,8 @@ class Tutorial: self.bot = bot @commands.command() - @commands.check(utils.is_owner) - # @utils.custom_perms(send_messages=True) + @utils.can_run(ownership=True) + # @utils.can_run(send_messages=True) async def tutorial(self, ctx, *, cmd_or_cog = None): # The message we'll use to send output = "" @@ -110,8 +110,8 @@ class Tutorial: inline=False ) try: - custom_perms = [func for func in command.checks if "custom_perms" in func.__qualname__][0] - perms = ",".join(attribute for attribute, setting in custom_perms.perms.items() if setting) + can_run = [func for func in command.checks if "can_run" in func.__qualname__][0] + perms = ",".join(attribute for attribute, setting in can_run.perms.items() if setting) embed.set_footer(text="Permissions required: {}".format(perms)) except IndexError: pass diff --git a/cogs/twitch.py b/cogs/twitch.py index 26b9e14..76b927b 100644 --- a/cogs/twitch.py +++ b/cogs/twitch.py @@ -142,8 +142,7 @@ class Twitch: @commands.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def twitch(self, ctx, *, member: discord.Member = None): """Use this command to check the twitch info of a user @@ -164,8 +163,7 @@ class Twitch: @twitch.command(name='add') @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def add_twitch_url(self, ctx, url: str): """Saves your user's twitch URL @@ -217,8 +215,7 @@ class Twitch: @twitch.command(name='remove', aliases=['delete']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def remove_twitch_url(self, ctx): """Removes your twitch URL @@ -234,8 +231,7 @@ class Twitch: @twitch.command(name='alerts', aliases=['notifications']) @commands.guild_only() - @utils.custom_perms(manage_guild=True) - @utils.check_restricted() + @utils.can_run(manage_guild=True) async def twitch_alerts_channel(self, ctx, channel: discord.TextChannel): """Sets the notifications channel for twitch notifications @@ -253,8 +249,7 @@ class Twitch: @twitch.group(invoke_without_command=True) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def notify(self, ctx): """This can be used to modify notification settings for your twitch user Call this command by itself to add 'this' server as one that will be notified when you on/offline @@ -282,8 +277,7 @@ class Twitch: @notify.command(name='on', aliases=['start,yes']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def notify_on(self, ctx): """Turns twitch notifications on @@ -304,8 +298,7 @@ class Twitch: @notify.command(name='off', aliases=['stop,no']) @commands.guild_only() - @utils.custom_perms(send_messages=True) - @utils.check_restricted() + @utils.can_run(send_messages=True) async def notify_off(self, ctx): """Turns twitch notifications off diff --git a/cogs/utils/__init__.py b/cogs/utils/__init__.py index 62b0249..acfc18d 100644 --- a/cogs/utils/__init__.py +++ b/cogs/utils/__init__.py @@ -1,5 +1,5 @@ from .cards import Deck -from .checks import is_owner, custom_perms, db_check, should_ignore, check_restricted +from .checks import can_run, db_check from .config import * from .utilities import * from .images import create_banner diff --git a/cogs/utils/checks.py b/cogs/utils/checks.py index 0cf2d24..ca5a424 100644 --- a/cogs/utils/checks.py +++ b/cogs/utils/checks.py @@ -70,119 +70,133 @@ def is_owner(ctx): return ctx.bot.owner.id == ctx.message.author.id -def should_ignore(bot, message): - if message.guild is None: +def should_ignore(ctx): + if ctx.message.guild is None: return False - ignored = bot.db.load('server_settings', key=message.guild.id, pluck='ignored') + ignored = ctx.bot.db.load('server_settings', key=ctx.message.guild.id, pluck='ignored') if not ignored: return False - return str(message.author.id) in ignored['members'] or str(message.channel.id) in ignored['channels'] + return str(ctx.message.author.id) in ignored['members'] or str(ctx.message.channel.id) in ignored['channels'] -def check_restricted(): - async def predicate(ctx): - # Return true if this is a private channel, we'll handle that in the registering of the command - if type(ctx.message.channel) is discord.DMChannel: - return True - - # First get all the restrictions - restrictions = ctx.bot.db.load('server_settings', key=ctx.message.guild.id, pluck='restrictions') or {} - # Now lets check the "from" restrictions - for from_restriction in restrictions.get('from', []): - # Get the source and destination - # Source should ALWAYS be a command in this case - source = from_restriction.get('source') - destination = from_restriction.get('destination') - # Convert destination to the object we want - destination = await utilities.convert(ctx, destination) - # If we couldn't find the destination, just continue with other restrictions - # Also if this restriction we're checking isn't for this command - if destination is None or source != ctx.command.qualified_name: - continue - - # This means that the type of restriction we have is `command from channel` - # Which means we do not want commands to be ran in this channel - if destination == ctx.message.channel: - return False - # This type is `command from Role` meaning anyone with this role can't run this command - elif destination in ctx.message.author.roles: - return False - # This is `command from Member` meaning this user specifically cannot run this command - elif destination == ctx.message.author: - return False - - # If we are here, then there are no blacklists stopping this from running - - # Now for the to restrictions this is a little different, we need to make a whitelist and - # see if our current channel is in this whitelist, as well as any whitelisted roles are in the author's roles - # Only if there is no whitelist, do we want to blanket return True - to_restrictions = restrictions.get('to', []) - if len(to_restrictions) == 0: - return True - - # Otherwise there is a whitelist, and we need to start it - whitelisted_channels = [] - whitelisted_roles = [] - - for to_restriction in to_restrictions: - # Get the source and destination - # Source should ALWAYS be a command in this case - source = to_restriction.get('source') - destination = to_restriction.get('destination') - # Convert destination to the object we want - destination = await utilities.convert(ctx, destination) - # If we couldn't find the destination, just continue with other restrictions - # Also if this restriction we're checking isn't for this command - if destination is None or source != ctx.command.qualified_name: - continue - - # Append to our two whitelists depending on what type this is - if isinstance(destination, discord.TextChannel): - whitelisted_channels.append(destination) - elif isinstance(destination, discord.Role): - whitelisted_roles.append(destination) - - if whitelisted_channels: - if ctx.channel not in whitelisted_channels: - return False - if whitelisted_roles: - if not any(x in ctx.message.author.roles for x in whitelisted_roles): - return False - - # If we have passed all of these, then we are allowed to run this command - # This looks like a whole lot, but all of these lists will be very tiny in almost all cases - # And only delving deep into the specific lists that may be large, will we finally see "large" lists - # Which means this still will not be slow in other cases +def check_restricted(ctx): + # Return true if this is a private channel, we'll handle that in the registering of the command + if type(ctx.message.channel) is discord.DMChannel: return True - return commands.check(predicate) + # First get all the restrictions + restrictions = ctx.bot.db.load('server_settings', key=ctx.message.guild.id, pluck='restrictions') or {} + # Now lets check the "from" restrictions + for from_restriction in restrictions.get('from', []): + # Get the source and destination + # Source should ALWAYS be a command in this case + source = from_restriction.get('source') + destination = from_restriction.get('destination') + # Convert destination to the object we want + destination = await utilities.convert(ctx, destination) + # If we couldn't find the destination, just continue with other restrictions + # Also if this restriction we're checking isn't for this command + if destination is None or source != ctx.command.qualified_name: + continue + + # This means that the type of restriction we have is `command from channel` + # Which means we do not want commands to be ran in this channel + if destination == ctx.message.channel: + return False + # This type is `command from Role` meaning anyone with this role can't run this command + elif destination in ctx.message.author.roles: + return False + # This is `command from Member` meaning this user specifically cannot run this command + elif destination == ctx.message.author: + return False + + # If we are here, then there are no blacklists stopping this from running + + # Now for the to restrictions this is a little different, we need to make a whitelist and + # see if our current channel is in this whitelist, as well as any whitelisted roles are in the author's roles + # Only if there is no whitelist, do we want to blanket return True + to_restrictions = restrictions.get('to', []) + if len(to_restrictions) == 0: + return True + + # Otherwise there is a whitelist, and we need to start it + whitelisted_channels = [] + whitelisted_roles = [] + + for to_restriction in to_restrictions: + # Get the source and destination + # Source should ALWAYS be a command in this case + source = to_restriction.get('source') + destination = to_restriction.get('destination') + # Convert destination to the object we want + destination = await utilities.convert(ctx, destination) + # If we couldn't find the destination, just continue with other restrictions + # Also if this restriction we're checking isn't for this command + if destination is None or source != ctx.command.qualified_name: + continue + + # Append to our two whitelists depending on what type this is + if isinstance(destination, discord.TextChannel): + whitelisted_channels.append(destination) + elif isinstance(destination, discord.Role): + whitelisted_roles.append(destination) + + if whitelisted_channels: + if ctx.channel not in whitelisted_channels: + return False + if whitelisted_roles: + if not any(x in ctx.message.author.roles for x in whitelisted_roles): + return False + + # If we have passed all of these, then we are allowed to run this command + # This looks like a whole lot, but all of these lists will be very tiny in almost all cases + # And only delving deep into the specific lists that may be large, will we finally see "large" lists + # Which means this still will not be slow in other cases + return True -def custom_perms(**perms): +def can_run(ctx, **perms): + # Return true if this is a private channel, we'll handle that in the registering of the command + if type(ctx.message.channel) is discord.DMChannel: + return True + + # Get the member permissions so that we can compare + guild_perms = ctx.message.author.guild_permissions + channel_perms = ctx.message.author.permissions_in(ctx.message.channel) + # Currently the library doesn't handle administrator overrides..so lets do this manually + if guild_perms.administrator: + return True + # Next, set the default permissions if one is not used, based on what was passed + # This will be overriden later, if we have custom permissions + required_perm = discord.Permissions.none() + for perm, setting in perms.items(): + setattr(required_perm, perm, setting) + + required_perm_value = ctx.bot.db.load('server_settings', key=ctx.message.guild.id, pluck='permissions') or {} + required_perm_value = required_perm_value.get(ctx.command.qualified_name) + if required_perm_value: + required_perm = discord.Permissions(required_perm_value) + + # Now just check if the person running the command has these permissions + return guild_perms >= required_perm or channel_perms >= required_perm + + +def can_run(**kwargs): def predicate(ctx): - # Return true if this is a private channel, we'll handle that in the registering of the command - if type(ctx.message.channel) is discord.DMChannel: - return True + # First check if the command requires ownership of the bot + if kwargs.pop("ownership", False) and not is_owner(ctx): + return False + # Next check if it requires any certain permissions + if kwargs and not can_run(ctx, **kwargs): + return False + # Next...check custom restrictions + if check_restricted(ctx): + return False + # Then if the user/channel should be ignored + if should_ignore(ctx): + return False + # Otherwise....we're good + return True - # Get the member permissions so that we can compare - guild_perms = ctx.message.author.guild_permissions - channel_perms = ctx.message.author.permissions_in(ctx.message.channel) - # Currently the library doesn't handle administrator overrides..so lets do this manually - if guild_perms.administrator: - return True - # Next, set the default permissions if one is not used, based on what was passed - # This will be overriden later, if we have custom permissions - required_perm = discord.Permissions.none() - for perm, setting in perms.items(): - setattr(required_perm, perm, setting) - - required_perm_value = ctx.bot.db.load('server_settings', key=ctx.message.guild.id, pluck='permissions') or {} - required_perm_value = required_perm_value.get(ctx.command.qualified_name) - if required_perm_value: - required_perm = discord.Permissions(required_perm_value) - - # Now just check if the person running the command has these permissions - return guild_perms >= required_perm or channel_perms >= required_perm - - predicate.perms = perms + predicate.perms = kwargs return commands.check(predicate)