2016-07-08 01:05:42 +12:00
|
|
|
#!/usr/local/bin/python3.5
|
2016-07-09 11:26:43 +12:00
|
|
|
import discord
|
2016-07-19 07:57:23 +12:00
|
|
|
import traceback
|
2016-07-31 02:59:35 +12:00
|
|
|
import logging
|
|
|
|
import datetime
|
2016-08-07 10:20:16 +12:00
|
|
|
import pendulum
|
2016-08-12 14:13:02 +12:00
|
|
|
import os
|
2017-02-13 11:40:28 +13:00
|
|
|
import aiohttp
|
2016-08-12 14:13:02 +12:00
|
|
|
|
2016-08-26 16:56:16 +12:00
|
|
|
os.chdir(os.path.dirname(os.path.realpath(__file__)))
|
2016-07-09 11:26:43 +12:00
|
|
|
|
2016-08-27 01:23:02 +12:00
|
|
|
from discord.ext import commands
|
2017-02-26 10:45:59 +13:00
|
|
|
from cogs import utils
|
2016-08-27 01:23:02 +12:00
|
|
|
|
2017-02-26 10:45:59 +13:00
|
|
|
opts = {'command_prefix': utils.command_prefix,
|
|
|
|
'description': utils.bot_description,
|
2016-08-31 07:16:24 +12:00
|
|
|
'pm_help': None,
|
2017-05-21 07:45:37 +12:00
|
|
|
'command_not_found': '',
|
|
|
|
'game': discord.Game(name=utils.default_status, type=0)}
|
2016-08-31 07:51:04 +12:00
|
|
|
|
2017-03-06 09:40:00 +13:00
|
|
|
bot = commands.AutoShardedBot(**opts)
|
2017-04-11 17:22:11 +12:00
|
|
|
logging.basicConfig(level=logging.INFO, filename='bonfire.log')
|
2016-07-08 10:10:24 +12:00
|
|
|
|
2016-07-31 12:20:55 +12:00
|
|
|
|
2016-07-08 01:05:42 +12:00
|
|
|
@bot.event
|
|
|
|
async def on_ready():
|
2017-05-12 12:43:43 +12:00
|
|
|
if not hasattr(bot, 'owner'):
|
|
|
|
appinfo = await bot.application_info()
|
|
|
|
bot.owner = appinfo.owner
|
2016-08-04 13:31:38 +12:00
|
|
|
|
2017-03-16 16:35:32 +13:00
|
|
|
|
2016-07-10 04:40:27 +12:00
|
|
|
@bot.event
|
|
|
|
async def on_message(message):
|
2017-06-07 20:30:19 +12:00
|
|
|
if message.author.bot or utils.should_ignore(bot, message):
|
2016-07-10 04:40:27 +12:00
|
|
|
return
|
|
|
|
await bot.process_commands(message)
|
2016-07-08 10:10:24 +12:00
|
|
|
|
2016-09-24 21:55:14 +12:00
|
|
|
|
2016-09-24 14:38:58 +12:00
|
|
|
@bot.event
|
2017-03-08 12:26:13 +13:00
|
|
|
async def on_command_completion(ctx):
|
2016-09-29 12:52:33 +13:00
|
|
|
# There's no reason to continue waiting for this to complete, so lets immediately launch this in a new future
|
2016-10-01 18:40:03 +13:00
|
|
|
bot.loop.create_task(process_command(ctx))
|
2016-10-01 07:02:41 +13:00
|
|
|
|
2016-09-24 14:38:58 +12:00
|
|
|
|
2016-10-01 18:40:03 +13:00
|
|
|
async def process_command(ctx):
|
2016-09-29 12:52:33 +13:00
|
|
|
author = ctx.message.author
|
2017-03-08 12:28:07 +13:00
|
|
|
server = ctx.message.guild
|
2016-10-01 18:40:03 +13:00
|
|
|
command = ctx.command
|
2016-09-29 12:52:33 +13:00
|
|
|
|
2017-06-07 20:30:19 +12:00
|
|
|
command_usage = await bot.db.actual_load('command_usage', key=command.qualified_name) or \
|
|
|
|
{'command': command.qualified_name}
|
2017-03-08 19:43:40 +13:00
|
|
|
|
2016-09-29 12:52:33 +13:00
|
|
|
# Add one to the total usage for this command, basing it off 0 to start with (obviously)
|
|
|
|
total_usage = command_usage.get('total_usage', 0) + 1
|
|
|
|
command_usage['total_usage'] = total_usage
|
|
|
|
|
|
|
|
# Add one to the author's usage for this command
|
|
|
|
total_member_usage = command_usage.get('member_usage', {})
|
2017-03-08 19:28:43 +13:00
|
|
|
member_usage = total_member_usage.get(str(author.id), 0) + 1
|
2017-03-08 19:25:17 +13:00
|
|
|
total_member_usage[str(author.id)] = member_usage
|
2016-09-29 12:52:33 +13:00
|
|
|
command_usage['member_usage'] = total_member_usage
|
|
|
|
|
|
|
|
# Add one to the server's usage for this command
|
2017-03-08 12:28:07 +13:00
|
|
|
if ctx.message.guild is not None:
|
2017-01-22 15:46:56 +13:00
|
|
|
total_server_usage = command_usage.get('server_usage', {})
|
2017-03-08 19:28:43 +13:00
|
|
|
server_usage = total_server_usage.get(str(server.id), 0) + 1
|
|
|
|
total_server_usage[str(server.id)] = server_usage
|
2017-01-22 15:46:56 +13:00
|
|
|
command_usage['server_usage'] = total_server_usage
|
2016-09-29 12:52:33 +13:00
|
|
|
|
|
|
|
# Save all the changes
|
2017-06-07 20:30:19 +12:00
|
|
|
bot.db.save('command_usage', command_usage)
|
2016-08-04 13:31:38 +12:00
|
|
|
|
2016-09-01 07:09:47 +12:00
|
|
|
|
2016-07-09 13:42:33 +12:00
|
|
|
@bot.event
|
2017-05-12 11:25:22 +12:00
|
|
|
async def on_command_error(ctx, error):
|
2016-09-18 13:29:48 +12:00
|
|
|
if isinstance(error, commands.CommandNotFound):
|
|
|
|
return
|
2016-11-12 15:22:35 +13:00
|
|
|
if isinstance(error, commands.DisabledCommand):
|
|
|
|
return
|
2016-09-23 13:48:18 +12:00
|
|
|
try:
|
|
|
|
if isinstance(error.original, discord.Forbidden):
|
|
|
|
return
|
2017-07-12 05:54:30 +12:00
|
|
|
elif isinstance(error.original, discord.HTTPException) and (
|
|
|
|
'empty message' in str(error.original) or
|
|
|
|
'INTERNAL SERVER ERROR' in str(error.original) or
|
2017-07-16 11:00:41 +12:00
|
|
|
'REQUEST ENTITY TOO LARGE' in str(error.original) or
|
2017-11-09 06:00:05 +13:00
|
|
|
'Unknown Message' in str(error.original) or
|
|
|
|
'Origin Time-out' in str(error.original) or
|
|
|
|
'Bad Gateway' in str(error.original) or
|
|
|
|
'Explicit content' in str(error.original)):
|
2016-11-02 08:28:47 +13:00
|
|
|
return
|
2017-02-13 11:40:28 +13:00
|
|
|
elif isinstance(error.original, aiohttp.ClientOSError):
|
|
|
|
return
|
2017-11-09 06:00:05 +13:00
|
|
|
elif isinstance(error.original, discord.NotFound) and 'Unknown Channel' in str(error.original):
|
|
|
|
return
|
|
|
|
|
2016-09-23 13:48:18 +12:00
|
|
|
except AttributeError:
|
|
|
|
pass
|
|
|
|
|
2017-04-09 14:52:10 +12:00
|
|
|
try:
|
|
|
|
if isinstance(error, commands.BadArgument):
|
|
|
|
fmt = "Please provide a valid argument to pass to the command: {}".format(error)
|
|
|
|
await ctx.message.channel.send(fmt)
|
|
|
|
elif isinstance(error, commands.CheckFailure):
|
|
|
|
fmt = "You can't tell me what to do!"
|
2017-07-12 05:54:30 +12:00
|
|
|
# await ctx.message.channel.send(fmt)
|
2017-04-09 14:52:10 +12:00
|
|
|
elif isinstance(error, commands.CommandOnCooldown):
|
|
|
|
m, s = divmod(error.retry_after, 60)
|
|
|
|
fmt = "This command is on cooldown! Hold your horses! >:c\nTry again in {} minutes and {} seconds" \
|
|
|
|
.format(round(m), round(s))
|
|
|
|
await ctx.message.channel.send(fmt)
|
|
|
|
elif isinstance(error, commands.NoPrivateMessage):
|
|
|
|
fmt = "This command cannot be used in a private message"
|
|
|
|
await ctx.message.channel.send(fmt)
|
|
|
|
elif isinstance(error, commands.MissingRequiredArgument):
|
|
|
|
await ctx.message.channel.send(error)
|
|
|
|
else:
|
|
|
|
now = datetime.datetime.now()
|
|
|
|
with open("error_log", 'a') as f:
|
|
|
|
print("In server '{0.message.guild}' at {1}\nFull command: `{0.message.content}`".format(ctx, str(now)),
|
|
|
|
file=f)
|
|
|
|
try:
|
|
|
|
traceback.print_tb(error.original.__traceback__, file=f)
|
|
|
|
print('{0.__class__.__name__}: {0}'.format(error.original), file=f)
|
|
|
|
except:
|
|
|
|
traceback.print_tb(error.__traceback__, file=f)
|
|
|
|
print('{0.__class__.__name__}: {0}'.format(error), file=f)
|
|
|
|
except discord.HTTPException:
|
|
|
|
pass
|
2016-07-31 12:20:55 +12:00
|
|
|
|
2016-07-18 09:10:12 +12:00
|
|
|
|
2016-07-09 13:27:19 +12:00
|
|
|
if __name__ == '__main__':
|
2017-05-21 07:45:37 +12:00
|
|
|
bot.loop.create_task(utils.db_check())
|
2016-11-11 16:08:01 +13:00
|
|
|
bot.remove_command('help')
|
2017-06-28 14:01:36 +12:00
|
|
|
bot.db = utils.DB()
|
2016-11-11 16:15:23 +13:00
|
|
|
|
2017-02-26 10:45:59 +13:00
|
|
|
for e in utils.extensions:
|
2016-07-09 13:27:19 +12:00
|
|
|
bot.load_extension(e)
|
2017-06-07 20:30:19 +12:00
|
|
|
|
|
|
|
bot.uptime = pendulum.utcnow()
|
2017-02-26 10:45:59 +13:00
|
|
|
bot.run(utils.bot_token)
|