1
0
Fork 0
mirror of synced 2024-05-20 12:32:26 +12:00

Update to work with the rewrite: Batch 1

This commit is contained in:
Phxntxm 2017-03-05 20:45:44 -06:00
parent 4b4649b0de
commit 23e69a01c6
10 changed files with 357 additions and 412 deletions

View file

@ -34,17 +34,17 @@ class Blackjack:
# When we're done with the game, we need to delete the game itself and remove it's instance from games
# To do this, it needs to be able to access this instance of Blackjack
game = Game(self.bot, message, self)
self.games[message.server.id] = game
self.games[message.guild.id] = game
@commands.group(pass_context=True, no_pm=True, aliases=['bj'], invoke_without_command=True)
@commands.group(no_pm=True, aliases=['bj'], invoke_without_command=True)
@utils.custom_perms(send_messages=True)
async def blackjack(self, ctx):
"""Creates a game/joins the current running game of blackjack
EXAMPLE: !blackjack
RESULT: A new game of blackjack!"""
# Get this server's game if it exists
game = self.games.get(ctx.message.server.id)
# Get this guild's game if it exists
game = self.games.get(ctx.message.guild.id)
# If it doesn't, start one
if game is None:
self.create_game(ctx.message)
@ -54,15 +54,15 @@ class Blackjack:
# If it worked, they're ready to play
if status:
fmt = "{} has joined the game of blackjack, and will be able to play next round!"
await self.bot.say(fmt.format(ctx.message.author.display_name))
await ctx.send(fmt.format(ctx.message.author.display_name))
else:
# Otherwise, lets check *why* they couldn't join
if game.playing(ctx.message.author):
await self.bot.say("You are already playing! Wait for your turn!")
await ctx.send("You are already playing! Wait for your turn!")
else:
await self.bot.say("There are already a max number of players playing/waiting to play!")
await ctx.send("There are already a max number of players playing/waiting to play!")
@blackjack.command(pass_context=True, no_pm=True, name='leave', aliases=['quit'])
@blackjack.command(no_pm=True, name='leave', aliases=['quit'])
@utils.custom_perms(send_messages=True)
async def blackjack_leave(self, ctx):
"""Leaves the current game of blackjack
@ -70,37 +70,37 @@ class Blackjack:
EXAMPLE: !blackjack leave
RESULT: You stop losing money in blackjack"""
# Get this server's game if it exists
game = self.games.get(ctx.message.server.id)
# Get this guild's game if it exists
game = self.games.get(ctx.message.guild.id)
if game is None:
await self.bot.say("There are currently no games of Blackjack running!")
await ctx.send("There are currently no games of Blackjack running!")
return
status = game.leave(ctx.message.author)
if status:
await self.bot.say("You have left the game, and will be removed at the end of this round")
await ctx.send("You have left the game, and will be removed at the end of this round")
else:
await self.bot.say("Either you have already bet, or you are not even playing right now!")
await ctx.send("Either you have already bet, or you are not even playing right now!")
@blackjack.command(pass_context=True, no_pm=True, name='forcestop', aliases=['stop'])
@utils.custom_perms(manage_server=True)
@blackjack.command(no_pm=True, name='forcestop', aliases=['stop'])
@utils.custom_perms(manage_guild=True)
async def blackjack_stop(self, ctx):
"""Forces the game to stop, mostly for use if someone has gone afk
EXAMPLE: !blackjack forcestop
RESULT: No more blackjack spam"""
# Get this server's game if it exists
game = self.games.get(ctx.message.server.id)
# Get this guild's game if it exists
game = self.games.get(ctx.message.guild.id)
if game is None:
await self.bot.say("There are currently no games of Blackjack running!")
await ctx.send("There are currently no games of Blackjack running!")
return
game.task.cancel()
del self.games[ctx.message.server.id]
await self.bot.say("The blackjack game running here has just ended")
del self.games[ctx.message.guild.id]
await ctx.send("The blackjack game running here has just ended")
def FOIL(a, b):
@ -226,7 +226,7 @@ class Game:
async def game_task(self):
"""The task to handle the entire game"""
while len(self.players) > 0:
await self.bot.send_message(self.channel, "A new round has started!!")
await self.channel.send("A new round has started!!")
# First wait for bets
await self.bet_task()
@ -253,25 +253,25 @@ class Game:
await self.cleanup()
# If we reach the end of this loop, that means there are no more players
del self.bj.games[self.channel.server.id]
del self.bj.games[self.channel.guild.id]
async def dealer_task(self):
"""The task handling the dealer's play after all players have stood"""
fmt = "It is the dealer's turn to play\n\n{}".format(self.dealer)
msg = await self.bot.send_message(self.channel, fmt)
msg = await self.channel.send(fmt)
while True:
await asyncio.sleep(1)
if self.dealer.bust:
fmt = msg.content + "\n\nDealer has busted!!"
await self.bot.edit_message(msg, fmt)
await msg.edit(content=fmt)
return
for num in self.dealer.count:
if num > 16:
return
self.hit(self.dealer)
fmt = "It is the dealer's turn to play\n\n{}".format(self.dealer)
msg = await self.bot.edit_message(msg, fmt)
msg = await msg.edit(content=fmt)
async def round_task(self):
"""The task handling the round itself, asking each person to hit or stand"""
@ -280,21 +280,25 @@ class Game:
# A differen task will handle if a player hit blackjack to start (so they would not be 'playing')
# Our check to make sure a valid 'command' was provided
check = lambda m: m.content.lower() in ['hit', 'stand', 'double']
def check(m):
if m.channel == self.channel && m.author = player.member:
return m.content.lower() in ['hit', 'stand', 'double']
else:
return False
# First lets handle the blackjacks
for entry in [p for p in self.players if p['status'] == 'blackjack']:
player = entry['player']
fmt = "You got a blackjack {0.member.mention}!\n\n{0}".format(player)
await self.bot.send_message(self.channel, fmt)
await self.channel.send(fmt)
# Loop through each player (as long as their status is playing) and they have bet chips
for entry in [p for p in self.players if p['status'] == 'playing' and hasattr(p['player'], 'bet')]:
player = entry['player']
# Let them know it's their turn to play
fmt = "It is your turn to play {0.member.mention}\n\n{0}".format(player)
await self.bot.send_message(self.channel, fmt)
await self.channel.send(fmt)
# If they're not playing anymore (i.e. they busted, are standing, etc.) then we don't want to keep asking
# them to hit or stand
@ -302,37 +306,28 @@ class Game:
# Ask if they want to hit or stand
fmt = "Hit, stand, or double?"
await self.bot.send_message(self.channel, fmt)
msg = await self.bot.wait_for_message(timeout=60, author=player.member, channel=self.channel,
check=check)
await self.channel.send(fmt)
# If they took to long, make them stand so the next person can play
if msg is None:
await self.bot.send_message(self.channel, "Took to long! You're standing!")
try:
msg = await self.bot.wait_for('message', timeout=60, check=check)
except asyncio.TimeoutError:
await self.channel.send("Took to long! You're standing!")
entry['status'] = 'stand'
# If they want to hit
elif 'hit' in msg.content.lower():
self.hit(player)
await self.bot.send_message(self.channel, player)
# If they want to stand
elif 'stand' in msg.content.lower():
self.stand(player)
elif 'double' in msg.content.lower():
self.double(player)
await self.bot.send_message(self.channel, player)
# TODO: Handle double, split
else:
# If they want to hit
if 'hit' in msg.content.lower():
self.hit(player)
await self.channel.send(player)
# If they want to stand
elif 'stand' in msg.content.lower():
self.stand(player)
elif 'double' in msg.content.lower():
self.double(player)
await self.channel.send(player)
# TODO: Handle double, split
async def bet_task(self):
"""Performs the task of betting"""
def check(_msg):
"""Makes sure the message provided is within the min and max bets"""
try:
msg_length = int(_msg.content)
return self.min_bet <= msg_length <= self.max_bet
except ValueError:
return _msg.content.lower() == 'skip'
# There is one situation that we want to allow that means we cannot loop through players like normally would
# be the case: Betting has started; while one person is betting, another joins This means our list has
# changed, and neither based on the length or looping through the list itself will handle this To handle
@ -348,28 +343,43 @@ class Game:
entry = players[0]
player = entry['player']
def check(_msg):
"""Makes sure the message provided is within the min and max bets"""
if _msg.channel == self.channel and _msg.author == player.member:
try:
msg_length = int(_msg.content)
return self.min_bet <= msg_length <= self.max_bet
except ValueError:
return _msg.content.lower() == 'skip'
else:
return false
fmt = "Your turn to bet {0.member.mention}, your current chips are: {0.chips}\n" \
"Current min bet is {1}, current max bet is {2}\n" \
"Place your bet now (please provide only the number;" \
"'skip' if you would like to leave this game)".format(player, self.min_bet, self.max_bet)
await self.bot.send_message(self.channel, fmt)
msg = await self.bot.wait_for_message(timeout=60, author=player.member, channel=self.channel, check=check)
if msg is None:
await self.bot.send_message(self.channel, "You took too long! You're sitting this round out")
await self.channel.send(fmt)
try:
msg = await self.bot.wait_for("message", timeout=60, check=check)
except asyncio.TimeoutError:
await self.channel.send("You took too long! You're sitting this round out")
entry['status'] = 'stand'
elif msg.content.lower() == 'skip':
await self.bot.send_message(self.channel, "Alright, you've been removed from the game")
self.leave(player.member)
else:
num = int(msg.content)
# Set the new bet, and remove it from this players chip total
if num <= player.chips:
player.bet = num
player.chips -= num
entry['status'] = 'bet'
if msg.content.lower() == 'skip':
await self.channel.send("Alright, you've been removed from the game")
self.leave(player.member)
else:
await self.bot.send_message(self.channel, "You can't bet more than you have!!")
num = int(msg.content)
# Set the new bet, and remove it from this players chip total
if num <= player.chips:
player.bet = num
player.chips -= num
entry['status'] = 'bet'
else:
await self.channel.send("You can't bet more than you have!!")
# Call this so that we can correct the list, if someone has left or join
self.player_cleanup()
@ -464,7 +474,7 @@ class Game:
# Add that to the main string
fmt += "Blackjacks: {}\n".format(_fmt)
await self.bot.send_message(self.channel, fmt)
await self.channel.send(fmt)
# Do the same for the dealers hand
cards = list(self.dealer.hand.draw(self.dealer.hand.count))
@ -481,10 +491,10 @@ class Game:
self.players.extend(self._added_players)
self._added_players.clear()
# What we want to do is remove any players that are in the game and have left the server
# What we want to do is remove any players that are in the game and have left the guild
for entry in self.players:
m = entry['player'].member
if m not in self.channel.server.members:
if m not in self.channel.guild.members:
self._removed_players.append(entry['player'])
# Remove the players who left

