From f82aac5f5669e84506e56ca9c2020d9a847e35c1 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Sat, 11 Aug 2018 16:07:33 -0500 Subject: [PATCH] Also moved cogs into their own folder --- BotConfig.py | 88 ++++++------ Geoffrey.py | 125 +++--------------- bot.py | 116 ++++++++++++++++ Add_Commands.py => cogs/Add_Commands.py | 2 +- Admin_Commands.py => cogs/Admin_Commands.py | 2 +- Delete_Commands.py => cogs/Delete_Commands.py | 2 +- Edit_Commands.py => cogs/Edit_Commands.py | 2 +- Search_Commands.py => cogs/Search_Commands.py | 2 +- test_commands.py => tests/test_commands.py | 0 .../test_geoffreyDatabase.py | 0 .../test_minecraftInfoGrabber.py | 0 test_stress.py => tests/test_stress.py | 0 12 files changed, 190 insertions(+), 149 deletions(-) create mode 100644 bot.py rename Add_Commands.py => cogs/Add_Commands.py (96%) rename Admin_Commands.py => cogs/Admin_Commands.py (95%) rename Delete_Commands.py => cogs/Delete_Commands.py (96%) rename Edit_Commands.py => cogs/Edit_Commands.py (96%) rename Search_Commands.py => cogs/Search_Commands.py (96%) rename test_commands.py => tests/test_commands.py (100%) rename test_geoffreyDatabase.py => tests/test_geoffreyDatabase.py (100%) rename test_minecraftInfoGrabber.py => tests/test_minecraftInfoGrabber.py (100%) rename test_stress.py => tests/test_stress.py (100%) diff --git a/BotConfig.py b/BotConfig.py index e1f8e86..4916c74 100644 --- a/BotConfig.py +++ b/BotConfig.py @@ -1,59 +1,67 @@ import configparser +def create_config(config): + config['Discord'] = {'Token': '', + 'Status': '', + 'Prefix': '?', + 'Bot_Mod': '' + } + config['SQL'] = {'Dialect+Driver': 'mysql+mysqldb', + 'Username': '', + 'Password': '', + 'Host': '', + 'Port': '', + 'Database': '' + } + config['Minecraft'] = {'Dynmap_Url': '', + 'World_Name': '' + } + config['Logging'] = {'Count': '', + 'Rotation_Duration': '' + } + + with open('GeoffreyConfig.ini', 'w') as configfile: + config.write(configfile) + + +def read_config(): + config = configparser.ConfigParser() + config.read('GeoffreyConfig.ini') + + if len(config.sections()) == 0: + create_config(config) + print("GeoffreyConfig.ini generated.") + quit(0) + + return config + + class Config: def __init__(self): - self.config = '' - self.engine_args = '' - self.token = '' - self.world_name = '' - self.status = '' - self.prefix = '' - self.dynmap_url = '' - self.bot_mod = '' - self.load_config() - - def load_config(self): try: - self.config = self.read_config() + self.config = read_config() self.engine_args = self.read_engine_arg() self.token = self.config['Discord']['Token'] self.world_name = self.config['Minecraft']['World_Name'] self.status = self.config['Discord']['Status'] self.prefix = self.config['Discord']['Prefix'] - self.dynmap_url = self.config['Minecraft']['dynmap_url'] - self.bot_mod = self.config['Discord']['bot_mod'] - except: - print("Invalid config file") + self.dynmap_url = self.config['Minecraft']['Dynmap_Url'] + self.bot_mod = self.config['Discord']['Bot_Mod'] + self.count = int(self.config['Logging']['Count']) + self.rotation_duration = int(self.config['Logging']['Rotation_Duration']) + except Exception as e: + print("Invalid config file, missing {}.".format(e)) quit(1) - def read_config(self): - config = configparser.ConfigParser() - config.read('GeoffreyConfig.ini') - - if len(config.sections()) == 0: - self.create_config(config) - print("GeoffreyConfig.ini generated.") - quit(0) - - return config - - def create_config(self, config): - config['Discord'] = {'Token': '', 'Status': '', 'Prefix': '', } - config['SQL'] = {'Dialect+Driver': '', 'username': '', 'password': '', 'host': '', 'port': '', - 'database': '', 'bot_mod': ''} - config['Minecraft'] = {'World_Name': '', 'dynmap_url': ''} - with open('GeoffreyConfig.ini', 'w') as configfile: - config.write(configfile) - def read_engine_arg(self): driver = self.config['SQL']['Dialect+Driver'] - username = self.config['SQL']['username'] - password = self.config['SQL']['password'] - host = self.config['SQL']['host'] - port = self.config['SQL']['port'] - database_name = self.config['SQL']['database'] + username = self.config['SQL']['Username'] + password = self.config['SQL']['Password'] + host = self.config['SQL']['Host'] + port = self.config['SQL']['Port'] + database_name = self.config['SQL']['Database'] engine_args = '{}://{}:{}@{}:{}/{}?charset=utf8mb4&use_unicode=1' diff --git a/Geoffrey.py b/Geoffrey.py index 7572990..b1f12a7 100644 --- a/Geoffrey.py +++ b/Geoffrey.py @@ -1,118 +1,35 @@ -from discord.ext import commands -from discord import Game -from Commands import * -from BotErrors import * -from MinecraftAccountInfoGrabber import * -from BotConfig import * -import asyncio +"""" +Geoffrey Minecraft Info Database -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. +Created by: Joey Hines (ZeroHD) -Please respect Geoffrey, the bot is very sensitive. - -If have a suggestion or if something is borked, you can PM my ding dong of a creator ZeroHD. - -*You must use ?register before adding things to Geoffrey* -''' - -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 {}: {})' +""" +import logging +import logging.handlers as handlers +from bot import start_bot +from BotConfig import bot_config -# Bot Commands ******************************************************************' -bot = commands.Bot(command_prefix=bot_config.prefix, description=description, case_insensitive=True) +def setup_logging(): + discord_logger = logging.getLogger('discord') + discord_logger.setLevel(logging.DEBUG) + sql_logger = logging.getLogger('sqlalchemy.engine') + sql_logger.setLevel(logging.INFO) -@bot.event -async def on_ready(): - print('GeoffreyBot') - print('Username: ' + bot.user.name) - print('ID: ' + bot.user.id) + handler = handlers.TimedRotatingFileHandler(filename='Geoffrey.log', when='D', + interval=bot_config.rotation_duration, backupCount=bot_config.count, + encoding='utf-8') - await bot.change_presence(game=Game(name=bot_config.status)) + handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s')) + discord_logger.addHandler(handler) + sql_logger.addHandler(handler) -@bot.event -async def on_command_error(error, ctx): - if hasattr(ctx, 'cog'): - if "Admin_Commands" in ctx.cog.__str__(): - return - if isinstance(error, commands.CommandNotFound): - error_str = 'Command not found, ding dongs like you can use ?help to see all the commands this bot can do.' - elif isinstance(error, commands.CommandOnCooldown): - return - elif isinstance(error, commands.UserInputError): - error_str = 'Invalid syntax for **{}** you ding dong, please read ?help {}.'\ - .format(ctx.invoked_with, ctx.invoked_with) - elif 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 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() - else: - error_str = bad_error_message.format(ctx.invoked_with, error) - - await bot.send_message(ctx.message.channel, '{} **Error Running Command:** {}'.format(ctx.message.author.mention, - error_str)) - - -async def username_update(): - session = None - await bot.wait_until_ready() - while not bot.is_closed: - session = bot_commands.interface.database.Session() - try: - print("Updating MC usernames...") - session = bot_commands.interface.database.Session() - player_list = session.query(Player).all() - for player in player_list: - player.name = grab_playername(player.mc_uuid) - - session.commit() - - await asyncio.sleep(600) - - except UsernameLookupFailed: - print("Username lookup error, are Mojang's servers down?") - session.rollback() - finally: - print("Done.") - session.close() - - if session is not None: - session.close() - -# Bot Startup ****************************************************************** -bot_commands = Commands() - -extensions = ['Add_Commands', 'Delete_Commands', 'Edit_Commands', 'Search_Commands', 'Admin_Commands'] if __name__ == '__main__': - bot_commands = Commands() - - for extension in extensions: - try: - bot.load_extension(extension) - except Exception as e: - print('Failed to load extension {}, {}'.format(extension, e)) - - try: - bot.loop.create_task(username_update()) - bot.run(bot_config.token) - except TimeoutError: - print("Disconnected, is Discord offline?") - except: - print("Bye") + setup_logging() + start_bot() diff --git a/bot.py b/bot.py new file mode 100644 index 0000000..b851783 --- /dev/null +++ b/bot.py @@ -0,0 +1,116 @@ +from BotErrors import * +from DatabaseModels import Player +from Commands import Commands +from discord.ext import commands +from discord import Game +from MinecraftAccountInfoGrabber import * +from BotConfig import * +import asyncio + +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. + +If have a suggestion or if something is borked, you can PM my ding dong of a creator ZeroHD. + +*You must use ?register before adding things to Geoffrey* +''' + +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 {}: {})' + + +bot = commands.Bot(command_prefix=bot_config.prefix, description=description, case_insensitive=True) +bot_commands = Commands() + +extensions = ['cogs.Add_Commands', + 'cogs.Delete_Commands', + 'cogs.Edit_Commands', + 'cogs.Search_Commands', + 'cogs.Admin_Commands'] + + +@bot.event +async def on_ready(): + print('GeoffreyBot') + print('Username: ' + bot.user.name) + print('ID: ' + bot.user.id) + + await bot.change_presence(game=Game(name=bot_config.status)) + + +@bot.event +async def on_command_error(error, ctx): + if hasattr(ctx, 'cog'): + if "Admin_Commands" in ctx.cog.__str__(): + return + if isinstance(error, commands.CommandNotFound): + error_str = 'Command not found, ding dongs like you can use ?help to see all the commands this bot can do.' + elif isinstance(error, commands.CommandOnCooldown): + return + elif isinstance(error, commands.UserInputError): + error_str = 'Invalid syntax for **{}** you ding dong, please read ?help {}.'\ + .format(ctx.invoked_with, ctx.invoked_with) + elif 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 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() + else: + error_str = bad_error_message.format(ctx.invoked_with, error) + + await bot.send_message(ctx.message.channel, '{} **Error Running Command:** {}'.format(ctx.message.author.mention, + error_str)) + + +async def username_update(): + session = None + await bot.wait_until_ready() + while not bot.is_closed: + session = bot_commands.interface.database.Session() + try: + print("Updating MC usernames...") + session = bot_commands.interface.database.Session() + player_list = session.query(Player).all() + for player in player_list: + player.name = grab_playername(player.mc_uuid) + + session.commit() + + await asyncio.sleep(600) + + except UsernameLookupFailed: + print("Username lookup error, are Mojang's servers down?") + session.rollback() + finally: + print("Done.") + session.close() + + if session is not None: + session.close() + + +def start_bot(): + for extension in extensions: + try: + bot.load_extension(extension) + except Exception as e: + print('Failed to load extension {}, {}'.format(extension, e)) + + try: + bot.loop.create_task(username_update()) + bot.run(bot_config.token) + except TimeoutError: + print("Disconnected, is Discord offline?") + except: + print("Bye") diff --git a/Add_Commands.py b/cogs/Add_Commands.py similarity index 96% rename from Add_Commands.py rename to cogs/Add_Commands.py index 91893ac..5130652 100644 --- a/Add_Commands.py +++ b/cogs/Add_Commands.py @@ -1,7 +1,7 @@ from discord.ext import commands from BotErrors import * from DiscordHelperFunctions import * -from Geoffrey import bot_commands +from bot import bot_commands @commands.cooldown(5, 60, commands.BucketType.user) diff --git a/Admin_Commands.py b/cogs/Admin_Commands.py similarity index 95% rename from Admin_Commands.py rename to cogs/Admin_Commands.py index b08b380..66f3444 100644 --- a/Admin_Commands.py +++ b/cogs/Admin_Commands.py @@ -1,7 +1,7 @@ from discord.ext import commands from BotErrors import * from BotConfig import bot_config -from Geoffrey import bot_commands +from bot import bot_commands from discord import Game diff --git a/Delete_Commands.py b/cogs/Delete_Commands.py similarity index 96% rename from Delete_Commands.py rename to cogs/Delete_Commands.py index 82a8b59..f171d60 100644 --- a/Delete_Commands.py +++ b/cogs/Delete_Commands.py @@ -1,7 +1,7 @@ from discord.ext import commands from BotErrors import * from DiscordHelperFunctions import * -from Geoffrey import bot_commands +from bot import bot_commands @commands.cooldown(5, 60, commands.BucketType.user) diff --git a/Edit_Commands.py b/cogs/Edit_Commands.py similarity index 96% rename from Edit_Commands.py rename to cogs/Edit_Commands.py index 4d028d5..d46d9bb 100644 --- a/Edit_Commands.py +++ b/cogs/Edit_Commands.py @@ -1,7 +1,7 @@ from discord.ext import commands from BotErrors import * from DiscordHelperFunctions import * -from Geoffrey import bot_commands +from bot import bot_commands class Edit_Commands: diff --git a/Search_Commands.py b/cogs/Search_Commands.py similarity index 96% rename from Search_Commands.py rename to cogs/Search_Commands.py index 173feae..46637f3 100644 --- a/Search_Commands.py +++ b/cogs/Search_Commands.py @@ -1,7 +1,7 @@ from discord.ext import commands from BotErrors import * from DiscordHelperFunctions import * -from Geoffrey import bot_commands +from bot import bot_commands class Search_Commands: diff --git a/test_commands.py b/tests/test_commands.py similarity index 100% rename from test_commands.py rename to tests/test_commands.py diff --git a/test_geoffreyDatabase.py b/tests/test_geoffreyDatabase.py similarity index 100% rename from test_geoffreyDatabase.py rename to tests/test_geoffreyDatabase.py diff --git a/test_minecraftInfoGrabber.py b/tests/test_minecraftInfoGrabber.py similarity index 100% rename from test_minecraftInfoGrabber.py rename to tests/test_minecraftInfoGrabber.py diff --git a/test_stress.py b/tests/test_stress.py similarity index 100% rename from test_stress.py rename to tests/test_stress.py