From d5d75841c80f14c8820aea3c323192873776c357 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Thu, 19 Jul 2018 20:18:22 -0500 Subject: [PATCH] Change addbase/addshop syntax and create a tunnel object --- BotErrors.py | 3 ++ DatabaseModels.py | 79 ++++++++++++++++++++-------------------- Geoffrey.py | 77 ++++++++++++++------------------------- test_geoffreyDatabase.py | 13 ++++--- 4 files changed, 77 insertions(+), 95 deletions(-) diff --git a/BotErrors.py b/BotErrors.py index b5edf6a..dd9bace 100644 --- a/BotErrors.py +++ b/BotErrors.py @@ -5,6 +5,9 @@ class DataBaseError(Exception): class LocationInitError(DataBaseError): '''Error in initializing Location''' +class TunnelInitError(DataBaseError): + '''Error in initializing Tunnel''' + class LocationLookUpError(DataBaseError): '''Error in finding location in database''' diff --git a/DatabaseModels.py b/DatabaseModels.py index c49c200..271879d 100644 --- a/DatabaseModels.py +++ b/DatabaseModels.py @@ -24,13 +24,13 @@ class DatabaseInterface: def __init__(self, db_engine_arg): self.database = GeoffreyDatabase(db_engine_arg) - def add_location(self, owner, name, x_pos, y_pos, z_pos, tunnel=None, dimension=None): - location = Location(name, x_pos, y_pos, z_pos, owner, tunnel, dimension) + def add_location(self, owner, name, x_pos, y_pos, z_pos, dimension=None): + location = Location(name, x_pos, y_pos, z_pos, owner, dimension) self.database.add_object(location) return location - def add_shop(self, owner, name, x_pos, y_pos, z_pos, tunnel=None, dimension=None): - shop = Shop(name, x_pos, y_pos, z_pos, owner, tunnel, dimension) + def add_shop(self, owner, name, x_pos, y_pos, z_pos, dimension=None): + shop = Shop(name, x_pos, y_pos, z_pos, owner, dimension) self.database.add_object(shop) return shop @@ -149,13 +149,13 @@ class DatabaseInterface: class DiscordDatabaseInterface(DatabaseInterface): - def add_location(self, owner_uuid, name, x_pos, y_pos, z_pos, tunnel=None, dimension=None): + def add_location(self, owner_uuid, name, x_pos, y_pos, z_pos, dimension=None): owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid) - return DatabaseInterface.add_location(self, owner, name, x_pos, y_pos, z_pos, tunnel, dimension) + return DatabaseInterface.add_location(self, owner, name, x_pos, y_pos, z_pos, dimension) - def add_shop(self, owner_uuid, name, x_pos, y_pos, z_pos, tunnel=None, dimension=None): + def add_shop(self, owner_uuid, name, x_pos, y_pos, z_pos, dimension=None): owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid) - return DatabaseInterface.add_shop(self, owner, name, x_pos, y_pos, z_pos, tunnel, dimension) + return DatabaseInterface.add_shop(self, owner, name, x_pos, y_pos, z_pos, dimension) def add_item(self, owner_uuid, shop_name, item_name, price, amount): owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid) @@ -257,21 +257,6 @@ class TunnelDirection(enum.Enum): else: raise ValueError - -class TunnelSide(enum.Enum): - right = 'right' - left = 'left' - - def str_to_tunnel_side(arg): - arg = arg.lower() - if check_similarity(TunnelSide.right.value, arg): - return TunnelSide.right - elif check_similarity(TunnelSide.left.value, arg): - return TunnelSide.left - else: - raise ValueError - - class Dimension(enum.Enum): overworld = 'overworld' nether = 'nether' @@ -296,6 +281,7 @@ class Player(SQL_Base): discord_uuid = Column(String) name = Column(String) locations = relationship("Location", back_populates="owner", lazy='dynamic') + tunnels = relationship("Tunnel", back_populates="owner", lazy='dynamic') def __init__(self, name, discord_id=None): self.mc_uuid = grab_UUID(name) @@ -303,6 +289,28 @@ class Player(SQL_Base): self.name = name +class Tunnel(SQL_Base): + __tablename__ = 'Tunnels' + id = Column(Integer, primary_key=True, autoincrement=True) + tunnel_number = Column(Integer) + tunnel_direction = Column(Enum(TunnelDirection)) + owner_id = Column(Integer, ForeignKey('Players.id')) + owner = relationship("Player", back_populates="tunnels") + location_id = Column(Integer, ForeignKey('Locations.id')) + location = relationship("Location", back_populates="tunnel") + + def __init__(self, owner, tunnel_color, tunnel_number, location=None): + try: + self.owner = owner + self.location = location + self.tunnel_direction = TunnelDirection.str_to_tunnel_dir(tunnel_color) + self.tunnel_number = tunnel_number + except (ValueError, IndexError): + raise TunnelInitError + + def __str__(self): + return '{} {} {}'.format(self.tunnel_direction.value.title(), self.tunnel_number) + class Location(SQL_Base): __tablename__ = 'Locations' @@ -311,9 +319,8 @@ class Location(SQL_Base): x = Column(Integer) y = Column(Integer) z = Column(Integer) - tunnel_number = Column(Integer) - tunnel_direction = Column(Enum(TunnelDirection)) - tunnel_side = Column(Enum(TunnelSide)) + + tunnel = relationship("Tunnel", back_populates="location") dimension = Column(Enum(Dimension)) owner_id = Column(Integer, ForeignKey('Players.id')) @@ -325,7 +332,7 @@ class Location(SQL_Base): 'polymorphic_identity': 'Location' } - def __init__(self, name, x, y, z, owner, tunnel, dimension): + def __init__(self, name, x, y, z, owner, dimension): try: self.name = name self.x = x @@ -333,12 +340,6 @@ class Location(SQL_Base): self.z = z self.owner = owner - if tunnel is not None: - tunnel_info_list = tunnel.split(',') - self.tunnel_direction = TunnelDirection.str_to_tunnel_dir(tunnel_info_list[0]) - self.tunnel_number = int(tunnel_info_list[1]) - self.tunnel_side = TunnelSide.str_to_tunnel_side(tunnel_info_list[2]) - if self.dimension is not None: self.dimension = self.dimension = Dimension.str_to_dimension(dimension) else: @@ -350,17 +351,15 @@ class Location(SQL_Base): def pos_to_str(self): return '(x= {}, y= {}, z= {}) in the {}'.format(self.x, self.y, self.z, self.dimension.value.title()) - def nether_tunnel_addr_to_str(self): - return '{} {} {}'.format(self.tunnel_direction.value.title(), self.tunnel_number, self.tunnel_side.value.title()) - def __str__(self): - if self.tunnel_direction is not None: + if self.tunnel is not None: return "Name: {}, Position: {}, Tunnel: {}".format(self.name, self.pos_to_str(), - self.nether_tunnel_addr_to_str()) + self.tunnel) else: return "Name: {}, Position: {}".format(self.name, self.pos_to_str()) + class Shop(Location): __tablename__ = 'Shops' shop_id = Column(Integer, ForeignKey('Locations.id'), primary_key=True) @@ -370,8 +369,8 @@ class Shop(Location): 'polymorphic_identity': 'Shop', } - def __init__(self, name, x, y, z, owner, tunnel, dimension): - Location.__init__(self, name, x, y, z, owner, tunnel, dimension) + def __init__(self, name, x, y, z, owner, dimension=None): + Location.__init__(self, name, x, y, z, owner, dimension) class ItemListing(SQL_Base): diff --git a/Geoffrey.py b/Geoffrey.py index d7f21dd..979656c 100644 --- a/Geoffrey.py +++ b/Geoffrey.py @@ -83,34 +83,24 @@ async def register(ctx): @bot.command(pass_context=True) -async def addbase(ctx, name: str, x_pos: int, y_pos: int, z_pos: int, * args): +async def addbase(ctx, x_pos: int, y_pos: int, z_pos: int, * args): ''' - Add your base to the database. - The tunnel address is optional. - The default dimension is the overworld. Valid options: overworld, nether, end - - ?addbase [Base Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Tunnel Color] [Optional Flags] - - Optional Flags: - -t [Tunnel Color],[Tunnel Position],[Side] - -d [dimension] + Adds your base to the database. The name is optional. + ?addbase [Shop Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Name] ''' - flags = get_args_dict(args) - tunnel = None - dimension = None - - if len(flags) > 0: - if '-t' in flags: - tunnel = flags['-t'] - - if '-d' in flags: - dimension = flags['-d'] - + if len(args) > 0: + name = args[0] + else: + name = '{}\'s Base'.format(database_interface.find_player_by_discord_uuid(ctx.message.author.id).name) try: - base = database_interface.add_base(ctx.message.author.id, name, x_pos, y_pos, z_pos, tunnel, dimension) + base = database_interface.add_location(ctx.message.author.id, name, x_pos, y_pos, z_pos) except LocationInitError: raise commands.UserInputError + except LocationNameNotUniqueError: + await bot.say('{}, you already have a based called {}. You need to specify a different name.'.format( + ctx.message.author.mention, name)) + return await bot.say('{}, your base named **{}** located at {} has been added' ' to the database.'.format(ctx.message.author.mention, base.name, base.pos_to_str())) @@ -118,35 +108,26 @@ async def addbase(ctx, name: str, x_pos: int, y_pos: int, z_pos: int, * args): @bot.command(pass_context=True) async def addshop(ctx, name: str, x_pos: int, y_pos: int, z_pos: int, *args): ''' - Adds a shop to the database. - The tunnel address is optional. - The default dimension is the overworld. Valid options: overworld, nether, end - - ?addbase [Shop Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Optional Flags] - - Optional Flags: - -t [Tunnel Color],[Tunnel Position],[Side] - -d [dimension] + Adds your shop to the database. The name is optional. + ?addshop [Base Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Name] ''' - flags = get_args_dict(args) - tunnel = None - dimension = None - - if len(flags) > 0: - if '-t' in flags: - tunnel = flags['-t'] - - if '-d' in flags: - dimension = flags['-d'] + if len(args) > 0: + name = args[0] + else: + name = '{}\'s Shop'.database_interface.find_player_by_discord_uuid(ctx.message.author.id) try: - shop = database_interface.add_shop(ctx.message.author.id, name, x_pos, y_pos, z_pos, tunnel, dimension) + base = database_interface.add_shop(ctx.message.author.id, name, x_pos, y_pos, z_pos) except LocationInitError: raise commands.UserInputError + except LocationNameNotUniqueError: + await bot.say('{}, you already have a shop called {}. You need to specify a different name.'.format( + ctx.message.author.mention, name)) + return await bot.say('{}, your shop named **{}** located at {} has been added' - ' to the database.'.format(ctx.message.author.mention, shop.name, shop.pos_to_str())) + ' to the database.'.format(ctx.message.author.mention, base.name, base.pos_to_str())) @bot.command(pass_context=True) @@ -172,9 +153,8 @@ async def delete(ctx, name: str): ?delete [Location name] ''' - player_name = get_nickname(ctx.message.author) try: - database_interface.delete_base(player_name, name) + database_interface.delete_location(ctx.message.author.id, name) await bot.say('{}, your location named **{}** has been deleted.'.format(ctx.message.author.mention, name)) except (DeleteEntryError, PlayerNotFound): await bot.say('{}, you do not have a location named **{}**.'.format(ctx.message.author.mention, name)) @@ -197,12 +177,12 @@ async def findaround(ctx, x_pos: int, z_pos: int, * args): radius = 200 dimension = 'Overworld' + if len(args) == 1: + radius = args[0] + flags = get_args_dict(args) if len(flags) > 0: - if '-r' in flags: - radius = int(flags['-r']) - if '-d' in flags: dimension = flags['-d'] @@ -227,7 +207,6 @@ async def additem(ctx, shop_name: str, item_name: str, amount: int, diamond_pric ''' try: - player_name = get_nickname(ctx.message.author) database_interface.add_item(ctx.message.author.id, shop_name, item_name, diamond_price, amount) await bot.say('{}, **{}** has been added to the inventory of **{}**.'.format(ctx.message.author.mention, diff --git a/test_geoffreyDatabase.py b/test_geoffreyDatabase.py index 79cd0ac..303a263 100644 --- a/test_geoffreyDatabase.py +++ b/test_geoffreyDatabase.py @@ -7,11 +7,13 @@ class TestGeoffreyDatabase(TestCase): def setUp(self): self.interface = DiscordDatabaseInterface('sqlite:///:memory:') self.owner = Player('ZeroHD', '143072699567177728') - self.loc = Location('test', 1, 2, 3, self.owner, 'Green,105,Right', 'Nether') + self.loc = Location('test', 1, 2, 3, self.owner, dimension='Nether') + self.tunnel = Tunnel(self.owner, 'Green', 105, self.loc) def test_add_object(self): self.interface.database.add_object(self.loc) self.interface.database.add_object(self.owner) + self.interface.database.add_object(self.tunnel) uuid = grab_UUID('ZeroHD') expr = Player.mc_uuid == uuid @@ -50,21 +52,20 @@ class TestGeoffreyDatabase(TestCase): shop_list = self.interface.find_shop_by_name('test') self.assertEqual(shop_list[0].dimension, shop.dimension) - self.assertEqual(shop_list[0].tunnel_side, shop.tunnel_side) def add_shop(self): - return self.interface.add_shop('143072699567177728', 'test', 1, 2, 3, 'Green,105,Right', 'Nether') + return self.interface.add_shop('143072699567177728', 'test', 1, 2, 3, "nether") def add_player(self): return self.interface.add_player('ZeroHD', '143072699567177728') def add_loc(self): - return self.interface.add_location('143072699567177728', 'test', 0, 0, 0, 'Green,105,Right', 'Nether') + return self.interface.add_location('143072699567177728', 'test', 0, 0, 0) def test_add_two_shops(self): owner = self.add_player() shop1 = self.add_shop() - shop2 = self.interface.add_shop('143072699567177728', 'no u', 1, 2, 3, 'Green,0,Right', 'Nether') + shop2 = self.interface.add_shop('143072699567177728', 'no u', 1, 2, 3) loc_list = self.interface.find_location_by_owner_uuid('143072699567177728') @@ -150,7 +151,7 @@ class TestGeoffreyDatabase(TestCase): self.assertEqual(loc_list[0].id, loc.id) - self.interface.add_shop('143072699567177728', 'testshop', 1, 2, 3, 'Green,0,lEft', 'neThEr') + self.interface.add_shop('143072699567177728', 'testshop', 1, 2, 3, 'neThEr') self.interface.add_item('143072699567177728', 'testshop', 'dirts', 1, 15)