Merge branch 'master' of https://github.com/Phxntxm/Bonfire
This commit is contained in:
commit
84baef2125
16 changed files with 159 additions and 69 deletions
12
README.md
12
README.md
|
@ -5,7 +5,7 @@ This is for a Discord bot using the discord.py wrapper made for fun, used in a c
|
||||||
If you'd like to add this bot to one of your own servers, please visit the following URL:
|
If you'd like to add this bot to one of your own servers, please visit the following URL:
|
||||||
https://discordapp.com/oauth2/authorize?client_id=183748889814237186&scope=bot&permissions=0
|
https://discordapp.com/oauth2/authorize?client_id=183748889814237186&scope=bot&permissions=0
|
||||||
|
|
||||||
This requires the discord.py library, as well as all of it's dependencies.
|
This requires the discord.py library, as well as all of its dependencies.
|
||||||
https://github.com/Rapptz/discord.py
|
https://github.com/Rapptz/discord.py
|
||||||
|
|
||||||
To save the data for the bot, rethinkdb is what is used:
|
To save the data for the bot, rethinkdb is what is used:
|
||||||
|
@ -20,6 +20,14 @@ py -3 -m pip install discord.py[voice] lxml fuzzywuzzy youtube_dl rethinkdb ruam
|
||||||
|
|
||||||
Note: ATM of writing this, Pillow 3.4.2 (the stable version...good job Pillow?) is broken, do not use pip's default to install this. This is why we're using Pillow==3.4.1 above, and not just Pillow
|
Note: ATM of writing this, Pillow 3.4.2 (the stable version...good job Pillow?) is broken, do not use pip's default to install this. This is why we're using Pillow==3.4.1 above, and not just Pillow
|
||||||
|
|
||||||
|
The joke command requires the fortune-mod package, which are installable on Linux and other Unix-based distros.
|
||||||
|
|
||||||
|
Debian, Ubuntu, etc.:
|
||||||
|
```
|
||||||
|
sudo apt install fortune-mod
|
||||||
|
```
|
||||||
|
If you're on Red Hat, Fedora, etc., replace ``apt`` with ``yum``. If you're on another Linux distro, I trust you know what package manager to use. If you're on Windows, you might want to check out [this guide](http://superuser.com/questions/683162/bsd-fortune-for-windows-command-prompt-or-dos), but you're on your own.
|
||||||
|
|
||||||
The only required file to modify would be the config.yml.sample file. The entries are as follows:
|
The only required file to modify would be the config.yml.sample file. The entries are as follows:
|
||||||
|
|
||||||
- bot_token: The token that can be retrieved from the [bot's application page](https://discordapp.com/developers/applications/me)
|
- bot_token: The token that can be retrieved from the [bot's application page](https://discordapp.com/developers/applications/me)
|
||||||
|
@ -36,6 +44,6 @@ The only required file to modify would be the config.yml.sample file. The entrie
|
||||||
- da_secret: The deviant art Secret, given with the da_id above
|
- da_secret: The deviant art Secret, given with the da_id above
|
||||||
- shard_count: This is the number of shards the bot is split over. 1 needs to be used if the bot is not being sharded
|
- shard_count: This is the number of shards the bot is split over. 1 needs to be used if the bot is not being sharded
|
||||||
- shard_id: This will be the ID of the shard in particular, 0 if sharding is not used
|
- shard_id: This will be the ID of the shard in particular, 0 if sharding is not used
|
||||||
- extensions: This is a list of the extensions loaded into the bot (check the cogs folder for the extensions available). The disabled playlist is a special entry....read that file for what it's purpose is....most likely you will not need it. Entries in this list need to be separated by ", " like in the example.
|
- extensions: This is a list of the extensions loaded into the bot (check the cogs folder for the extensions available). The disabled playlist is a special entry....read that file for what its purpose is....most likely you will not need it. Entries in this list need to be separated by ", " like in the example.
|
||||||
- db_*: This is the information for the rethinkdb database. The cert is the certificate used for driver connections
|
- db_*: This is the information for the rethinkdb database. The cert is the certificate used for driver connections
|
||||||
|
|
||||||
|
|
24
bot.py
24
bot.py
|
@ -10,13 +10,13 @@ import aiohttp
|
||||||
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from cogs.utils import config
|
from cogs import utils
|
||||||
|
|
||||||
opts = {'command_prefix': config.command_prefix,
|
opts = {'command_prefix': utils.command_prefix,
|
||||||
'description': config.bot_description,
|
'description': utils.bot_description,
|
||||||
'pm_help': None,
|
'pm_help': None,
|
||||||
'shard_count': config.shard_count,
|
'shard_count': utils.shard_count,
|
||||||
'shard_id': config.shard_id,
|
'shard_id': utils.shard_id,
|
||||||
'command_not_found': ''}
|
'command_not_found': ''}
|
||||||
|
|
||||||
bot = commands.Bot(**opts)
|
bot = commands.Bot(**opts)
|
||||||
|
@ -26,11 +26,11 @@ logging.basicConfig(level=logging.WARNING, filename='bonfire.log')
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_ready():
|
async def on_ready():
|
||||||
# Change the status upon connection to the default status
|
# Change the status upon connection to the default status
|
||||||
await bot.change_presence(game=discord.Game(name=config.default_status, type=0))
|
await bot.change_presence(game=discord.Game(name=utils.default_status, type=0))
|
||||||
|
|
||||||
if not hasattr(bot, 'uptime'):
|
if not hasattr(bot, 'uptime'):
|
||||||
bot.uptime = pendulum.utcnow()
|
bot.uptime = pendulum.utcnow()
|
||||||
|
await utils.db_check()
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
async def on_message(message):
|
async def on_message(message):
|
||||||
|
@ -51,7 +51,7 @@ async def process_command(ctx):
|
||||||
command = ctx.command
|
command = ctx.command
|
||||||
|
|
||||||
r_filter = {'command': command.qualified_name}
|
r_filter = {'command': command.qualified_name}
|
||||||
command_usage = await config.get_content('command_usage', r_filter)
|
command_usage = await utils.get_content('command_usage', r_filter)
|
||||||
if command_usage is None:
|
if command_usage is None:
|
||||||
command_usage = {'command': command.qualified_name}
|
command_usage = {'command': command.qualified_name}
|
||||||
else:
|
else:
|
||||||
|
@ -74,8 +74,8 @@ async def process_command(ctx):
|
||||||
command_usage['server_usage'] = total_server_usage
|
command_usage['server_usage'] = total_server_usage
|
||||||
|
|
||||||
# Save all the changes
|
# Save all the changes
|
||||||
if not await config.update_content('command_usage', command_usage, r_filter):
|
if not await utils.update_content('command_usage', command_usage, r_filter):
|
||||||
await config.add_content('command_usage', command_usage, r_filter)
|
await utils.add_content('command_usage', command_usage, r_filter)
|
||||||
|
|
||||||
|
|
||||||
@bot.event
|
@bot.event
|
||||||
|
@ -126,6 +126,6 @@ async def on_command_error(error, ctx):
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
bot.remove_command('help')
|
bot.remove_command('help')
|
||||||
|
|
||||||
for e in config.extensions:
|
for e in utils.extensions:
|
||||||
bot.load_extension(e)
|
bot.load_extension(e)
|
||||||
bot.run(config.bot_token)
|
bot.run(utils.bot_token)
|
||||||
|
|
|
@ -207,6 +207,12 @@ class Game:
|
||||||
|
|
||||||
# Lets create our main deck, and shuffle it
|
# Lets create our main deck, and shuffle it
|
||||||
self.deck = utils.Deck()
|
self.deck = utils.Deck()
|
||||||
|
# So apparently, it is possible, with 10 players and nearly everyone/everyone busting
|
||||||
|
# To actually deplete the deck, and cause it to return None, and mess up later
|
||||||
|
# Due to this, lets make put 2 decks in here
|
||||||
|
_deck2 = utils.Deck()
|
||||||
|
self.deck.insert(list(_deck2.draw(52)))
|
||||||
|
del _deck2
|
||||||
self.deck.shuffle()
|
self.deck.shuffle()
|
||||||
# The dealer
|
# The dealer
|
||||||
self.dealer = Player('Dealer')
|
self.dealer = Player('Dealer')
|
||||||
|
@ -282,8 +288,8 @@ class Game:
|
||||||
fmt = "You got a blackjack {0.member.mention}!\n\n{0}".format(player)
|
fmt = "You got a blackjack {0.member.mention}!\n\n{0}".format(player)
|
||||||
|
|
||||||
await self.bot.send_message(self.channel, fmt)
|
await self.bot.send_message(self.channel, fmt)
|
||||||
# Loop through each player (as long as their status is playing)
|
# 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']:
|
for entry in [p for p in self.players if p['status'] == 'playing' and hasattr(p['player'], 'bet')]:
|
||||||
player = entry['player']
|
player = entry['player']
|
||||||
|
|
||||||
# Let them know it's their turn to play
|
# Let them know it's their turn to play
|
||||||
|
|
|
@ -71,7 +71,7 @@ class Core:
|
||||||
entries = sorted(utils.get_all_commands(self.bot))
|
entries = sorted(utils.get_all_commands(self.bot))
|
||||||
try:
|
try:
|
||||||
pages = utils.Pages(self.bot, message=ctx.message, entries=entries)
|
pages = utils.Pages(self.bot, message=ctx.message, entries=entries)
|
||||||
await pages.paginate()
|
await pages.paginate(start_page=page)
|
||||||
except utils.CannotPaginate as e:
|
except utils.CannotPaginate as e:
|
||||||
await self.bot.say(str(e))
|
await self.bot.say(str(e))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -79,6 +79,8 @@ class Deviantart:
|
||||||
data = await utils.request(self.base_url, payload=params)
|
data = await utils.request(self.base_url, payload=params)
|
||||||
if data is None:
|
if data is None:
|
||||||
continue
|
continue
|
||||||
|
elif not data['results']:
|
||||||
|
continue
|
||||||
|
|
||||||
result = data['results'][0]
|
result = data['results'][0]
|
||||||
cache[da_name] = result
|
cache[da_name] = result
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
from discord.ext.commands.cooldowns import BucketType
|
from discord.ext.commands.cooldowns import BucketType
|
||||||
from .utils import config
|
|
||||||
from .utils import checks
|
from . import utils
|
||||||
from .utils import utilities
|
|
||||||
import discord
|
import discord
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ class Interaction:
|
||||||
not p2 == player_id and not p1 == player_id}
|
not p2 == player_id and not p1 == player_id}
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@checks.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
async def hug(self, ctx, user: discord.Member = None):
|
async def hug(self, ctx, user: discord.Member = None):
|
||||||
"""Makes me hug a person!
|
"""Makes me hug a person!
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ class Interaction:
|
||||||
await self.bot.say(fmt.format(user.display_name))
|
await self.bot.say(fmt.format(user.display_name))
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@checks.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
async def avatar(self, ctx, member: discord.Member = None):
|
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)
|
"""Provides an image for the provided person's avatar (yours if no other member is provided)
|
||||||
|
|
||||||
|
@ -134,7 +134,7 @@ class Interaction:
|
||||||
|
|
||||||
url = member.avatar_url
|
url = member.avatar_url
|
||||||
if ctx.message.server.me.permissions_in(ctx.message.channel).attach_files:
|
if ctx.message.server.me.permissions_in(ctx.message.channel).attach_files:
|
||||||
file = await utilities.download_image(url)
|
file = await utils.download_image(url)
|
||||||
if file is None:
|
if file is None:
|
||||||
await self.bot.say(url)
|
await self.bot.say(url)
|
||||||
else:
|
else:
|
||||||
|
@ -149,7 +149,7 @@ class Interaction:
|
||||||
|
|
||||||
@commands.group(pass_context=True, no_pm=True, invoke_without_command=True)
|
@commands.group(pass_context=True, no_pm=True, invoke_without_command=True)
|
||||||
@commands.cooldown(1, 180, BucketType.user)
|
@commands.cooldown(1, 180, BucketType.user)
|
||||||
@checks.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
async def battle(self, ctx, player2: discord.Member):
|
async def battle(self, ctx, player2: discord.Member):
|
||||||
"""Challenges the mentioned user to a battle
|
"""Challenges the mentioned user to a battle
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ class Interaction:
|
||||||
await self.bot.say(fmt.format(ctx, player2))
|
await self.bot.say(fmt.format(ctx, player2))
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@checks.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
async def accept(self, ctx):
|
async def accept(self, ctx):
|
||||||
"""Accepts the battle challenge
|
"""Accepts the battle challenge
|
||||||
|
|
||||||
|
@ -206,13 +206,13 @@ class Interaction:
|
||||||
# All we need to do is change what order the challengers are printed/added as a paramater
|
# All we need to do is change what order the challengers are printed/added as a paramater
|
||||||
if random.SystemRandom().randint(0, 1):
|
if random.SystemRandom().randint(0, 1):
|
||||||
await self.bot.say(fmt.format(battleP1.mention, battleP2.mention))
|
await self.bot.say(fmt.format(battleP1.mention, battleP2.mention))
|
||||||
await utilities.update_records('battle_records', battleP1, battleP2)
|
await utils.update_records('battle_records', battleP1, battleP2)
|
||||||
else:
|
else:
|
||||||
await self.bot.say(fmt.format(battleP2.mention, battleP1.mention))
|
await self.bot.say(fmt.format(battleP2.mention, battleP1.mention))
|
||||||
await utilities.update_records('battle_records', battleP2, battleP1)
|
await utils.update_records('battle_records', battleP2, battleP1)
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@checks.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
async def decline(self, ctx):
|
async def decline(self, ctx):
|
||||||
"""Declines the battle challenge
|
"""Declines the battle challenge
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ class Interaction:
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@commands.cooldown(1, 180, BucketType.user)
|
@commands.cooldown(1, 180, BucketType.user)
|
||||||
@checks.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
async def boop(self, ctx, boopee: discord.Member = None, *, message = ""):
|
async def boop(self, ctx, boopee: discord.Member = None, *, message = ""):
|
||||||
"""Boops the mentioned person
|
"""Boops the mentioned person
|
||||||
|
|
||||||
|
@ -259,19 +259,19 @@ class Interaction:
|
||||||
return
|
return
|
||||||
|
|
||||||
r_filter = {'member_id': booper.id}
|
r_filter = {'member_id': booper.id}
|
||||||
boops = await config.get_content('boops', r_filter)
|
boops = await utils.get_content('boops', r_filter)
|
||||||
if boops is not None:
|
if boops is not None:
|
||||||
boops = boops[0]['boops']
|
boops = boops[0]['boops']
|
||||||
# If the booper has never booped the member provided, assure it's 0
|
# If the booper has never booped the member provided, assure it's 0
|
||||||
amount = boops.get(boopee.id, 0) + 1
|
amount = boops.get(boopee.id, 0) + 1
|
||||||
boops[boopee.id] = amount
|
boops[boopee.id] = amount
|
||||||
|
|
||||||
await config.update_content('boops', {'boops': boops}, r_filter)
|
await utils.update_content('boops', {'boops': boops}, r_filter)
|
||||||
else:
|
else:
|
||||||
entry = {'member_id': booper.id,
|
entry = {'member_id': booper.id,
|
||||||
'boops': {boopee.id: 1}}
|
'boops': {boopee.id: 1}}
|
||||||
|
|
||||||
await config.add_content('boops', entry, r_filter)
|
await utils.add_content('boops', entry, r_filter)
|
||||||
amount = 1
|
amount = 1
|
||||||
|
|
||||||
fmt = "{0.mention} has just booped {1.mention}{3}! That's {2} times now!"
|
fmt = "{0.mention} has just booped {1.mention}{3}! That's {2} times now!"
|
||||||
|
|
|
@ -233,7 +233,7 @@ class Mod:
|
||||||
# If we don't find custom permissions, get the required permission for a command
|
# 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.custom_perms, if custom_perms isn't found, we'll get an IndexError
|
||||||
try:
|
try:
|
||||||
custom_perms = [func for func in cmd.utils if "custom_perms" in func.__qualname__][0]
|
custom_perms = [func for func in cmd.checks if "custom_perms" in func.__qualname__][0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
# Loop through and check if there is a check called is_owner
|
# 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
|
# If we loop through and don't find one, this means that the only other choice is to be
|
||||||
|
|
|
@ -12,6 +12,7 @@ import re
|
||||||
import os
|
import os
|
||||||
import glob
|
import glob
|
||||||
import socket
|
import socket
|
||||||
|
import inspect
|
||||||
|
|
||||||
if not discord.opus.is_loaded():
|
if not discord.opus.is_loaded():
|
||||||
discord.opus.load_opus('/usr/lib64/libopus.so.0')
|
discord.opus.load_opus('/usr/lib64/libopus.so.0')
|
||||||
|
@ -320,6 +321,34 @@ class Music:
|
||||||
pass
|
pass
|
||||||
await self.bot.delete_message(message)
|
await self.bot.delete_message(message)
|
||||||
|
|
||||||
|
@commands.command(pass_context=True)
|
||||||
|
@commands.check(utils.is_owner)
|
||||||
|
async def vdebug(self, ctx, *, code : str):
|
||||||
|
"""Evaluates code."""
|
||||||
|
code = code.strip('` ')
|
||||||
|
python = '```py\n{}\n```'
|
||||||
|
result = None
|
||||||
|
|
||||||
|
env = {
|
||||||
|
'bot': self.bot,
|
||||||
|
'ctx': ctx,
|
||||||
|
'message': ctx.message,
|
||||||
|
'server': ctx.message.server,
|
||||||
|
'channel': ctx.message.channel,
|
||||||
|
'author': ctx.message.author
|
||||||
|
}
|
||||||
|
|
||||||
|
env.update(globals())
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = eval(code, env)
|
||||||
|
if inspect.isawaitable(result):
|
||||||
|
result = await result
|
||||||
|
except Exception as e:
|
||||||
|
await self.bot.say(python.format(type(e).__name__ + ': ' + str(e)))
|
||||||
|
return
|
||||||
|
|
||||||
|
await self.bot.say(python.format(result))
|
||||||
|
|
||||||
@commands.command(pass_context=True, no_pm=True)
|
@commands.command(pass_context=True, no_pm=True)
|
||||||
@utils.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
|
@ -355,7 +384,8 @@ class Music:
|
||||||
except discord.InvalidArgument:
|
except discord.InvalidArgument:
|
||||||
await self.bot.say('This is not a voice channel...')
|
await self.bot.say('This is not a voice channel...')
|
||||||
except (asyncio.TimeoutError, discord.ConnectionClosed):
|
except (asyncio.TimeoutError, discord.ConnectionClosed):
|
||||||
await self.bot.say("I failed to connect! This can sometimes be caused by your server region being far away."
|
await self.bot.say("I failed to connect! This usually happens if I don't have permission to join the"
|
||||||
|
" channel, but can sometimes be caused by your server region being far away."
|
||||||
" Otherwise this is an issue on Discord's end, causing the connect to timeout!")
|
" Otherwise this is an issue on Discord's end, causing the connect to timeout!")
|
||||||
await self.remove_voice_client(channel.server)
|
await self.remove_voice_client(channel.server)
|
||||||
else:
|
else:
|
||||||
|
@ -376,7 +406,8 @@ class Music:
|
||||||
try:
|
try:
|
||||||
success = await self.create_voice_client(summoned_channel)
|
success = await self.create_voice_client(summoned_channel)
|
||||||
except (asyncio.TimeoutError, discord.ConnectionClosed):
|
except (asyncio.TimeoutError, discord.ConnectionClosed):
|
||||||
await self.bot.say("I failed to connect! This can sometimes be caused by your server region being far away."
|
await self.bot.say("I failed to connect! This usually happens if I don't have permission to join the"
|
||||||
|
" channel, but can sometimes be caused by your server region being far away."
|
||||||
" Otherwise this is an issue on Discord's end, causing the connect to timeout!")
|
" Otherwise this is an issue on Discord's end, causing the connect to timeout!")
|
||||||
await self.remove_voice_client(summoned_channel.server)
|
await self.remove_voice_client(summoned_channel.server)
|
||||||
return False
|
return False
|
||||||
|
@ -525,8 +556,9 @@ class Music:
|
||||||
|
|
||||||
# Stop playing whatever song is playing.
|
# Stop playing whatever song is playing.
|
||||||
if state.is_playing():
|
if state.is_playing():
|
||||||
player = state.player
|
state.player.stop()
|
||||||
player.stop()
|
|
||||||
|
state.songs.clear()
|
||||||
|
|
||||||
# This will stop cancel the audio event we're using to loop through the queue
|
# This will stop cancel the audio event we're using to loop through the queue
|
||||||
# Then erase the voice_state entirely, and disconnect from the channel
|
# Then erase the voice_state entirely, and disconnect from the channel
|
||||||
|
|
|
@ -10,9 +10,6 @@ import aiohttp
|
||||||
import pendulum
|
import pendulum
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
getter = re.compile(r'`(?!`)(.*?)`')
|
|
||||||
multi = re.compile(r'```(.*?)```', re.DOTALL)
|
|
||||||
|
|
||||||
|
|
||||||
class Owner:
|
class Owner:
|
||||||
"""Commands that can only be used by Phantom, bot management commands"""
|
"""Commands that can only be used by Phantom, bot management commands"""
|
||||||
|
@ -35,32 +32,32 @@ class Owner:
|
||||||
|
|
||||||
@commands.command(pass_context=True)
|
@commands.command(pass_context=True)
|
||||||
@commands.check(utils.is_owner)
|
@commands.check(utils.is_owner)
|
||||||
async def debug(self, ctx):
|
async def debug(self, ctx, *, code : str):
|
||||||
"""Executes code"""
|
"""Evaluates code."""
|
||||||
# Eval and exec have different useful purposes, so use both
|
code = code.strip('` ')
|
||||||
|
python = '```py\n{}\n```'
|
||||||
|
result = None
|
||||||
|
|
||||||
|
env = {
|
||||||
|
'bot': self.bot,
|
||||||
|
'ctx': ctx,
|
||||||
|
'message': ctx.message,
|
||||||
|
'server': ctx.message.server,
|
||||||
|
'channel': ctx.message.channel,
|
||||||
|
'author': ctx.message.author
|
||||||
|
}
|
||||||
|
|
||||||
|
env.update(globals())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
result = eval(code, env)
|
||||||
# `Get all content in this format`
|
|
||||||
match_single = getter.findall(ctx.message.content)
|
|
||||||
# ```\nGet all content in this format```
|
|
||||||
match_multi = multi.findall(ctx.message.content)
|
|
||||||
|
|
||||||
if match_single:
|
|
||||||
result = eval(match_single[0])
|
|
||||||
|
|
||||||
# In case the result needs to be awaited, handle that
|
|
||||||
if inspect.isawaitable(result):
|
if inspect.isawaitable(result):
|
||||||
result = await result
|
result = await result
|
||||||
await self.bot.say("```\n{0}```".format(result))
|
except Exception as e:
|
||||||
elif match_multi:
|
await self.bot.say(python.format(type(e).__name__ + ': ' + str(e)))
|
||||||
# Internal method to send the message to the channel, of whatever is passed
|
return
|
||||||
def r(v):
|
|
||||||
self.bot.loop.create_task(self.bot.say("```\n{}```".format(v)))
|
|
||||||
|
|
||||||
exec(match_multi[0])
|
await self.bot.say(python.format(result))
|
||||||
except Exception as error:
|
|
||||||
fmt = 'An error occurred while processing this request: ```py\n{}: {}\n```'
|
|
||||||
await self.bot.say(fmt.format(type(error).__name__, error))
|
|
||||||
|
|
||||||
@commands.command(pass_context=True)
|
@commands.command(pass_context=True)
|
||||||
@commands.check(utils.is_owner)
|
@commands.check(utils.is_owner)
|
||||||
|
|
|
@ -97,7 +97,7 @@ class Picarto:
|
||||||
server_alerts = await utils.get_content('server_alerts', {'server_id': server_id})
|
server_alerts = await utils.get_content('server_alerts', {'server_id': server_id})
|
||||||
try:
|
try:
|
||||||
channel_id = server_alerts[0]['channel_id']
|
channel_id = server_alerts[0]['channel_id']
|
||||||
except IndexError:
|
except (IndexError, TypeError):
|
||||||
channel_id = server_id
|
channel_id = server_id
|
||||||
channel = self.bot.get_channel(channel_id)
|
channel = self.bot.get_channel(channel_id)
|
||||||
# Get the member that has just gone live
|
# Get the member that has just gone live
|
||||||
|
|
|
@ -89,7 +89,7 @@ class Twitch:
|
||||||
continue
|
continue
|
||||||
server_alerts = await utils.get_content('server_alerts', {'server_id': server_id})
|
server_alerts = await utils.get_content('server_alerts', {'server_id': server_id})
|
||||||
channel_id = server_id
|
channel_id = server_id
|
||||||
if len(server_alerts) > 0:
|
if server_alerts is not None and len(server_alerts) > 0:
|
||||||
channel_id = server_alerts[0].get('channel_id')
|
channel_id = server_alerts[0].get('channel_id')
|
||||||
channel = self.bot.get_channel(channel_id)
|
channel = self.bot.get_channel(channel_id)
|
||||||
# Get the member that has just gone live
|
# Get the member that has just gone live
|
||||||
|
@ -210,6 +210,7 @@ class Twitch:
|
||||||
await self.bot.say("I am already set to notify in this server...")
|
await self.bot.say("I am already set to notify in this server...")
|
||||||
else:
|
else:
|
||||||
await utils.update_content('twitch', {'servers': r.row['servers'].append(ctx.message.server.id)}, r_filter)
|
await utils.update_content('twitch', {'servers': r.row['servers'].append(ctx.message.server.id)}, r_filter)
|
||||||
|
await self.bot.say("This server will now be notified if you go live")
|
||||||
|
|
||||||
@notify.command(name='on', aliases=['start,yes'], pass_context=True, no_pm=True)
|
@notify.command(name='on', aliases=['start,yes'], pass_context=True, no_pm=True)
|
||||||
@utils.custom_perms(send_messages=True)
|
@utils.custom_perms(send_messages=True)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from .cards import Deck
|
from .cards import Deck
|
||||||
from .checks import is_owner, custom_perms, is_pm
|
from .checks import is_owner, custom_perms, is_pm, db_check
|
||||||
from .config import *
|
from .config import *
|
||||||
from .utilities import *
|
from .utilities import *
|
||||||
from .images import create_banner
|
from .images import create_banner
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import rethinkdb as r
|
||||||
|
|
||||||
from discord.ext import commands
|
from discord.ext import commands
|
||||||
import discord
|
import discord
|
||||||
|
@ -6,6 +7,46 @@ from . import config
|
||||||
|
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
|
|
||||||
|
# The list of tables needed for the database
|
||||||
|
table_list = ['battle_records', 'battling', 'boops', 'bot_data', 'command_usage', 'custom_permissions',
|
||||||
|
'deviantart', 'motd', 'nsfw_channels', 'overwatch', 'picarto', 'prefixes', 'raffles',
|
||||||
|
'rules', 'server_alerts', 'strawpolls', 'tags', 'tictactoe', 'twitch', 'user_notifications']
|
||||||
|
|
||||||
|
|
||||||
|
async def db_check():
|
||||||
|
"""Used to check if the required database/tables are setup"""
|
||||||
|
db_opts = config.db_opts
|
||||||
|
|
||||||
|
r.set_loop_type('asyncio')
|
||||||
|
# First try to connect, and see if the correct information was provided
|
||||||
|
try:
|
||||||
|
conn = await r.connect(**db_opts)
|
||||||
|
except r.errors.ReqlDriverError:
|
||||||
|
print("Cannot connect to the RethinkDB instance with the following information: {}".format(db_opts))
|
||||||
|
|
||||||
|
print("The RethinkDB instance you have setup may be down, otherwise please ensure you setup a"\
|
||||||
|
" RethinkDB instance, and you have provided the correct database information in config.yml")
|
||||||
|
quit()
|
||||||
|
|
||||||
|
# Get the current databases and check if the one we need is there
|
||||||
|
dbs = await r.db_list().run(conn)
|
||||||
|
if db_opts['db'] not in dbs:
|
||||||
|
# If not, we want to create it
|
||||||
|
print('Couldn\'t find database {}...creating now'.format(db_opts['db']))
|
||||||
|
await r.db_create(db_opts['db']).run(conn)
|
||||||
|
# Then add all the tables
|
||||||
|
for table in table_list:
|
||||||
|
print("Creating table {}...".format(table))
|
||||||
|
await r.table_create(table).run(conn)
|
||||||
|
print("Done!")
|
||||||
|
else:
|
||||||
|
# Otherwise, if the database is setup, make sure all the required tables are there
|
||||||
|
tables = await r.table_list().run(conn)
|
||||||
|
for table in table_list:
|
||||||
|
if table not in tables:
|
||||||
|
print("Creating table {}...".format(table))
|
||||||
|
await r.table_create(table).run(conn)
|
||||||
|
print("Done checking tables!")
|
||||||
|
|
||||||
def is_owner(ctx):
|
def is_owner(ctx):
|
||||||
return ctx.message.author.id in config.owner_ids
|
return ctx.message.author.id in config.owner_ids
|
||||||
|
|
|
@ -58,6 +58,8 @@ steam_key = global_config.get("steam_key", "")
|
||||||
youtube_key = global_config.get("youtube_key", "")
|
youtube_key = global_config.get("youtube_key", "")
|
||||||
# The key for Osu API calls
|
# The key for Osu API calls
|
||||||
osu_key = global_config.get('osu_key', '')
|
osu_key = global_config.get('osu_key', '')
|
||||||
|
# The key for League of Legends API calls
|
||||||
|
lol_key = global_config.get('lol_key', '')
|
||||||
# The keys needed for deviant art calls
|
# The keys needed for deviant art calls
|
||||||
da_id = global_config.get("da_id", "")
|
da_id = global_config.get("da_id", "")
|
||||||
da_secret = global_config.get("da_secret", "")
|
da_secret = global_config.get("da_secret", "")
|
||||||
|
|
|
@ -169,9 +169,9 @@ class Pages:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
async def paginate(self):
|
async def paginate(self, start_page=1):
|
||||||
"""Actually paginate the entries and run the interactive loop if necessary."""
|
"""Actually paginate the entries and run the interactive loop if necessary."""
|
||||||
await self.show_page(1, first=True)
|
await self.show_page(start_page, first=True)
|
||||||
|
|
||||||
while self.paginating:
|
while self.paginating:
|
||||||
react = await self.bot.wait_for_reaction(message=self.message, check=self.react_check, timeout=120.0)
|
react = await self.bot.wait_for_reaction(message=self.message, check=self.react_check, timeout=120.0)
|
||||||
|
|
1
riot.txt
Normal file
1
riot.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
fe04e897-b34e-4bf5-b79e-ccd5664bbd54
|
Loading…
Reference in a new issue