View file

@ -10,7 +10,7 @@ from enum import Enum
class Chess:
def __init__(self, bot):
self.bot = bot
# Our format for games is going to be a little different, because we do want to allow multiple games per server
# Our format for games is going to be a little different, because we do want to allow multiple games per guild
# Format should be {'server_id': [Game, Game, Game]}
self.games = {}
@ -91,18 +91,18 @@ class Chess:
return MoveStatus.invalid
def get_game(self, player):
"""Provides the game this player is playing, in this server"""
server_games = self.games.get(player.server.id, [])
for game in server_games:
"""Provides the game this player is playing, in this guild"""
guild_games = self.games.get(player.guild.id, [])
for game in guild_games:
if player in game.challengers.values():
return game
return None
def in_game(self, player):
"""Checks to see if a player is playing in a game right now, in this server"""
server_games = self.games.get(player.server.id, [])
for game in server_games:
"""Checks to see if a player is playing in a game right now, in this guild"""
guild_games = self.games.get(player.guild.id, [])
for game in guild_games:
if player in game.challengers.values():
return True
@ -111,13 +111,13 @@ class Chess:
def start_game(self, player1, player2):
game = Game(player1, player2)
try:
self.games[player1.server.id].append(game)
self.games[player1.guild.id].append(game)
except KeyError:
self.games[player1.server.id] = [game]
self.games[player1.guild.id] = [game]
return game
@commands.group(pass_contxt=True, invoke_without_command=True)
@commands.group(invoke_without_command=True)
@checks.custom_perms(send_messages=True)
async def chess(self, ctx, *, move):
"""Moves a piece based on the notation provided
@ -142,45 +142,45 @@ class Chess:
EXAMPLE: !rook to d4"""
result = self.play(ctx.message.author, move)
if result is MoveStatus.invalid:
await self.bot.say("That was an invalid move!")
await ctx.send("That was an invalid move!")
elif result is MoveStatus.wrong_turn:
await self.bot.say("It is not your turn to play on your game in this server!")
await ctx.send("It is not your turn to play on your game in this guild!")
elif result is MoveStatus.no_game:
await self.bot.say("You are not currently playing a game on this server!")
await ctx.send("You are not currently playing a game on this guild!")
elif result is MoveStatus.valid:
game = self.get_game(ctx.message.author)
link = game.draw_board()
await self.bot.upload(link)
@commands.command(pass_context=True)
@commands.command()
@checks.custom_perms(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 server at a time
You can play one game on a single guild at a time
EXAMPLE: !chess start @Victim
RESULT: A new chess game! Good luck~"""
# Lets first check our permissions; we're not going to create a text based board
# So we need to be able to attach files in order to send the board
if not ctx.message.channel.permissions_for(ctx.message.server.me).attach_files:
await self.bot.say(
if not ctx.message.channel.permissions_for(ctx.message.guild.me).attach_files:
await ctx.send(
"I need to be able to send pictures to provide the board! Please ask someone with mange roles permission, to grant me attach files permission if you want to play this")
return
# Make sure the author and player 2 are not in a game already
if self.in_game(ctx.message.author):
await self.bot.say("Sorry, but you can only be in one game per server at a time")
await ctx.send("Sorry, but you can only be in one game per guild at a time")
return
if self.in_game(player2):
await self.bot.say("Sorry, but {} is already in a game on this server!".format(player2.display_name))
await ctx.send("Sorry, but {} is already in a game on this guild!".format(player2.display_name))
return
# Start the game
game = self.start_game(ctx.message.author, player2)
player1 = game.challengers.get('white')
await self.bot.say(
await ctx.send(
"{} you have started a chess game with {}\n\n{} will be white this game, and is going first.\nIf you need information about the notation used to play, run {}help chess".format(
ctx.message.author.display_name, player2.display_name, ctx.prefix))
@ -209,7 +209,7 @@ class Game:
self.reset_board()
# The point of chess revolves around the king's position
# Due to this, we're going to use the king's position a lot, so lets save this variable
# Due to this, we're going to use the king's position a lot, so lets save this variable
self.w_king_pos = (0, 4)
self.b_king_pos = (7, 4)
@ -388,7 +388,7 @@ class Game:
def check(self):
"""Checks our current board, and checks (based on whose turn it is) if we're in a 'check' state"""
# To check for a check, what we should do is loop through the board
# Then check if it's the the current players turn's piece, and compare to moving to the king's position
# Then check if it's the the current players turn's piece, and compare to moving to the king's position
for x, row in enumerate(self.board):
for y, piece in enumerate(row):
if self.white_turn and re.search('B.', piece) and self.valid_move((x, y), self.b_king_pos):

View file

@ -23,30 +23,7 @@ class Core:
self.results_per_page = 10
self.commands = None
def find_command(self, command):
# This method ensures the command given is valid. We need to loop through commands
# As self.bot.commands only includes parent commands
# So we are splitting the command in parts, looping through the commands
# And getting the subcommand based on the next part
# If we try to access commands of a command that isn't a group
# We'll hit an AttributeError, meaning an invalid command was given
# If we loop through and don't find anything, cmd will still be None
# And we'll report an invalid was given as well
cmd = None
for part in command.split():
try:
if cmd is None:
cmd = self.bot.commands.get(part)
else:
cmd = cmd.commands.get(part)
except AttributeError:
cmd = None
break
return cmd
@commands.command(pass_context=True)
@commands.command()
@utils.custom_perms(send_messages=True)
async def help(self, ctx, *, message=None):
"""This command is used to provide a link to the help URL.
@ -65,7 +42,7 @@ class Core:
try:
page = int(message)
except:
cmd = self.find_command(message)
cmd = self.bot.get_command(message)
if cmd is None:
entries = sorted(utils.get_all_commands(self.bot))
@ -73,7 +50,7 @@ class Core:
pages = utils.Pages(self.bot, message=ctx.message, entries=entries)
await pages.paginate(start_page=page)
except utils.CannotPaginate as e:
await self.bot.say(str(e))
await ctx.send(str(e))
else:
# Get the description for a command
description = cmd.help
@ -100,11 +77,11 @@ class Core:
if subcommands:
embed.add_field(name='Subcommands', value="\n".join(subcommands), inline=False)
await self.bot.say(embed=embed)
await ctx.send(embed=embed)
@commands.command()
@utils.custom_perms(send_messages=True)
async def motd(self, *, date=None):
async def motd(self, ctx, *, date=None):
"""This command can be used to print the current MOTD (Message of the day)
This will most likely not be updated every day, however messages will still be pushed to this every now and then
@ -126,10 +103,10 @@ class Core:
motd = latest_motd['motd']
# This will be hit if we do not have any entries for motd
except TypeError:
await self.bot.say("No message of the day!")
await ctx.send("No message of the day!")
else:
fmt = "Last updated: {}\n\n{}".format(date, motd)
await self.bot.say(fmt)
await ctx.send(fmt)
else:
try:
r_filter = pendulum.parse(date)
@ -137,18 +114,18 @@ class Core:
date = motd[0]['date']
motd = motd[0]['motd']
fmt = "Message of the day for {}:\n\n{}".format(date, motd)
await self.bot.say(fmt)
await ctx.send(fmt)
# This one will be hit if we return None for that day
except TypeError:
await self.bot.say("No message of the day for {}!".format(date))
await ctx.send("No message of the day for {}!".format(date))
# This will be hit if pendulum fails to parse the date passed
except ValueError:
now = pendulum.utcnow().to_date_string()
await self.bot.say("Invalid date format! Try like {}".format(now))
await ctx.send("Invalid date format! Try like {}".format(now))
@commands.command()
@utils.custom_perms(send_messages=True)
async def calendar(self, month: str = None, year: int = None):
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
@ -176,30 +153,23 @@ class Core:
else:
month = months.get(month.lower())
if month is None:
await self.bot.say("Please provide a valid Month!")
await ctx.send("Please provide a valid Month!")
return
# If year was not passed, use the current year
if year is None:
year = datetime.datetime.today().year
# Here we create the actual "text" calendar that we are printing
cal = calendar.TextCalendar().formatmonth(year, month)
await self.bot.say("```\n{}```".format(cal))
await ctx.send("```\n{}```".format(cal))
@commands.command()
@utils.custom_perms(send_messages=True)
async def info(self):
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
# The only real use of doing it this way is easier editing if the info
# in this command is changed
bot_data = await utils.get_content('bot_data')
total_data = {'member_count': 0,
'server_count': 0}
for entry in bot_data:
total_data['member_count'] += entry['member_count']
total_data['server_count'] += entry['server_count']
# Create the original embed object
opts = {'title': 'Dev Server',
'description': 'Join the server above for any questions/suggestions about me.',
@ -207,8 +177,8 @@ class Core:
embed = discord.Embed(**opts)
# Add the normal values
embed.add_field(name='Total Servers', value=total_data['server_count'])
embed.add_field(name='Total Members', value=total_data['member_count'])
embed.add_field(name='Total Servers', value=len(self.bot.servers))
embed.add_field(name='Total Members', value=len(set(self.bot.get_all_members())))
# Count the variable values; hangman, tictactoe, etc.
hm_games = len(self.bot.get_cog('Hangman').games)
@ -233,20 +203,20 @@ class Core:
embed.add_field(name='Uptime', value=(pendulum.utcnow() - self.bot.uptime).in_words())
embed.set_footer(text=self.bot.description)
await self.bot.say(embed=embed)
await ctx.send(embed=embed)
@commands.command()
@utils.custom_perms(send_messages=True)
async def uptime(self):
async def uptime(self, ctx):
"""Provides a printout of the current bot's uptime
EXAMPLE: !uptime
RESULT: A BAJILLION DAYS"""
await self.bot.say("Uptime: ```\n{}```".format((pendulum.utcnow() - self.bot.uptime).in_words()))
await ctx.send("Uptime: ```\n{}```".format((pendulum.utcnow() - self.bot.uptime).in_words()))
@commands.command(aliases=['invite'])
@utils.custom_perms(send_messages=True)
async def addbot(self):
async def addbot(self, ctx):
"""Provides a link that you can use to add me to a server
EXAMPLE: !addbot
@ -261,13 +231,17 @@ class Core:
perms.embed_links = True
perms.read_message_history = True
perms.attach_files = True
perms.speak = True
perms.connect = True
perms.attach_files = True
perms.add_reactions = True
app_info = await self.bot.application_info()
await self.bot.say("Use this URL to add me to a server that you'd like!\n{}"
await ctx.send("Use this URL to add me to a server that you'd like!\n{}"
.format(discord.utils.oauth_url(app_info.id, perms)))
@commands.command()
@utils.custom_perms(send_messages=True)
async def doggo(self):
async def doggo(self, ctx):
"""Use this to print a random doggo image.
EXAMPLE: !doggo
@ -275,7 +249,7 @@ class Core:
# Find a random image based on how many we currently have
f = random.SystemRandom().choice(glob.glob('images/doggo*'))
with open(f, 'rb') as f:
await self.bot.upload(f)
await ctx.send(file=f)
@commands.command()
@utils.custom_perms(send_messages=True)
@ -287,11 +261,11 @@ class Core:
# Find a random image based on how many we currently have
f = random.SystemRandom().choice(glob.glob('images/snek*'))
with open(f, 'rb') as f:
await self.bot.upload(f)
await ctx.send(file=f)
@commands.command()
@utils.custom_perms(send_messages=True)
async def joke(self):
async def joke(self, ctx):
"""Prints a random riddle
EXAMPLE: !joke
@ -302,13 +276,13 @@ class Core:
try:
fortune = subprocess.check_output(
fortune_command.split()).decode("utf-8")
await self.bot.say(fortune)
await ctx.send(fortune)
except discord.HTTPException:
pass
else:
break
@commands.command(pass_context=True)
@commands.command()
@utils.custom_perms(send_messages=True)
async def roll(self, ctx, notation: str = "d6"):
"""Rolls a die based on the notation given
@ -325,7 +299,7 @@ class Core:
# Check if something like ed3 was provided, or something else entirely
# was provided
except (AttributeError, ValueError):
await self.bot.say("Please provide the die notation in #d#!")
await ctx.send("Please provide the die notation in #d#!")
return
# Dice will be None if d# was provided, assume this means 1d#
@ -334,13 +308,13 @@ class Core:
# have it set
dice = int(dice)
if dice > 10:
await self.bot.say("I'm not rolling more than 10 dice, I have tiny hands")
await ctx.send("I'm not rolling more than 10 dice, I have tiny hands")
return
if num > 100:
await self.bot.say("What die has more than 100 sides? Please, calm down")
await ctx.send("What die has more than 100 sides? Please, calm down")
return
if num <= 1:
await self.bot.say("A {} sided die? You know that's impossible right?".format(num))
await ctx.send("A {} sided die? You know that's impossible right?".format(num))
return
value_str = ", ".join(str(random.SystemRandom().randint(1, num))
@ -350,7 +324,7 @@ class Core:
fmt = '{0.message.author.name} has rolled a {2} sided die and got the number {3}!'
else:
fmt = '{0.message.author.name} has rolled {1}, {2} sided dice and got the numbers {3}!'
await self.bot.say(fmt.format(ctx, dice, num, value_str))
await ctx.send(fmt.format(ctx, dice, num, value_str))
def setup(bot):

View file

@ -59,9 +59,7 @@ class Deviantart:
try:
for entry in content:
user = discord.utils.get(self.bot.get_all_members(), id=entry['member_id'])
# If we're sharded, we might not be able to find this user.
# If the bot is not in the server with the member either
# If the bot is not in the server with the member, we might not be able to find this user.
if user is None:
continue
@ -97,7 +95,7 @@ class Deviantart:
result['title'],
result['author']['username'],
result['url'])
await self.bot.send_message(user, fmt)
await user.sendfmt)
# Now we can update the user's last updated for this DA
# We want to do this whether or not our last if statement was met
r_filter = {'member_id': user.id}
@ -110,12 +108,12 @@ class Deviantart:
@commands.group()
@utils.custom_perms(send_messages=True)
async def da(self):
async def da(self, ctx):
"""This provides a sort of 'RSS' feed for subscribed to artists.
Subscribe to artists, and I will PM you when new posts come out from these artists"""
pass
@da.command(pass_context=True, name='sub', aliases=['add', 'subscribe'])
@da.command(name='sub', aliases=['add', 'subscribe'])
@utils.custom_perms(send_messages=True)
async def da_sub(self, ctx, *, username):
"""This can be used to add a feed to your notifications.
@ -130,7 +128,7 @@ class Deviantart:
if content is None:
entry = {'member_id': ctx.message.author.id, 'subbed': [username], 'last_updated': {}}
await utils.add_content('deviantart', entry, r_filter)
await self.bot.say("You have just subscribed to {}!".format(username))
await ctx.send("You have just subscribed to {}!".format(username))
elif content[0]['subbed'] is None or username not in content[0]['subbed']:
if content[0]['subbed'] is None:
sub_list = [username]
@ -138,9 +136,9 @@ class Deviantart:
content[0]['subbed'].append(username)
sub_list = content[0]['subbed']
await utils.update_content('deviantart', {'subbed': sub_list}, r_filter)
await self.bot.say("You have just subscribed to {}!".format(username))
await ctx.send("You have just subscribed to {}!".format(username))
else:
await self.bot.say("You are already subscribed to that user!")
await ctx.send("You are already subscribed to that user!")
@da.command(pass_context=True, name='unsub', aliases=['delete', 'remove', 'unsubscribe'])
@utils.custom_perms(send_messages=True)
@ -153,13 +151,13 @@ class Deviantart:
content = await utils.get_content('deviantart', r_filter)
if content is None or content[0]['subbed'] is None:
await self.bot.say("You are not subscribed to anyone at the moment!")
await ctx.send("You are not subscribed to anyone at the moment!")
elif username in content[0]['subbed']:
content[0]['subbed'].remove(username)
await utils.update_content('deviantart', {'subbed': content[0]['subbed']}, r_filter)
await self.bot.say("You have just unsubscribed from {}!".format(username))
await ctx.send("You have just unsubscribed from {}!".format(username))
else:
await self.bot.say("You are not subscribed to that user!")
await ctx.send("You are not subscribed to that user!")
def setup(bot):

View file

@ -19,7 +19,7 @@ class Music:
async def on_voice_state_update(self, before, after):
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def progress(self, ctx):
"""Provides the progress of the current song
@ -28,7 +28,7 @@ class Music:
RESULT: 532 minutes! (Hopefully not)"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def join(self, ctx, *, channel: discord.Channel):
"""Joins a voice channel.
@ -37,7 +37,7 @@ class Music:
RESULT: I'm in the Music voice channel!"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def summon(self, ctx):
"""Summons the bot to join your voice channel.
@ -46,7 +46,7 @@ class Music:
RESULT: I'm in your voice channel!"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def play(self, ctx, *, song: str):
"""Plays a song.
@ -61,7 +61,7 @@ class Music:
"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(kick_members=True)
async def volume(self, ctx, value: int = None):
"""Sets the volume of the currently playing song.
@ -70,7 +70,7 @@ class Music:
RESULT: My volume is now set to 50"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(kick_members=True)
async def pause(self, ctx):
"""Pauses the currently played song.
@ -79,7 +79,7 @@ class Music:
RESULT: I'm paused!"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(kick_members=True)
async def resume(self, ctx):
"""Resumes the currently played song.
@ -88,7 +88,7 @@ class Music:
RESULT: Ain't paused no more!"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(kick_members=True)
async def stop(self, ctx):
"""Stops playing audio and leaves the voice channel.
@ -98,7 +98,7 @@ class Music:
RESULT: No more music"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def eta(self, ctx):
"""Provides an ETA on when your next song will play
@ -107,7 +107,7 @@ class Music:
RESULT: 5,000 days! Lol have fun"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def queue(self, ctx):
"""Provides a printout of the songs that are in the queue.
@ -121,7 +121,7 @@ class Music:
RESULT: A list of shitty songs you probably don't wanna listen to"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def queuelength(self, ctx):
"""Prints the length of the queue
@ -130,7 +130,7 @@ class Music:
RESULT: Probably 10 songs"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def skip(self, ctx):
"""Vote to skip a song. The song requester can automatically skip.
@ -142,7 +142,7 @@ class Music:
"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(kick_members=True)
async def modskip(self, ctx):
"""Forces a song skip, can only be used by a moderator
@ -151,7 +151,7 @@ class Music:
RESULT: No more terrible song :D"""
pass
@commands.command(pass_context=True, no_pm=True, enabled=False)
@commands.command(no_pm=True, enabled=False)
@checks.custom_perms(send_messages=True)
async def playing(self, ctx):
"""Shows info about the currently played song.

View file

@ -48,38 +48,17 @@ class StatsUpdate:
log.info('bots.discord.pw statistics returned {} for {}'.format(resp.status, payload))
async def on_server_join(self, server):
r_filter = {'shard_id': config.shard_id}
server_count = len(self.bot.servers)
member_count = len(set(self.bot.get_all_members()))
entry = {'server_count': server_count, 'member_count': member_count, "shard_id": config.shard_id}
# Check if this was successful, if it wasn't, that means a new shard was added and we need to add that entry
if not await config.update_content('bot_data', entry, r_filter):
await config.add_content('bot_data', entry, r_filter)
self.bot.loop.create_task(self.update())
async def on_server_leave(self, server):
r_filter = {'shard_id': config.shard_id}
server_count = len(self.bot.servers)
member_count = len(set(self.bot.get_all_members()))
entry = {'server_count': server_count, 'member_count': member_count, "shard_id": config.shard_id}
# Check if this was successful, if it wasn't, that means a new shard was added and we need to add that entry
if not await config.update_content('bot_data', entry, r_filter):
await config.add_content('bot_data', entry, r_filter)
self.bot.loop.create_task(self.update())
async def on_ready(self):
r_filter = {'shard_id': config.shard_id}
server_count = len(self.bot.servers)
member_count = len(set(self.bot.get_all_members()))
entry = {'server_count': server_count, 'member_count': member_count, "shard_id": config.shard_id}
# Check if this was successful, if it wasn't, that means a new shard was added and we need to add that entry
if not await config.update_content('bot_data', entry, r_filter):
await config.add_content('bot_data', entry, r_filter)
self.bot.loop.create_task(self.update())
async def on_member_join(self, member):
server = member.server
r_filter = {'server_id': server.id}
guild = member.guild
r_filter = {'server_id': guild.id}
notifications = await config.get_content('user_notifications', r_filter)
try:
@ -91,12 +70,12 @@ class StatsUpdate:
if not channel_id:
return
channel = server.get_channel(channel_id)
await self.bot.send_message(channel, "Welcome to the '{0.server.name}' server {0.mention}!".format(member))
channel = guild.get_channel(channel_id)
await channel.send("Welcome to the '{0.server.name}' server {0.mention}!".format(member))
async def on_member_remove(self, member):
server = member.server
r_filter = {'server_id': server.id}
guild = member.guild
r_filter = {'server_id': guild.id}
notifications = await config.get_content('user_notifications', r_filter)
try:
@ -109,9 +88,7 @@ class StatsUpdate:
return
channel = server.get_channel(channel_id)
await self.bot.send_message(channel,
"{0} has left the server, I hope it wasn't because of something I said :c".format(
member.display_name))
await channelsend("{0} has left the server, I hope it wasn't because of something I said :c".format(member.display_name))
def setup(bot):

View file

@ -104,10 +104,10 @@ class Hangman:
def create(self, word, ctx):
# Create a new game, then save it as the server's game
game = Game(word)
self.games[ctx.message.server.id] = game
self.games[ctx.message.guild.id] = game
return game
@commands.group(aliases=['hm'], pass_context=True, no_pm=True, invoke_without_command=True)
@commands.group(aliases=['hm'], no_pm=True, invoke_without_command=True)
@commands.cooldown(1, 7, BucketType.user)
@checks.custom_perms(send_messages=True)
async def hangman(self, ctx, *, guess):
@ -115,10 +115,10 @@ class Hangman:
EXAMPLE: !hangman e (or) !hangman The Phrase!
RESULT: Hopefully a win!"""
game = self.games.get(ctx.message.server.id)
game = self.games.get(ctx.message.guild.id)
if not game:
ctx.command.reset_cooldown(ctx)
await self.bot.say("There are currently no hangman games running!")
await ctx.send("There are currently no hangman games running!")
return
# Check if we are guessing a letter or a phrase. Only one letter can be guessed at a time
@ -128,7 +128,7 @@ class Hangman:
if len(guess) == 1:
if guess in game.guessed_letters:
ctx.command.reset_cooldown(ctx)
await self.bot.say("That letter has already been guessed!")
await ctx.send("That letter has already been guessed!")
# Return here as we don't want to count this as a failure
return
if game.guess_letter(guess):
@ -143,16 +143,16 @@ class Hangman:
if game.win():
fmt += " You guys got it! The word was `{}`".format(game.word)
del self.games[ctx.message.server.id]
del self.games[ctx.message.guild.id]
elif game.failed():
fmt += " Sorry, you guys failed...the word was `{}`".format(game.word)
del self.games[ctx.message.server.id]
del self.games[ctx.message.guild.id]
else:
fmt += str(game)
await self.bot.say(fmt)
await ctx.send(fmt)
@hangman.command(name='create', aliases=['start'], no_pm=True, pass_context=True)
@hangman.command(name='create', aliases=['start'], no_pm=True)
@checks.custom_perms(send_messages=True)
async def create_hangman(self, ctx):
"""This is used to create a new hangman game
@ -163,16 +163,16 @@ class Hangman:
# Only have one hangman game per server, since anyone
# In a server (except the creator) can guess towards the current game
if self.games.get(ctx.message.server.id) is not None:
await self.bot.say("Sorry but only one Hangman game can be running per server!")
if self.games.get(ctx.message.guild.id) is not None:
await ctx.send("Sorry but only one Hangman game can be running per server!")
return
game = self.create(random.SystemRandom().choice(phrases), ctx)
# Let them know the game has started, then print the current game so that the blanks are shown
await self.bot.say(
await ctx.send(
"Alright, a hangman game has just started, you can start guessing now!\n{}".format(str(game)))
@hangman.command(name='delete', aliases=['stop', 'remove', 'end'], pass_context=True, no_pm=True)
@hangman.command(name='delete', aliases=['stop', 'remove', 'end'], no_pm=True)
@checks.custom_perms(kick_members=True)
async def stop_game(self, ctx):
"""Force stops a game of hangman
@ -181,12 +181,12 @@ class Hangman:
EXAMPLE: !hangman stop
RESULT: No more men being hung"""
if self.games.get(ctx.message.server.id) is None:
await self.bot.say("There are no Hangman games running on this server!")
if self.games.get(ctx.message.guild.id) is None:
await ctx.send("There are no Hangman games running on this server!")
return
del self.games[ctx.message.server.id]
await self.bot.say("I have just stopped the game of Hangman, a new should be able to be started now!")
del self.games[ctx.message.guild.id]
await ctx.send("I have just stopped the game of Hangman, a new should be able to be started now!")
def setup(bot):

View file

@ -85,7 +85,7 @@ class Interaction:
self.battles = {}
def user_battling(self, ctx, player2=None):
battling = self.battles.get(ctx.message.server.id)
battling = self.battles.get(ctx.message.guild.id)
# If no one is battling, obviously the user is not battling
if battling is None:
@ -101,14 +101,14 @@ class Interaction:
# Handles removing the author from the dictionary of battles
def battling_off(self, ctx):
battles = self.battles.get(ctx.message.server.id) or {}
battles = self.battles.get(ctx.message.guild.id) or {}
player_id = ctx.message.author.id
# Create a new dictionary, exactly the way the last one was setup
# But don't include any that have the author's ID
self.battles[ctx.message.server.id] = {p1: p2 for p1, p2 in battles.items() if
self.battles[ctx.message.guild.id] = {p1: p2 for p1, p2 in battles.items() if
not p2 == player_id and not p1 == player_id}
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(send_messages=True)
async def hug(self, ctx, user: discord.Member = None):
"""Makes me hug a person!
@ -119,9 +119,9 @@ class Interaction:
user = ctx.message.author
fmt = random.SystemRandom().choice(hugs)
await self.bot.say(fmt.format(user.display_name))
await ctx.send(fmt.format(user.display_name))
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(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)
@ -133,21 +133,21 @@ class Interaction:
member = ctx.message.author
url = member.avatar_url
if ctx.message.server.me.permissions_in(ctx.message.channel).attach_files:
if ctx.message.guild.me.permissions_in(ctx.message.channel).attach_files:
file = await utils.download_image(url)
if file is None:
await self.bot.say(url)
await ctx.send(url)
else:
if '.gif' in url:
filename = 'avatar.gif'
else:
filename = 'avatar.webp'
file = utils.convert_to_jpeg(file)
await self.bot.upload(file, filename=filename)
await ctx.send(file=file, filename=filename)
else:
await self.bot.say(url)
await ctx.send(url)
@commands.group(pass_context=True, no_pm=True, invoke_without_command=True)
@commands.group(no_pm=True, invoke_without_command=True)
@commands.cooldown(1, 180, BucketType.user)
@utils.custom_perms(send_messages=True)
async def battle(self, ctx, player2: discord.Member):
@ -157,29 +157,29 @@ class Interaction:
RESULT: A battle to the death"""
if ctx.message.author.id == player2.id:
ctx.command.reset_cooldown(ctx)
await self.bot.say("Why would you want to battle yourself? Suicide is not the answer")
await ctx.send("Why would you want to battle yourself? Suicide is not the answer")
return
if self.bot.user.id == player2.id:
ctx.command.reset_cooldown(ctx)
await self.bot.say("I always win, don't even try it.")
await ctx.send("I always win, don't even try it.")
return
if self.user_battling(ctx, player2):
ctx.command.reset_cooldown(ctx)
await self.bot.say("You or the person you are trying to battle is already in a battle!")
await ctx.send("You or the person you are trying to battle is already in a battle!")
return
# Add the author and player provided in a new battle
battles = self.battles.get(ctx.message.server.id) or {}
battles = self.battles.get(ctx.message.guild.id) or {}
battles[ctx.message.author.id] = player2.id
self.battles[ctx.message.server.id] = battles
self.battles[ctx.message.guild.id] = battles
fmt = "{0.message.author.mention} has challenged you to a battle {1.mention}\n" \
"{0.prefix}accept or {0.prefix}decline"
# Add a call to turn off battling, if the battle is not accepted/declined in 3 minutes
self.bot.loop.call_later(180, self.battling_off, ctx)
await self.bot.say(fmt.format(ctx, player2))
await ctx.send(fmt.format(ctx, player2))
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(send_messages=True)
async def accept(self, ctx):
"""Accepts the battle challenge
@ -188,13 +188,13 @@ class Interaction:
RESULT: Hopefully the other person's death"""
# This is a check to make sure that the author is the one being BATTLED
# And not the one that started the battle
battles = self.battles.get(ctx.message.server.id) or {}
battles = self.battles.get(ctx.message.guild.id) or {}
p1 = [p1_id for p1_id, p2_id in battles.items() if p2_id == ctx.message.author.id]
if len(p1) == 0:
await self.bot.say("You are not currently being challenged to a battle!")
await ctx.send("You are not currently being challenged to a battle!")
return
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.server.members)
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.guild.members)
battleP2 = ctx.message.author
# Get a random win message from our list
@ -205,13 +205,13 @@ class Interaction:
# Randomize the order of who is printed/sent to the update system
# All we need to do is change what order the challengers are printed/added as a paramater
if random.SystemRandom().randint(0, 1):
await self.bot.say(fmt.format(battleP1.mention, battleP2.mention))
await ctx.send(fmt.format(battleP1.mention, battleP2.mention))
await utils.update_records('battle_records', battleP1, battleP2)
else:
await self.bot.say(fmt.format(battleP2.mention, battleP1.mention))
await ctx.send(fmt.format(battleP2.mention, battleP1.mention))
await utils.update_records('battle_records', battleP2, battleP1)
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(send_messages=True)
async def decline(self, ctx):
"""Declines the battle challenge
@ -220,20 +220,20 @@ class Interaction:
RESULT: You chicken out"""
# This is a check to make sure that the author is the one being BATTLED
# And not the one that started the battle
battles = self.battles.get(ctx.message.server.id) or {}
battles = self.battles.get(ctx.message.guild.id) or {}
p1 = [p1_id for p1_id, p2_id in battles.items() if p2_id == ctx.message.author.id]
if len(p1) == 0:
await self.bot.say("You are not currently being challenged to a battle!")
await ctx.send("You are not currently being challenged to a battle!")
return
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.server.members)
battleP1 = discord.utils.find(lambda m: m.id == p1[0], ctx.message.guild.members)
battleP2 = ctx.message.author
# There's no need to update the stats for the members if they declined the battle
self.battling_off(ctx)
await self.bot.say("{0} has chickened out! What a loser~".format(battleP2.mention, battleP1.mention))
await ctx.send("{0} has chickened out! What a loser~".format(battleP2.mention, battleP1.mention))
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@commands.cooldown(1, 180, BucketType.user)
@utils.custom_perms(send_messages=True)
async def boop(self, ctx, boopee: discord.Member = None, *, message = ""):
@ -244,18 +244,18 @@ class Interaction:
booper = ctx.message.author
if boopee is None:
ctx.command.reset_cooldown(ctx)
await self.bot.say("You try to boop the air, the air boops back. Be afraid....")
await ctx.send("You try to boop the air, the air boops back. Be afraid....")
return
# To keep formatting easier, keep it either "" or the message with a space in front
if message is not None:
message = " " + message
if boopee.id == booper.id:
ctx.command.reset_cooldown(ctx)
await self.bot.say("You can't boop yourself! Silly...")
await ctx.send("You can't boop yourself! Silly...")
return
if boopee.id == self.bot.user.id:
ctx.command.reset_cooldown(ctx)
await self.bot.say("Why the heck are you booping me? Get away from me >:c")
await ctx.send("Why the heck are you booping me? Get away from me >:c")
return
r_filter = {'member_id': booper.id}
@ -275,7 +275,7 @@ class Interaction:
amount = 1
fmt = "{0.mention} has just booped {1.mention}{3}! That's {2} times now!"
await self.bot.say(fmt.format(booper, boopee, amount, message))
await ctx.send(fmt.format(booper, boopee, amount, message))
def setup(bot):

