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.discord_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 discord_bot. Now, they know where your stuff is. Please respect Geoffrey, the discord_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 discord_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.discord_bot.discord_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(): asyncio.set_event_loop(asyncio.new_event_loop()) bot = None try: bot = GeoffreyBot() @bot.command(pass_context=True) async def test(ctx): """ Checks if the discord_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...")