From 89bf3b0ba7e529167fae19ea5cba6fa428dee057 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Wed, 29 Aug 2018 16:10:35 -0500 Subject: [PATCH] Refactored how the config file is handled. The location can now be passed in as an arg in start_bot... This broke a few features of the config --- geoffrey/BotConfig.py | 17 +++++----- geoffrey/Commands.py | 14 +++++---- geoffrey/DatabaseInterface.py | 11 +++---- geoffrey/DatabaseModels.py | 40 ++++++++++++----------- geoffrey/DiscordHelperFunctions.py | 4 +-- geoffrey/Geoffrey.py | 4 --- geoffrey/bot.py | 42 +++++++++++++++---------- geoffrey/cogs/Add_Commands.py | 4 +-- geoffrey/cogs/Admin_Commands.py | 3 +- geoffrey/cogs/Delete_Commands.py | 2 +- geoffrey/cogs/Edit_Commands.py | 2 +- geoffrey/cogs/Search_Commands.py | 2 +- geoffrey/tests/test_commands.py | 23 +++++++------- geoffrey/tests/test_geoffreyDatabase.py | 9 +++--- 14 files changed, 91 insertions(+), 86 deletions(-) diff --git a/geoffrey/BotConfig.py b/geoffrey/BotConfig.py index 1f72e87..1bbc9fe 100644 --- a/geoffrey/BotConfig.py +++ b/geoffrey/BotConfig.py @@ -29,18 +29,17 @@ def create_config(config, path): } config['Special Names'] = {} - with open('{}/GeoffreyConfig.ini'.format(path), 'w') as configfile: + with open(path, 'w') as configfile: config.write(configfile) -def read_config(): +def read_config(path): config = configparser.ConfigParser() - path = os.path.dirname(os.path.abspath(__file__)) - config.read_file(codecs.open("{}/GeoffreyConfig.ini".format(path), "r", "utf8")) + config.read_file(codecs.open(path, "r", "utf8")) if len(config.sections()) == 0: create_config(config, path) - print("GeoffreyConfig.ini generated.") + print("Config generated.") quit(0) return config @@ -48,9 +47,9 @@ def read_config(): class Config: - def __init__(self): + def __init__(self, path): try: - self.config = read_config() + self.config = read_config(path) self.engine_args = self.read_engine_arg() self.token = self.config['Discord']['Token'] @@ -86,4 +85,6 @@ class Config: return engine_args.format(driver, username, password, host, port, database_name) -bot_config = Config() +def get_config(config_path): + return Config(config_path) + diff --git a/geoffrey/Commands.py b/geoffrey/Commands.py index bb9ff53..8754099 100644 --- a/geoffrey/Commands.py +++ b/geoffrey/Commands.py @@ -2,8 +2,9 @@ from geoffrey.DatabaseInterface import * class Commands: - def __init__(self, engine_args=None): - self.interface = DatabaseInterface(engine_args) + def __init__(self, bot_config, debug=False): + self.bot_config = bot_config + self.interface = DatabaseInterface(bot_config, debug) def get_player(self, session, discord_uuid=None, mc_uuid=None): if discord_uuid is not None: @@ -87,7 +88,8 @@ class Commands: location_name = location_list[0].name - tunnel = self.interface.add_tunnel(session, player, tunnel_color, tunnel_number, location_name) + tunnel = self.interface.add_tunnel(session, player, tunnel_color, tunnel_number, location_name, + self.bot_config) tunnel_info = tunnel.__str__() finally: @@ -159,7 +161,7 @@ class Commands: def info(self, location_name): session = self.interface.database.Session() try: - loc = self.interface.find_location_by_name(session, location_name)[0].full_str() + loc = self.interface.find_location_by_name(session, location_name)[0].full_str(self.bot_config) finally: session.close() @@ -231,7 +233,7 @@ class Commands: location.tunnel.tunnel_direction = TunnelDirection.str_to_tunnel_dir(tunnel_color) location.tunnel.tunnel_number = tunnel_number else: - self.interface.add_tunnel(session, player, tunnel_color, tunnel_number, loc_name) + self.interface.add_tunnel(session, player, tunnel_color, tunnel_number, loc_name, self.bot_config) loc_str = location.__str__() @@ -305,7 +307,7 @@ class Commands: expr = (ItemListing.name == item) & (ItemListing.shop == shop) self.interface.database.delete_entry(session, ItemListing, expr) - shop_str = shop.full_str() + shop_str = shop.full_str(self.bot_config) finally: session.close() diff --git a/geoffrey/DatabaseInterface.py b/geoffrey/DatabaseInterface.py index 4a2131f..51de0b4 100644 --- a/geoffrey/DatabaseInterface.py +++ b/geoffrey/DatabaseInterface.py @@ -3,11 +3,8 @@ from geoffrey.DatabaseModels import * class DatabaseInterface: - def __init__(self, engine_args=None): - if engine_args is None: - self.database = GeoffreyDatabase() - else: - self.database = GeoffreyDatabase(engine_args) + def __init__(self, bot_config, debug=False): + self.database = GeoffreyDatabase(bot_config, debug) def add_base(self, session, owner, name, x_pos, z_pos, dimension=None): base = Base(name, x_pos, z_pos, owner, dimension) @@ -19,7 +16,7 @@ class DatabaseInterface: self.database.add_object(session, shop) return shop - def add_tunnel(self, session, owner, color, number, location_name): + def add_tunnel(self, session, owner, color, number, location_name, config): tunnels = self.find_tunnel_by_owner(session, owner) if location_name is None: if len(tunnels): @@ -36,7 +33,7 @@ class DatabaseInterface: except IndexError: raise LocationLookUpError - tunnel = Tunnel(owner, color, number, location) + tunnel = Tunnel(owner, color, number, config, location) self.database.add_object(session, tunnel) return tunnel diff --git a/geoffrey/DatabaseModels.py b/geoffrey/DatabaseModels.py index d2fec12..91604e3 100644 --- a/geoffrey/DatabaseModels.py +++ b/geoffrey/DatabaseModels.py @@ -7,7 +7,6 @@ from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, column_property, sessionmaker from sqlalchemy.sql import expression -from geoffrey.BotConfig import bot_config from geoffrey.BotErrors import * from geoffrey.MinecraftAccountInfoGrabber import * @@ -25,8 +24,11 @@ def check_similarity(a, b): class GeoffreyDatabase: - def __init__(self, engine_args=bot_config.engine_args): - self.engine = create_engine(engine_args, pool_recycle=3600, pool_pre_ping=True) + def __init__(self, bot_config, debug): + if not debug: + self.engine = create_engine(bot_config.engine_args, pool_recycle=3600, pool_pre_ping=True) + else: + self.engine = create_engine(bot_config.config['SQL']['test_args'], pool_recycle=3600, pool_pre_ping=True) self.Session = sessionmaker(bind=self.engine) SQL_Base.metadata.create_all(self.engine) @@ -83,21 +85,21 @@ class GeoffreyDatabase: class TunnelDirection(enum.Enum): - North = bot_config.north_tunnel - East = bot_config.east_tunnel - South = bot_config.south_tunnel - West = bot_config.west_tunnel + North = "North" + East = "East" + South = "South" + West = "West" - def str_to_tunnel_dir(arg): + def str_to_tunnel_dir(bot_config, arg): arg = arg.lower() - if check_similarity(TunnelDirection.North.value, arg): + if check_similarity(bot_config.north_tunnel, arg): return TunnelDirection.North - elif check_similarity(TunnelDirection.East.value, arg): + elif check_similarity(bot_config.east_tunnel, arg): return TunnelDirection.East - elif check_similarity(TunnelDirection.South.value, arg): + elif check_similarity(bot_config.south_tunnel, arg): return TunnelDirection.South - elif check_similarity(TunnelDirection.West.value, arg): + elif check_similarity(bot_config.west_tunnel, arg): return TunnelDirection.West else: raise InvalidTunnelError @@ -149,11 +151,11 @@ class Tunnel(SQL_Base): location_id = Column(Integer, ForeignKey('geoffrey_locations.id', ondelete='CASCADE')) location = relationship("Location", back_populates="tunnel", lazy="joined") - def __init__(self, owner, tunnel_color, tunnel_number, location=None): + def __init__(self, owner, tunnel_color, tunnel_number, config, location=None): try: self.owner = owner self.location = location - self.tunnel_direction = TunnelDirection.str_to_tunnel_dir(tunnel_color) + self.tunnel_direction = TunnelDirection.str_to_tunnel_dir(config, tunnel_color) self.tunnel_number = tunnel_number except (ValueError, IndexError): raise TunnelInitError @@ -206,7 +208,7 @@ class Location(SQL_Base): except (ValueError, IndexError): raise LocationInitError - def dynmap_link(self): + def dynmap_link(self, bot_config): return '<{}/?worldname={}&mapname=surface&zoom=4&x={}&y=65&z={}>'.\ format(bot_config.dynmap_url, bot_config.world_name, self.x, self.z) @@ -221,8 +223,8 @@ class Location(SQL_Base): return "**{}** @ {}, Owner: **{}**, Type: **{}**".format(self.name, self.pos_to_str(), self.owner.name, self.type) - def full_str(self): - return self.__str__() + '\n' + self.dynmap_link() + def full_str(self, bot_config): + return self.__str__() + '\n' + self.dynmap_link(bot_config) def __str__(self): return self.info_str() @@ -260,8 +262,8 @@ class Shop(Location): else: return '' - def full_str(self): - return Location.full_str(self) + self.inv_to_str() + def full_str(self, bot_config): + return Location.full_str(self, bot_config) + self.inv_to_str() def __str__(self): return Location.__str__(self) diff --git a/geoffrey/DiscordHelperFunctions.py b/geoffrey/DiscordHelperFunctions.py index 6110150..b9f161e 100644 --- a/geoffrey/DiscordHelperFunctions.py +++ b/geoffrey/DiscordHelperFunctions.py @@ -1,7 +1,5 @@ from itertools import zip_longest -from geoffrey.BotConfig import bot_config - def get_name(args): if len(args) > 0: @@ -12,7 +10,7 @@ def get_name(args): return name -def get_nickname(discord_user): +def get_nickname(discord_user, bot_config): if discord_user.nick is None: name = discord_user.display_name else: diff --git a/geoffrey/Geoffrey.py b/geoffrey/Geoffrey.py index 59e9a34..1f1ff14 100644 --- a/geoffrey/Geoffrey.py +++ b/geoffrey/Geoffrey.py @@ -4,12 +4,8 @@ Geoffrey Minecraft Info Database Created by: Joey Hines (ZeroHD) """ -import logging -import logging.handlers as handlers -from sys import stdout from geoffrey import bot -from geoffrey.BotConfig import bot_config if __name__ == '__main__': print("Starting bot...") diff --git a/geoffrey/bot.py b/geoffrey/bot.py index 6f8b4ac..ffceb9c 100644 --- a/geoffrey/bot.py +++ b/geoffrey/bot.py @@ -10,7 +10,7 @@ import logging.handlers as handlers from sys import stdout -from geoffrey.BotConfig import bot_config +from geoffrey.BotConfig import * from geoffrey.BotErrors import * from geoffrey.Commands import Commands from geoffrey.DatabaseModels import Player @@ -38,12 +38,10 @@ extensions = ['geoffrey.cogs.Add_Commands', 'geoffrey.cogs.Search_Commands', 'geoffrey.cogs.Admin_Commands'] -bot = commands.Bot(command_prefix=bot_config.prefix, description=description, case_insensitive=True) +bot_config = None +bot_commands = None -try: - bot_commands = Commands() -except OperationalError: - logger.info('Could not connect to MySQL server.') +bot = commands.Bot(command_prefix='?', description=description, case_insensitive=True) @bot.event @@ -52,7 +50,7 @@ async def on_ready(): info = await bot.application_info() url = oauth_url(info.id) logger.info("Bot url: %s", url) - await bot.change_presence(activity=Game(bot_config.status)) + await bot.change_presence(game=Game(name="Geoffrey")) @bot.event @@ -62,7 +60,8 @@ async def on_command(command, ctx): else: subcommand = ":" + ctx.invoked_subcommand - logger.info("User %s, used command %s%s with context: %s", ctx.message.author, command, subcommand, ctx.args) + logger.info("User %s, used command %s%s with context: %s", ctx.message.author, command, subcommand, + ctx.args) @bot.event @@ -101,13 +100,15 @@ async def on_command_error(error, ctx): return if error_str is None: - await send_error_message('Geoffrey encountered unhandled exception: {}. Context:'.format(error, ctx.args)) + await send_error_message( + 'Geoffrey encountered unhandled exception: {}. Context:'.format(error, ctx.args)) logger.error("Geoffrey encountered unhandled exception: %s", error) error_str = bad_error_message.format(ctx.invoked_with) - await bot.send_message(ctx.message.channel, '{} **Error Running Command:** {}'.format(ctx.message.author.mention, - error_str)) + await bot.send_message(ctx.message.channel, + '{} **Error Running Command:** {}'.format(ctx.message.author.mention, + error_str)) async def send_error_message(msg): @@ -116,6 +117,7 @@ async def send_error_message(msg): await bot.send_message(user, msg) + async def username_update(): await bot.wait_until_ready() while not bot.is_closed: @@ -140,7 +142,8 @@ async def username_update(): session.close() await asyncio.sleep(600) -def setup_logging(): + +def setup_logging(config): discord_logger = logging.getLogger('discord') discord_logger.setLevel(logging.INFO) @@ -150,7 +153,7 @@ def setup_logging(): bot_info_logger.setLevel(logging.INFO) handler = handlers.TimedRotatingFileHandler(filename='Geoffrey.log', when='D', - interval=bot_config.rotation_duration, backupCount=bot_config.count, + interval=config.rotation_duration, backupCount=config.count, encoding='utf-8') handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s')) @@ -165,19 +168,24 @@ def setup_logging(): bot_info_logger.addHandler(console) -def start_bot(): +def start_bot(config_path="{}/GeoffreyConfig.ini".format(os.path.dirname(os.path.abspath(__file__)))): try: - setup_logging() - Commands() + global bot_config, bot_commands + bot_config = get_config(config_path) + setup_logging(bot_config) + + bot_commands = Commands(bot_config) + for extension in extensions: try: bot.load_extension(extension) except Exception as e: logger.info('Failed to load extension {}'.format(extension)) raise e - bot.loop.create_task(username_update()) + logger.info('Logging into Discord...') bot.run(bot_config.token) + except KeyboardInterrupt: logger.info("Bot received keyboard interrupt") except Exception as e: diff --git a/geoffrey/cogs/Add_Commands.py b/geoffrey/cogs/Add_Commands.py index 8344ead..0cf269f 100644 --- a/geoffrey/cogs/Add_Commands.py +++ b/geoffrey/cogs/Add_Commands.py @@ -2,7 +2,7 @@ from discord.ext import commands from geoffrey.BotErrors import * from geoffrey.DiscordHelperFunctions import * -from geoffrey.bot import bot_commands +from geoffrey.bot import bot_commands, bot_config @commands.cooldown(5, 60, commands.BucketType.user) @@ -24,7 +24,7 @@ class Add_Commands: """ try: - player_name = get_nickname(ctx.message.author) + player_name = get_nickname(ctx.message.author, bot_config) bot_commands.register(player_name, ctx.message.author.id) await self.bot.say('{}, you have been added to the database.'.format(ctx.message.author.mention)) except AttributeError: diff --git a/geoffrey/cogs/Admin_Commands.py b/geoffrey/cogs/Admin_Commands.py index fdd2a5a..59bbc25 100644 --- a/geoffrey/cogs/Admin_Commands.py +++ b/geoffrey/cogs/Admin_Commands.py @@ -1,9 +1,8 @@ from discord import Game from discord.ext import commands -from geoffrey.BotConfig import bot_config from geoffrey.BotErrors import * -from geoffrey.bot import bot_commands +from geoffrey.bot import bot_commands, bot_config def check_mod(user): diff --git a/geoffrey/cogs/Delete_Commands.py b/geoffrey/cogs/Delete_Commands.py index 9bc0ebd..f9ff93f 100644 --- a/geoffrey/cogs/Delete_Commands.py +++ b/geoffrey/cogs/Delete_Commands.py @@ -2,7 +2,7 @@ from discord.ext import commands from geoffrey.BotErrors import * from geoffrey.DiscordHelperFunctions import * -from geoffrey.bot import bot_commands +from geoffrey.bot import bot_commands, bot_config class Delete_Commands: diff --git a/geoffrey/cogs/Edit_Commands.py b/geoffrey/cogs/Edit_Commands.py index d622d9e..1884680 100644 --- a/geoffrey/cogs/Edit_Commands.py +++ b/geoffrey/cogs/Edit_Commands.py @@ -2,7 +2,7 @@ from discord.ext import commands from geoffrey.BotErrors import * from geoffrey.DiscordHelperFunctions import * -from geoffrey.bot import bot_commands +from geoffrey.bot import bot_commands, bot_config class Edit_Commands: diff --git a/geoffrey/cogs/Search_Commands.py b/geoffrey/cogs/Search_Commands.py index 186030f..118b9f2 100644 --- a/geoffrey/cogs/Search_Commands.py +++ b/geoffrey/cogs/Search_Commands.py @@ -2,7 +2,7 @@ from discord.ext import commands from geoffrey.BotErrors import * from geoffrey.DiscordHelperFunctions import * -from geoffrey.bot import bot_commands +from geoffrey.bot import bot_commands, bot_config class Search_Commands: diff --git a/geoffrey/tests/test_commands.py b/geoffrey/tests/test_commands.py index 97ce3b9..d7b7ef9 100644 --- a/geoffrey/tests/test_commands.py +++ b/geoffrey/tests/test_commands.py @@ -1,12 +1,13 @@ from unittest import TestCase from Commands import * +from BotConfig import get_config class TestCommands(TestCase): def setUp(self): - - self.commands = Commands(bot_config.config['SQL']['test_args']) + self.bot_config = get_config() + self.commands = Commands(self.bot_config, True) self.session = self.commands.interface.database.Session() self.commands.interface.database.clear_all(self.session) self.session.close() @@ -49,13 +50,13 @@ class TestCommands(TestCase): self.commands.register('ZeroHD', '143072699567177728') self.commands.add_shop(0, 0, shop_name='test shop', discord_uuid='143072699567177728') - tunnel2 = self.commands.add_tunnel(bot_config.east_tunnel, 50, location_name='test_shop', + tunnel2 = self.commands.add_tunnel(self.bot_config.east_tunnel, 50, location_name='test_shop', discord_uuid='143072699567177728') - if bot_config.east_tunnel not in tunnel2: + if self.bot_config.east_tunnel not in tunnel2: self.fail() - self.assertRaises(LocationHasTunnelError, self.commands.add_tunnel, bot_config.east_tunnel, 50, + self.assertRaises(LocationHasTunnelError, self.commands.add_tunnel, self.bot_config.east_tunnel, 50, location_name='test_shop', discord_uuid='143072699567177728') def test_find(self): @@ -126,11 +127,11 @@ class TestCommands(TestCase): self.commands.register('ZeroHD', '143072699567177728') self.commands.add_shop(0, 0, shop_name='frick', discord_uuid='143072699567177728') - self.commands.add_tunnel(bot_config.north_tunnel, 50, location_name='frick', discord_uuid='143072699567177728') + self.commands.add_tunnel(self.bot_config.north_tunnel, 50, location_name='frick', discord_uuid='143072699567177728') result = self.commands.info('frick') - if bot_config.north_tunnel in result: + if self.bot_config.north_tunnel in result: pass else: self.fail() @@ -139,11 +140,11 @@ class TestCommands(TestCase): self.commands.register('ZeroHD', '143072699567177728') self.commands.add_shop(0, 0, shop_name='test shop', discord_uuid='143072699567177728') - self.commands.add_tunnel(bot_config.south_tunnel, 50, None, discord_uuid='143072699567177728') + self.commands.add_tunnel(self.bot_config.south_tunnel, 50, None, discord_uuid='143072699567177728') result = self.commands.tunnel('ZeroHD') - if bot_config.south_tunnel in result: + if self.bot_config.south_tunnel in result: pass else: self.fail() @@ -190,11 +191,11 @@ class TestCommands(TestCase): self.commands.register('ZeroHD', '143072699567177728') self.commands.add_shop(0, 0, shop_name='test shop', discord_uuid='143072699567177728') - self.commands.edit_tunnel(bot_config.east_tunnel, 500, 'test shop', discord_uuid='143072699567177728') + self.commands.edit_tunnel(self.bot_config.east_tunnel, 500, 'test shop', discord_uuid='143072699567177728') result = self.commands.info('test shop') - if bot_config.east_tunnel in result: + if self.bot_config.east_tunnel in result: pass else: self.fail() diff --git a/geoffrey/tests/test_geoffreyDatabase.py b/geoffrey/tests/test_geoffreyDatabase.py index 3598d09..5f33f21 100644 --- a/geoffrey/tests/test_geoffreyDatabase.py +++ b/geoffrey/tests/test_geoffreyDatabase.py @@ -1,17 +1,18 @@ from unittest import TestCase from DatabaseInterface import * - +from BotConfig import * class TestGeoffreyDatabase(TestCase): def setUp(self): - self.interface = DatabaseInterface(bot_config.config['SQL']['test_args']) + self.config = get_config() + self.interface = DatabaseInterface(self.config, debug=True) self.session = self.interface.database.Session() self.interface.database.clear_all(self.session) self.owner = Player('ZeroHD', '143072699567177728') self.loc = Location('test', 1, 3, self.owner, dimension='Nether') - self.tunnel = Tunnel(self.owner, bot_config.west_tunnel, 105, self.loc) + self.tunnel = Tunnel(self.owner, self.config.west_tunnel, 105, self.config, self.loc) def tearDown(self): self.session.commit() @@ -90,7 +91,7 @@ class TestGeoffreyDatabase(TestCase): def test_add_tunnel(self): player = self.add_player() - tunnel1 = self.interface.add_tunnel(self.session, player, bot_config.south_tunnel, 155, None) + tunnel1 = self.interface.add_tunnel(self.session, player, self.config.south_tunnel, 155, None, self.config) tunnel2 = self.interface.find_tunnel_by_owner_name(self.session, 'ZeroHD')[0] self.assertEqual(tunnel1, tunnel2)