View file

@ -17,13 +17,15 @@ class Links:
def __init__(self, bot):
self.bot = bot
@commands.command(pass_context=True, aliases=['g'])
@commands.command(aliases=['g'])
@utils.custom_perms(send_messages=True)
async def google(self, ctx, *, query: str):
"""Searches google for a provided query
EXAMPLE: !g Random cat pictures!
RESULT: Links to sites with random cat pictures!"""
await ctx.message.channel.trigger_typing()
url = "https://www.google.com/search"
# Turn safe filter on or off, based on whether or not this is a nsfw channel
@ -43,7 +45,7 @@ class Links:
data = await utils.request(url, payload=params, attr='text')
if data is None:
await self.bot.send_message(ctx.message.channel, "I failed to connect to google! (That can happen??)")
await ctx.send("I failed to connect to google! (That can happen??)")
return
# Convert to a BeautifulSoup element and loop through each result clasified by h3 tags with a class of 'r'
@ -55,7 +57,7 @@ class Links:
try:
result_url = re.search('(?<=q=).*(?=&sa=)', element.find('a').get('href')).group(0)
except AttributeError:
await self.bot.say("I couldn't find any results for {}!".format(query))
await ctx.send("I couldn't find any results for {}!".format(query))
return
# Get the next sibling, find the span where the description is, and get the text from this
@ -68,15 +70,17 @@ class Links:
fmt += '\n\n**URL**: <{}>\n**Description**: {}'.format(result_url, description)
fmt = "**Top 3 results for the query** _{}_:{}".format(query, fmt)
await self.bot.say(fmt)
await ctx.send(fmt)
@commands.command(aliases=['yt'], pass_context=True)
@commands.command(aliases=['yt'])
@utils.custom_perms(send_messages=True)
async def youtube(self, ctx, *, query: str):
"""Searches youtube for a provided query
EXAMPLE: !youtube Cat videos!
RESULT: Cat videos!"""
await ctx.message.channel.trigger_typing()
key = utils.youtube_key
url = "https://www.googleapis.com/youtube/v3/search"
params = {'key': key,
@ -87,13 +91,13 @@ class Links:
data = await utils.request(url, payload=params)
if data is None:
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to youtube!")
await ctx.send("Sorry but I failed to connect to youtube!")
return
try:
result = data['items'][0]
except IndexError:
await self.bot.say("I could not find any results with the search term {}".format(query))
await ctx.send("I could not find any results with the search term {}".format(query))
return
result_url = "https://youtube.com/watch?v={}".format(result['id']['videoId'])
@ -101,15 +105,17 @@ class Links:
description = result['snippet']['description']
fmt = "**Title:** {}\n\n**Description:** {}\n\n**URL:** <{}>".format(title, description, result_url)
await self.bot.say(fmt)
await ctx.send(fmt)
@commands.command(pass_context=True)
@commands.command()
@utils.custom_perms(send_messages=True)
async def wiki(self, ctx, *, query: str):
"""Pulls the top match for a specific term from wikipedia, and returns the result
EXAMPLE: !wiki Test
RESULT: A link to the wikipedia article for the word test"""
await ctx.message.channel.trigger_typing()
# All we need to do is search for the term provided, so the action, list, and format never need to change
base_url = "https://en.wikipedia.org/w/api.php"
params = {"action": "query",
@ -120,11 +126,11 @@ class Links:
data = await utils.request(base_url, payload=params)
if data is None:
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to Wikipedia!")
await ctx.send("Sorry but I failed to connect to Wikipedia!")
return
if len(data['query']['search']) == 0:
await self.bot.say("I could not find any results with that term, I tried my best :c")
await ctx.send("I could not find any results with that term, I tried my best :c")
return
# Wiki articles' URLs are in the format https://en.wikipedia.org/wiki/[Titlehere]
# Replace spaces with %20
@ -136,36 +142,38 @@ class Links:
snippet = re.sub('</span>', '', snippet)
snippet = re.sub('&quot;', '"', snippet)
await self.bot.say(
await ctx.send(
"Here is the best match I found with the query `{}`:\nURL: <{}>\nSnippet: \n```\n{}```".format(query, url,
snippet))
@commands.command(pass_context=True)
@commands.command()
@utils.custom_perms(send_messages=True)
async def urban(self, ctx, *, msg: str):
"""Pulls the top urbandictionary.com definition for a term
EXAMPLE: !urban a normal phrase
RESULT: Probably something lewd; this is urban dictionary we're talking about"""
await ctx.message.channel.trigger_typing()
url = "http://api.urbandictionary.com/v0/define"
params = {"term": msg}
try:
data = await utils.request(url, payload=params)
if data is None:
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to urban dictionary!")
await ctx.send("Sorry but I failed to connect to urban dictionary!")
return
# List is the list of definitions found, if it's empty then nothing was found
if len(data['list']) == 0:
await self.bot.say("No result with that term!")
await ctx.send("No result with that term!")
# If the list is not empty, use the first result and print it's defintion
else:
await self.bot.say(data['list'][0]['definition'])
await ctx.send(data['list'][0]['definition'])
# Urban dictionary has some long definitions, some might not be able to be sent
except discord.HTTPException:
await self.bot.say('```\nError: Definition is too long for me to send```')
await ctx.send('```\nError: Definition is too long for me to send```')
except KeyError:
await self.bot.say("Sorry but I failed to connect to urban dictionary!")
await ctx.send("Sorry but I failed to connect to urban dictionary!")
@commands.command(pass_context=True)
@utils.custom_perms(send_messages=True)
@ -174,6 +182,8 @@ class Links:
EXAMPLE: !derpi Rainbow Dash
RESULT: A picture of Rainbow Dash!"""
await ctx.message.channel.trigger_typing()
if len(search) > 0:
url = 'https://derpibooru.org/search.json'
@ -192,18 +202,16 @@ class Links:
else:
params['q'] += ", safe"
await self.bot.say("Looking up an image with those tags....")
try:
# Get the response from derpibooru and parse the 'search' result from it
data = await utils.request(url, payload=params)
if data is None:
await self.bot.send_message(ctx.message.channel, "Sorry but I failed to connect to Derpibooru!")
await ctx.send("Sorry but I failed to connect to Derpibooru!")
return
results = data['search']
except KeyError:
await self.bot.say("No results with that search term, {0}!".format(ctx.message.author.mention))
await ctx.send("No results with that search term, {0}!".format(ctx.message.author.mention))
return
# The first request we've made ensures there are results
@ -215,7 +223,7 @@ class Links:
params['page'] = random.SystemRandom().randint(1, pages)
data = await utils.request(url, payload=params)
if data is None:
await self.bot.say("Sorry but I failed to connect to Derpibooru!")
await ctx.send("Sorry but I failed to connect to Derpibooru!")
return
# Now get the results again
results = data['search']
@ -224,14 +232,14 @@ class Links:
index = random.SystemRandom().randint(0, len(results) - 1)
image_link = 'https://derpibooru.org/{}'.format(results[index]['id'])
else:
await self.bot.say("No results with that search term, {0}!".format(ctx.message.author.mention))
await ctx.send("No results with that search term, {0}!".format(ctx.message.author.mention))
return
else:
# If no search term was provided, search for a random image
# .url will be the URL we end up at, not the one requested.
# https://derpibooru.org/images/random redirects to a random image, so this is exactly what we want
image_link = await utils.request('https://derpibooru.org/images/random', attr='url')
await self.bot.say(image_link)
await ctx.send(image_link)
@commands.command(pass_context=True)
@utils.custom_perms(send_messages=True)
@ -242,19 +250,19 @@ class Links:
EXAMPLE: !e621 dragon
RESULT: A picture of a dragon (hopefully, screw your tagging system e621)"""
await ctx.message.channel.trigger_typing()
# This changes the formatting for queries, so we don't
# Have to use e621's stupid formatting when using the command
tags = tags.replace(' ', '_')
tags = tags.replace(',_', ' ')
url = 'https://e621.net/post/index.json'
params = {'limit': 320,
'tags': tags}
# e621 provides a way to change how many images can be shown on one request
# This gives more of a chance of random results, however it causes the lookup to take longer than most
# Due to this, send a message saying we're looking up the information first
await self.bot.say("Looking up an image with those tags....")
r_filter = {'channel_id': ctx.message.channel.id}
nsfw_channels = await utils.get_content("nsfw_channels", r_filter)
@ -266,8 +274,7 @@ class Links:
data = await utils.request(url, payload=params)
if data is None:
await self.bot.send_message(ctx.message.channel,
"Sorry, I had trouble connecting at the moment; please try again later")
await ctx.send("Sorry, I had trouble connecting at the moment; please try again later")
return
# Try to find an image from the list. If there were no results, we're going to attempt to find
@ -276,9 +283,9 @@ class Links:
# i.e. it responded with a 404/504/etc.
try:
rand_image = data[random.SystemRandom().randint(0, len(data) - 1)]['file_url']
await self.bot.say(rand_image)
await ctx.send(rand_image)
except (ValueError, KeyError):
await self.bot.say("No results with that tag {}".format(ctx.message.author.mention))
await ctx.send("No results with that tag {}".format(ctx.message.author.mention))
return

View file

@ -16,53 +16,30 @@ class Mod:
def __init__(self, bot):
self.bot = bot
def find_command(self, command):
# This method ensures the command given is valid. We need to loop through commands
# As self.bot.commands only includes parent commands
# So we are splitting the command in parts, looping through the commands
# And getting the subcommand based on the next part
# If we try to access commands of a command that isn't a group
# We'll hit an AttributeError, meaning an invalid command was given
# If we loop through and don't find anything, cmd will still be None
# And we'll report an invalid was given as well
cmd = None
for part in command.split():
try:
if cmd is None:
cmd = self.bot.commands.get(part)
else:
cmd = cmd.commands.get(part)
except AttributeError:
cmd = None
break
return cmd
@commands.command(pass_context=True, no_pm=True, aliases=['nick'])
@commands.command(no_pm=True, aliases=['nick'])
@utils.custom_perms(kick_members=True)
async def nickname(self, ctx, *, name=None):
"""Used to set the nickname for Bonfire (provide no nickname and it will reset)
EXAMPLE: !nick Music Bot
RESULT: My nickname is now music bot"""
await self.bot.change_nickname(ctx.message.server.me, name)
await self.bot.say("\N{OK HAND SIGN}")
RESULT: My nickname is now Music Bot"""
await ctx.message.server.me.edit(nick=name)
await ctx.send("\N{OK HAND SIGN}")
@commands.command(no_pm=True)
@utils.custom_perms(kick_members=True)
async def kick(self, member: discord.Member):
async def kick(self, ctx, member: discord.Member):
"""Used to kick a member from this server
EXAMPLE: !kick @Member
RESULT: They're kicked from the server?"""
try:
await self.bot.kick(member)
await self.bot.say("\N{OK HAND SIGN}")
await member.kick()
await ctx.send("\N{OK HAND SIGN}")
except discord.Forbidden:
await self.bot.say("But I can't, muh permissions >:c")
await ctx.send("But I can't, muh permissions >:c")
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(ban_members=True)
async def unban(self, ctx, member_id: int):
"""Used to unban a member from this server
@ -74,16 +51,15 @@ class Mod:
# Lets only accept an int for this method, in order to ensure only an ID is provided
# Due to that though, we need to ensure a string is passed as the member's ID
member = discord.Object(id=str(member_id))
try:
await self.bot.unban(ctx.message.server, member)
await self.bot.say("\N{OK HAND SIGN}")
await discord.http.unban(member.id, ctx.guild.id)
await ctx.send("\N{OK HAND SIGN}")
except discord.Forbidden:
await self.bot.say("But I can't, muh permissions >:c")
await ctx.send("But I can't, muh permissions >:c")
except discord.HTTPException:
await self.bot.say("Sorry, I failed to unban that user!")
await ctx.send("Sorry, I failed to unban that user!")
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(ban_members=True)
async def ban(self, ctx, *, member):
"""Used to ban a member
@ -95,31 +71,35 @@ class Mod:
# Lets first check if a user ID was provided, as that will be the easiest case to ban
if member.isdigit():
# First convert it to a discord object based on the ID that was given
member = discord.Object(id=member)
# Next, to ban from the server the API takes a server obejct and uses that ID
# So set "this" server as the member's server. This creates the "fake" member we need
member.server = ctx.message.server
try:
await discord.http.ban(member, ctx.guild.id)
await ctx.send("\N{OK HAND SIGN}")
except discord.Forbidden:
await ctx.send("But I can't, muh permissions >:c")
except discord.HTTPException:
await ctx.send("Sorry, I failed to ban that user!")
finally:
return
else:
# If no ID was provided, lets try to convert what was given using the internal coverter
converter = commands.converter.UserConverter(ctx, member)
converter = commands.converter.MemberConverter(ctx, member)
try:
member = converter.convert()
except commands.converter.BadArgument:
await self.bot.say(
await ctx.send(
'{} does not appear to be a valid member. If this member is not in this server, please provide '
'their ID'.format(member))
return
# Now lets try actually banning the member we've been given
try:
await self.bot.ban(member)
await self.bot.say("\N{OK HAND SIGN}")
await member.ban()
await ctx.send("\N{OK HAND SIGN}")
except discord.Forbidden:
await self.bot.say("But I can't, muh permissions >:c")
await ctx.send("But I can't, muh permissions >:c")
except discord.HTTPException:
await self.bot.say("Sorry, I failed to ban that user!")
await ctx.send("Sorry, I failed to ban that user!")
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(kick_members=True)
async def alerts(self, ctx, channel: discord.Channel):
"""This command is used to set a channel as the server's 'notifications' channel
@ -132,10 +112,10 @@ class Mod:
'channel_id': channel.id}
if not await utils.add_content('server_alerts', entry, r_filter):
await utils.update_content('server_alerts', entry, r_filter)
await self.bot.say("I have just changed this server's 'notifications' channel"
await ctx.send("I have just changed this server's 'notifications' channel"
"\nAll notifications will now go to `{}`".format(channel))
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(kick_members=True)
async def usernotify(self, ctx, on_off: str):
"""This command can be used to set whether or not you want user notificaitons to show
@ -148,22 +128,21 @@ class Mod:
# So we base this channel on it's own and not from alerts
# When mod logging becomes available, that will be kept to it's own channel if wanted as well
on_off = ctx.message.channel.id if re.search("(on|yes|true)", on_off.lower()) else None
r_filter = {'server_id': ctx.message.server.id}
entry = {'server_id': ctx.message.server.id,
r_filter = {'server_id': ctx.message.guild.id}
entry = {'server_id': ctx.message.guild.id,
'channel_id': on_off}
if not await utils.add_content('user_notifications', entry, r_filter):
await utils.update_content('user_notifications', entry, r_filter)
fmt = "notify" if on_off else "not notify"
await self.bot.say("This server will now {} if someone has joined or left".format(fmt))
await ctx.send("This server will now {} if someone has joined or left".format(fmt))
@commands.group(pass_context=True)
@commands.group()
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
if ctx.invoked_subcommand is None:
await self.bot.say('Invalid subcommand passed: {0.subcommand_passed}'.format(ctx))
pass
@nsfw.command(name="add", pass_context=True)
@nsfw.command(name="add")
@utils.custom_perms(kick_members=True)
async def nsfw_add(self, ctx):
"""Registers this channel as a 'nsfw' channel
@ -172,11 +151,11 @@ class Mod:
RESULT: ;)"""
r_filter = {'channel_id': ctx.message.channel.id}
if await utils.add_content('nsfw_channels', r_filter, r_filter):
await self.bot.say("This channel has just been registered as 'nsfw'! Have fun you naughties ;)")
await ctx.send("This channel has just been registered as 'nsfw'! Have fun you naughties ;)")
else:
await self.bot.say("This channel is already registered as 'nsfw'!")
await ctx.send("This channel is already registered as 'nsfw'!")
@nsfw.command(name="remove", aliases=["delete"], pass_context=True)
@nsfw.command(name="remove", aliases=["delete"])
@utils.custom_perms(kick_members=True)
async def nsfw_remove(self, ctx):
"""Removes this channel as a 'nsfw' channel
@ -185,11 +164,11 @@ class Mod:
RESULT: ;("""
r_filter = {'channel_id': ctx.message.channel.id}
if await utils.remove_content('nsfw_channels', r_filter):
await self.bot.say("This channel has just been unregistered as a nsfw channel")
await ctx.send("This channel has just been unregistered as a nsfw channel")
else:
await self.bot.say("This channel is not registered as a ''nsfw' channel!")
await ctx.send("This channel is not registered as a ''nsfw' channel!")
@commands.command(pass_context=True)
@commands.command()
@utils.custom_perms(kick_members=True)
async def say(self, ctx, *, msg: str):
"""Tells the bot to repeat what you say
@ -197,13 +176,13 @@ class Mod:
EXAMPLE: !say I really like orange juice
RESULT: I really like orange juice"""
fmt = "\u200B{}".format(msg)
await self.bot.say(fmt)
await ctx.send(fmt)
try:
await self.bot.delete_message(ctx.message)
await ctx.message.delete()
except:
pass
@commands.group(pass_context=True, invoke_without_command=True, no_pm=True)
@commands.group(invoke_without_command=True, no_pm=True)
@utils.custom_perms(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
@ -212,20 +191,20 @@ class Mod:
EXAMPLE: !perms help RESULT: Hopefully a result saying you just need send_messages permissions; otherwise lol
this server's admin doesn't like me """
if command is None:
await self.bot.say(
await ctx.send(
"Valid permissions are: ```\n{}```".format("\n".join("{}".format(i) for i in valid_perms)))
return
r_filter = {'server_id': ctx.message.server.id}
r_filter = {'server_id': ctx.message.guild.id}
server_perms = await utils.get_content('custom_permissions', r_filter)
try:
server_perms = server_perms[0]
except TypeError:
server_perms = {}
cmd = self.find_command(command)
cmd = self.bot.get_command(command)
if cmd is None:
await self.bot.say("That is not a valid command!")
await ctx.send("That is not a valid command!")
return
perms_value = server_perms.get(cmd.qualified_name)
@ -240,15 +219,15 @@ class Mod:
# Able to manage the server (for the utils on perm commands)
for func in cmd.utils:
if "is_owner" in func.__qualname__:
await self.bot.say("You need to own the bot to run this command")
await ctx.send("You need to own the bot to run this command")
return
await self.bot.say(
await ctx.send(
"You are required to have `manage_server` permissions to run `{}`".format(cmd.qualified_name))
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)
await self.bot.say(
await ctx.send(
"You are required to have `{}` permissions to run `{}`".format(perms, cmd.qualified_name))
else:
# Permissions are saved as bit values, so create an object based on that value
@ -256,10 +235,10 @@ class Mod:
# There's no need to check for errors here, as we ensure a permission is valid when adding it
permissions = discord.Permissions(perms_value)
needed_perm = [perm[0] for perm in permissions if perm[1]][0]
await self.bot.say("You need to have the permission `{}` "
await ctx.send("You need to have the permission `{}` "
"to use the command `{}` in this server".format(needed_perm, command))
@perms.command(name="add", aliases=["setup,create"], pass_context=True, no_pm=True)
@perms.command(name="add", aliases=["setup,create"], no_pm=True)
@commands.has_permissions(manage_server=True)
async def add_perms(self, ctx, *msg: str):
"""Sets up custom permissions on the provided command
@ -274,7 +253,7 @@ class Mod:
try:
permissions = msg[len(msg) - 1]
except IndexError:
await self.bot.say("Please provide the permissions you want to setup, the format for this must be in:\n"
await ctx.send("Please provide the permissions you want to setup, the format for this must be in:\n"
"`perms add <command> <permission>`")
return
@ -288,15 +267,15 @@ class Mod:
try:
setattr(perm_obj, permissions, True)
except AttributeError:
await self.bot.say("{} does not appear to be a valid permission! Valid permissions are: ```\n{}```"
await ctx.send("{} does not appear to be a valid permission! Valid permissions are: ```\n{}```"
.format(permissions, "\n".join(valid_perms)))
return
perm_value = perm_obj.value
cmd = self.find_command(command)
cmd = self.bot.get_command(command)
if cmd is None:
await self.bot.say(
await ctx.send(
"That command does not exist! You can't have custom permissions on a non-existant command....")
return
@ -305,12 +284,12 @@ class Mod:
# Which means I do not want to check custom permissions at all
# Currently the second case is only on adding and removing permissions, to avoid abuse on these
for check in cmd.checks:
if "is_owner" == check.__name__ or re.search("has_permissions", str(check)) is not None:
await self.bot.say("This command cannot have custom permissions setup!")
if "is_owner" == check.__name__ or "has_permissions" not in str(check):
await ctx.send("This command cannot have custom permissions setup!")
return
r_filter = {'server_id': ctx.message.server.id}
entry = {'server_id': ctx.message.server.id,
r_filter = {'server_id': ctx.message.guild.id}
entry = {'server_id': ctx.message.guild.id,
cmd.qualified_name: perm_value}
# In all other cases, I've used add_content before update_content
@ -322,10 +301,10 @@ class Mod:
# Same case as prefixes, for now, trigger a manual update
self.bot.loop.create_task(utils.cache['custom_permissions'].update())
await self.bot.say("I have just added your custom permissions; "
await ctx.send("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)
@perms.command(name="remove", aliases=["delete"], 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
@ -333,32 +312,32 @@ class Mod:
EXAMPLE: !perms remove play
RESULT: Freedom!"""
cmd = self.find_command(command)
cmd = self.bot.get_command(command)
if cmd is None:
await self.bot.say(
await ctx.send(
"That command does not exist! You can't have custom permissions on a non-existant command....")
return
r_filter = {'server_id': ctx.message.server.id}
await utils.replace_content('custom_permissions', r.row.without(cmd.qualified_name), r_filter)
await self.bot.say("I have just removed the custom permissions for {}!".format(cmd))
await ctx.send("I have just removed the custom permissions for {}!".format(cmd))
# Same case as prefixes, for now, trigger a manual update
self.bot.loop.create_task(utils.cache['custom_permissions'].update())
@commands.command(pass_context=True, no_pm=True)
@utils.custom_perms(manage_server=True)
@commands.command(no_pm=True)
@utils.custom_perms(manage_guild=True)
async def prefix(self, ctx, *, prefix: str):
"""This command can be used to set a custom prefix per server
EXAMPLE: !prefix new_prefix
RESULT: You probably screwing it up and not realizing you now need to do new_prefixprefix"""
r_filter = {'server_id': ctx.message.server.id}
r_filter = {'server_id': ctx.message.guild.id}
if prefix.lower().strip() == "none":
prefix = None
entry = {'server_id': ctx.message.server.id,
entry = {'server_id': ctx.message.guild.id,
'prefix': prefix}
if not await utils.add_content('prefixes', entry, r_filter):
@ -369,9 +348,9 @@ class Mod:
else:
fmt = "I have just updated the prefix for this server; you now need to call commands with `{0}`. " \
"For example, you can call this command again with {0}prefix".format(prefix)
await self.bot.say(fmt)
await ctx.send(fmt)
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(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
@ -379,15 +358,15 @@ class Mod:
EXAMPLE: !purge 50
RESULT: -50 messages in this channel"""
if not ctx.message.channel.permissions_for(ctx.message.server.me).manage_messages:
await self.bot.say("I do not have permission to delete messages...")
await ctx.send("I do not have permission to delete messages...")
return
try:
await self.bot.purge_from(ctx.message.channel, limit=limit)
await ctx.message.channel.purge(limit=limit)
except discord.HTTPException:
await self.bot.send_message(ctx.message.channel, "Detected messages that are too far back for me to delete;" \
" I can only bulk delete messages that are under 14 days old.")
@commands.command(pass_context=True, no_pm=True)
@commands.command(no_pm=True)
@utils.custom_perms(manage_messages=True)
async def prune(self, ctx, limit: int = 100):
"""This command can be used to prune messages from certain members
@ -403,48 +382,48 @@ class Mod:
# If no members are provided, assume we're trying to prune our own messages
members = ctx.message.mentions
if len(members) == 0:
members = [ctx.message.server.me]
members = [ctx.message.guild.me]
# If we're not setting the user to the bot, then we're deleting someone elses messages
# To do so, we need manage_messages permission, so check if we have that
elif not ctx.message.channel.permissions_for(ctx.message.server.me).manage_messages:
await self.bot.say("I do not have permission to delete messages...")
await ctx.send("I do not have permission to delete messages...")
return
# Since logs_from will give us any message, not just the user's we need
# We'll increment count, and stop deleting messages if we hit the limit.
count = 0
async for msg in self.bot.logs_from(ctx.message.channel):
async for msg in ctx.message.channel.history:
if msg.author in members:
try:
await self.bot.delete_message(msg)
await msg.delete()
count += 1
except discord.NotFound:
pass
if count >= limit:
break
msg = await self.bot.say("{} messages succesfully deleted".format(count))
await asyncio.sleep(60)
msg = await ctx.send("{} messages succesfully deleted".format(count))
await asyncio.sleep(5)
try:
await self.bot.delete_message(msg)
await msg.delete()
except discord.NotFound:
pass
@commands.group(aliases=['rule'], pass_context=True, no_pm=True, invoke_without_command=True)
@commands.group(aliases=['rule'], no_pm=True, invoke_without_command=True)
@utils.custom_perms(send_messages=True)
async def rules(self, ctx, rule: int = None):
"""This command can be used to view the current rules on the server
EXAMPLE: !rules 5
RESULT: Rule 5 is printed"""
r_filter = {'server_id': ctx.message.server.id}
r_filter = {'server_id': ctx.message.guild.id}
rules = await utils.get_content('rules', r_filter)
try:
rules = rules[0]['rules']
except TypeError:
await self.bot.say("This server currently has no rules on it! I see you like to live dangerously...")
await ctx.send("This server currently has no rules on it! I see you like to live dangerously...")
return
if len(rules) == 0:
await self.bot.say("This server currently has no rules on it! I see you like to live dangerously...")
await ctx.send("This server currently has no rules on it! I see you like to live dangerously...")
return
if rule is None:
@ -453,16 +432,16 @@ class Mod:
pages.title = "Rules for {}".format(ctx.message.server.name)
await pages.paginate()
except utils.CannotPaginate as e:
await self.bot.say(str(e))
await ctx.send(str(e))
else:
try:
fmt = rules[rule - 1]
except IndexError:
await self.bot.say("That rules does not exist.")
await ctx.send("That rules does not exist.")
return
await self.bot.say("Rule {}: \"{}\"".format(rule, fmt))
await ctx.send("Rule {}: \"{}\"".format(rule, fmt))
@rules.command(name='add', aliases=['create'], pass_context=True, no_pm=True)
@rules.command(name='add', aliases=['create'], no_pm=True)
@utils.custom_perms(manage_server=True)
async def rules_add(self, ctx, *, rule: str):
"""Adds a rule to this server's rules
@ -476,9 +455,9 @@ class Mod:
if not await utils.update_content('rules', update, r_filter):
await utils.add_content('rules', entry, r_filter)
await self.bot.say("I have just saved your new rule, use the rules command to view this server's current rules")
await ctx.send("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)
@rules.command(name='remove', aliases=['delete'], no_pm=True)
@utils.custom_perms(manage_server=True)
async def rules_delete(self, ctx, rule: int):
"""Removes one of the rules from the list of this server's rules
@ -489,9 +468,9 @@ class Mod:
r_filter = {'server_id': ctx.message.server.id}
update = {'rules': r.row['rules'].delete_at(rule - 1)}
if not await utils.update_content('rules', update, r_filter):
await self.bot.say("That is not a valid rule number, try running the command again.")
await ctx.send("That is not a valid rule number, try running the command again.")
else:
await self.bot.say("I have just removed that rule from your list of rules!")
await ctx.send("I have just removed that rule from your list of rules!")
def setup(bot):