Geoffrey-Django/api/bot/bot.py

167 lines
6.6 KiB
Python

import asyncio
import logging
from discord import Game
from discord.ext import commands
from discord.utils import oauth_url
import logging.handlers as handlers
from sys import stdout
from os import path
from GeoffreyApp.api.bot.BotErrors import *
from GeoffreyApp.api.commands import *
from django.conf import settings
logger = logging.getLogger(__name__)
description = '''
Geoffrey (pronounced JOFF-ree) started his life as an inside joke none of you will understand.
At some point, she was to become an airhorn bot. Now, they know where your stuff is.
Please respect Geoffrey, the bot is very sensitive.
All commands must be prefaced with '?'
If have a suggestion or if something is borked, you can PM my ding dong of a creator BirbHD.
*You must use ?register before adding things to Geoffrey*
For a better a explanation on how this bot works go the following link:
https://github.com/joeyahines/Geoffrey/blob/master/README.md
'''
bad_error_message = 'OOPSIE WOOPSIE!! Uwu We made a fucky wucky!! A wittle fucko boingo! The admins at our ' \
'headquarters are working VEWY HAWD to fix this! (Error in command {})'
extensions = []
'''
extensions = ['GeoffreyApp.cogs.Add_Commands',
'GeoffreyApp.cogs.Delete_Commands',
'GeoffreyApp.cogs.Edit_Commands',
'GeoffreyApp.cogs.Search_Commands',
'GeoffreyApp.cogs.Admin_Commands']
'''
class GeoffreyBot(commands.Bot):
def __init__(self):
super().__init__(command_prefix=getattr(settings, 'BOT_PREFIX', '?'), description=description, pm_help=True, case_insensitive=True)
self.error_users = getattr(settings, 'ERROR_USERS', [])
self.admin_users = getattr(settings, 'MOD_RANK', [])
self.special_users = getattr(settings, 'SPECIAL_USERS', [])
self.default_status = getattr(settings, 'DEFAULT_STATUS', 'sed')
for extension in extensions:
try:
self.load_extension(extension)
except Exception as e:
logger.info('Failed to load extension {}'.format(extension))
raise e
async def on_ready(self):
logger.info("%s Online, ID: %s", self.user.name, self.user.id)
info = await self.application_info()
url = oauth_url(info.id)
logger.info("Bot url: %s", url)
await self.change_presence(activity=Game(self.default_status))
async def on_command(self, ctx):
if ctx.invoked_subcommand is None:
subcommand = ""
else:
subcommand = ":" + ctx.invoked_subcommand.__str__()
logger.info("User %s, used command %s%s with context: %s", ctx.message.author, ctx.command.name, subcommand,
ctx.args)
if ctx.invoked_with.lower() == 'help' and ctx.message.guild is not None:
await ctx.send("{}, I sent you some help in the DMs.".format(ctx.message.author.mention))
async def on_command_error(self, ctx, error):
error_str = ''
if hasattr(ctx, 'cog'):
if "Admin_Commands" in ctx.cog.__str__():
return
if hasattr(error, 'original'):
if isinstance(error.original, NoPermissionError):
error_str = 'You don\'t have permission for that cool command.'
elif isinstance(error.original, UsernameLookupFailed):
error_str = 'Your user name was not found, either Mojang is having a fucky wucky ' \
'or your nickname is not set correctly. *stares at the Mods*'
elif isinstance(error.original, PlayerNotFound):
error_str = 'Make sure to use ?register first you ding dong.'
elif isinstance(error.original, EntryNameNotUniqueError):
error_str = 'An entry in the database already has that name you ding dong.'
elif isinstance(error.original, DatabaseValueError):
error_str = 'Use a shorter name or a smaller value, dong ding.'
elif isinstance(error.original, NotOnServerError):
error_str = 'Command needs to be run on 24CC. Run this command there whoever you are.'.format()
elif isinstance(error.original, EmptryString):
error_str = 'Do not not pass empty string to Geoffrey. Ding dong.'
elif isinstance(error, commands.CommandOnCooldown):
return
elif isinstance(error, commands.UserInputError):
error_str = 'Invalid syntax for **{}** you ding dong:' \
.format(ctx.invoked_with, ctx.invoked_with)
pages = await self.formatter.format_help_for(ctx, ctx.command)
for page in pages:
error_str = error_str + '\n' + page
elif isinstance(error, commands.CommandNotFound):
return
if error_str is '':
await self.send_error_message(
'Geoffrey encountered unhandled exception: {} Command: **{}** Context: {}'.format(error,
ctx.command.name,
ctx.args))
error_str = bad_error_message.format(ctx.invoked_with)
logger.error("Geoffrey encountered exception: %s", error)
await ctx.message.channel.send('{} **Error Running Command:** {}'.format(
ctx.message.author.mention, error_str))
async def send_error_message(self, msg):
for user_id in self.error_users:
user = await self.get_user_info(user_id)
await user.send(msg)
def setup_logging():
discord_logger = logging.getLogger('discord')
discord_logger.setLevel(logging.INFO)
bot_info_logger = logging.getLogger('GeoffreyApp.api.bot.bot')
bot_info_logger.setLevel(logging.INFO)
console = logging.StreamHandler(stdout)
console.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
bot_info_logger.addHandler(console)
def start_bot():
bot = None
try:
bot = GeoffreyBot()
@bot.command(pass_context=True)
async def test(ctx):
"""
Checks if the bot is alive.
"""
await ctx.send('I\'m here you ding dong')
setup_logging()
bot.run(getattr(settings, 'DISCORD_TOKEN'))
except KeyboardInterrupt:
logger.info("Bot received keyboard interrupt")
except Exception as e:
print(e)
logger.info('Bot encountered the following unhandled exception %s', e)
finally:
if bot is not None:
bot.loop.stop()
logger.info("Bot shutting down...")