Added commands and interface support for the new shops. Also changed how linked objects handle printing.
parent
29673bdfe8
commit
625e4dc796
|
@ -21,7 +21,7 @@ class UsernameLookupFailed(Exception):
|
||||||
class PlayerNotFound(DataBaseError):
|
class PlayerNotFound(DataBaseError):
|
||||||
'''Player not found in database.'''
|
'''Player not found in database.'''
|
||||||
|
|
||||||
class LocationNameNotUniqueError(DataBaseError):
|
class EntryNameNotUniqueError(DataBaseError):
|
||||||
'''A location by that name is already in the database.'''
|
'''A location by that name is already in the database.'''
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ from difflib import SequenceMatcher
|
||||||
|
|
||||||
SQL_Base = declarative_base()
|
SQL_Base = declarative_base()
|
||||||
|
|
||||||
|
|
||||||
def check_similarity(a, b):
|
def check_similarity(a, b):
|
||||||
ratio = SequenceMatcher(None, a, b).ratio()
|
ratio = SequenceMatcher(None, a, b).ratio()
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ def check_similarity(a, b):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
class DatabaseInterface:
|
class DatabaseInterface:
|
||||||
|
|
||||||
def __init__(self, db_engine_arg):
|
def __init__(self, db_engine_arg):
|
||||||
|
@ -34,6 +36,23 @@ class DatabaseInterface:
|
||||||
self.database.add_object(shop)
|
self.database.add_object(shop)
|
||||||
return shop
|
return shop
|
||||||
|
|
||||||
|
def add_tunnel(self, owner, color, number, location_name):
|
||||||
|
if location_name is None:
|
||||||
|
if len(self.find_tunnel_by_owner(owner)):
|
||||||
|
raise EntryNameNotUniqueError
|
||||||
|
else:
|
||||||
|
location = None
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
location = self.find_location_by_name_and_owner(owner, location_name)[0]
|
||||||
|
except IndexError:
|
||||||
|
raise LocationLookUpError
|
||||||
|
|
||||||
|
tunnel = Tunnel(owner, color, number, location)
|
||||||
|
|
||||||
|
self.database.add_object(tunnel)
|
||||||
|
return tunnel
|
||||||
|
|
||||||
def add_item(self, owner, shop_name, item_name, price, amount):
|
def add_item(self, owner, shop_name, item_name, price, amount):
|
||||||
try:
|
try:
|
||||||
shop = self.find_shop_by_name_and_owner(owner, shop_name)
|
shop = self.find_shop_by_name_and_owner(owner, shop_name)
|
||||||
|
@ -75,8 +94,8 @@ class DatabaseInterface:
|
||||||
return self.database.query_by_filter(Location, expr)
|
return self.database.query_by_filter(Location, expr)
|
||||||
|
|
||||||
def find_location_by_owner_name(self, owner_name):
|
def find_location_by_owner_name(self, owner_name):
|
||||||
owner = self.find_player(owner_name)
|
expr = Location.owner.has(Player.name.ilike(owner_name))
|
||||||
return self.find_location_by_owner(owner)
|
return self.database.query_by_filter(Location, expr)
|
||||||
|
|
||||||
def find_shop_by_name_and_owner(self, owner, name):
|
def find_shop_by_name_and_owner(self, owner, name):
|
||||||
expr = (Shop.owner == owner) & (Shop.name.ilike(name))
|
expr = (Shop.owner == owner) & (Shop.name.ilike(name))
|
||||||
|
@ -93,6 +112,15 @@ class DatabaseInterface:
|
||||||
|
|
||||||
return self.database.query_by_filter(Location, expr)
|
return self.database.query_by_filter(Location, expr)
|
||||||
|
|
||||||
|
def find_tunnel_by_owner(self, owner):
|
||||||
|
expr = Tunnel.owner == owner
|
||||||
|
|
||||||
|
return self.database.query_by_filter(Tunnel, expr)
|
||||||
|
|
||||||
|
def find_tunnel_by_owner_name(self, owner_name):
|
||||||
|
expr = Tunnel.owner.has(Player.name.ilike(owner_name))
|
||||||
|
return self.database.query_by_filter(Tunnel, expr)
|
||||||
|
|
||||||
def find_item(self, item_name):
|
def find_item(self, item_name):
|
||||||
expr = ItemListing.name.ilike('%{}%'.format(item_name))
|
expr = ItemListing.name.ilike('%{}%'.format(item_name))
|
||||||
return self.database.query_by_filter(ItemListing, expr)
|
return self.database.query_by_filter(ItemListing, expr)
|
||||||
|
@ -157,6 +185,10 @@ class DiscordDatabaseInterface(DatabaseInterface):
|
||||||
owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid)
|
owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid)
|
||||||
return DatabaseInterface.add_shop(self, owner, name, x_pos, y_pos, z_pos, dimension)
|
return DatabaseInterface.add_shop(self, owner, name, x_pos, y_pos, z_pos, dimension)
|
||||||
|
|
||||||
|
def add_tunnel(self, owner_uuid, color, number, location_name=""):
|
||||||
|
owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid)
|
||||||
|
return DatabaseInterface.add_tunnel(self, owner, color, number, location_name)
|
||||||
|
|
||||||
def add_item(self, owner_uuid, shop_name, item_name, price, amount):
|
def add_item(self, owner_uuid, shop_name, item_name, price, amount):
|
||||||
owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid)
|
owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid)
|
||||||
return DatabaseInterface.add_item(self, owner, shop_name, item_name, price, amount)
|
return DatabaseInterface.add_item(self, owner, shop_name, item_name, price, amount)
|
||||||
|
@ -209,7 +241,7 @@ class GeoffreyDatabase:
|
||||||
self.session.add(obj)
|
self.session.add(obj)
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
except IntegrityError:
|
except IntegrityError:
|
||||||
raise LocationNameNotUniqueError
|
raise EntryNameNotUniqueError
|
||||||
|
|
||||||
def query_by_filter(self, obj_type, * args):
|
def query_by_filter(self, obj_type, * args):
|
||||||
filter_value = self.combine_filter(args)
|
filter_value = self.combine_filter(args)
|
||||||
|
@ -309,7 +341,7 @@ class Tunnel(SQL_Base):
|
||||||
raise TunnelInitError
|
raise TunnelInitError
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} {} {}'.format(self.tunnel_direction.value.title(), self.tunnel_number)
|
return '{} {}'.format(self.tunnel_direction.value.title(), self.tunnel_number)
|
||||||
|
|
||||||
class Location(SQL_Base):
|
class Location(SQL_Base):
|
||||||
__tablename__ = 'Locations'
|
__tablename__ = 'Locations'
|
||||||
|
@ -320,7 +352,7 @@ class Location(SQL_Base):
|
||||||
y = Column(Integer)
|
y = Column(Integer)
|
||||||
z = Column(Integer)
|
z = Column(Integer)
|
||||||
|
|
||||||
tunnel = relationship("Tunnel", back_populates="location")
|
tunnel = relationship("Tunnel", back_populates="location", uselist=False)
|
||||||
dimension = Column(Enum(Dimension))
|
dimension = Column(Enum(Dimension))
|
||||||
|
|
||||||
owner_id = Column(Integer, ForeignKey('Players.id'))
|
owner_id = Column(Integer, ForeignKey('Players.id'))
|
||||||
|
@ -369,6 +401,18 @@ class Shop(Location):
|
||||||
'polymorphic_identity': 'Shop',
|
'polymorphic_identity': 'Shop',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def inv_to_str(self):
|
||||||
|
inv = ''
|
||||||
|
str_format = '{}\n\t{}'
|
||||||
|
|
||||||
|
for item in self.inventory:
|
||||||
|
inv = str_format.format(inv, item)
|
||||||
|
|
||||||
|
return inv
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return Location.__str__(self) + "\n\t*Inventory*: {}".format(self.inv_to_str())
|
||||||
|
|
||||||
def __init__(self, name, x, y, z, owner, dimension=None):
|
def __init__(self, name, x, y, z, owner, dimension=None):
|
||||||
Location.__init__(self, name, x, y, z, owner, dimension)
|
Location.__init__(self, name, x, y, z, owner, dimension)
|
||||||
|
|
||||||
|
|
67
Geoffrey.py
67
Geoffrey.py
|
@ -49,7 +49,7 @@ async def on_command_error(error, ctx):
|
||||||
elif isinstance(error.original, PlayerNotFound):
|
elif isinstance(error.original, PlayerNotFound):
|
||||||
error_str = 'Make sure to use ?register first you ding dong.'
|
error_str = 'Make sure to use ?register first you ding dong.'
|
||||||
database_interface.database.session.rollback()
|
database_interface.database.session.rollback()
|
||||||
elif isinstance(error.original, LocationNameNotUniqueError):
|
elif isinstance(error.original, EntryNameNotUniqueError):
|
||||||
error_str = 'An entry in the database already has that name ding dong.'
|
error_str = 'An entry in the database already has that name ding dong.'
|
||||||
database_interface.database.session.rollback()
|
database_interface.database.session.rollback()
|
||||||
else:
|
else:
|
||||||
|
@ -65,6 +65,7 @@ async def test():
|
||||||
'''
|
'''
|
||||||
await bot.say('I\'m here you ding dong')
|
await bot.say('I\'m here you ding dong')
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
@bot.command(pass_context=True)
|
||||||
async def register(ctx):
|
async def register(ctx):
|
||||||
'''
|
'''
|
||||||
|
@ -86,43 +87,44 @@ async def register(ctx):
|
||||||
async def addbase(ctx, x_pos: int, y_pos: int, z_pos: int, * args):
|
async def addbase(ctx, x_pos: int, y_pos: int, z_pos: int, * args):
|
||||||
'''
|
'''
|
||||||
Adds your base to the database. The name is optional.
|
Adds your base to the database. The name is optional.
|
||||||
?addbase [Shop Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Name]
|
?addbase [X Coordinate] [Y Coordinate] [Z Coordinate] [Base Name]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if len(args) > 0:
|
if len(args) > 0:
|
||||||
name = args[0]
|
name = args[0]
|
||||||
else:
|
else:
|
||||||
name = '{}\'s Base'.format(database_interface.find_player_by_discord_uuid(ctx.message.author.id).name)
|
name = '{}\'s_Base'.format(database_interface.find_player_by_discord_uuid(ctx.message.author.id).name)
|
||||||
try:
|
try:
|
||||||
base = database_interface.add_location(ctx.message.author.id, name, x_pos, y_pos, z_pos)
|
base = database_interface.add_location(ctx.message.author.id, name, x_pos, y_pos, z_pos)
|
||||||
except LocationInitError:
|
except LocationInitError:
|
||||||
raise commands.UserInputError
|
raise commands.UserInputError
|
||||||
except LocationNameNotUniqueError:
|
except EntryNameNotUniqueError:
|
||||||
await bot.say('{}, you already have a based called {}. You need to specify a different name.'.format(
|
await bot.say('{}, a based called {} already exists. You need to specify a different name.'.format(
|
||||||
ctx.message.author.mention, name))
|
ctx.message.author.mention, name))
|
||||||
return
|
return
|
||||||
|
|
||||||
await bot.say('{}, your base named **{}** located at {} has been added'
|
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()))
|
' to the database.'.format(ctx.message.author.mention, base.name, base.pos_to_str()))
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
@bot.command(pass_context=True)
|
||||||
async def addshop(ctx, x_pos: int, y_pos: int, z_pos: int, *args):
|
async def addshop(ctx, x_pos: int, y_pos: int, z_pos: int, *args):
|
||||||
'''
|
'''
|
||||||
Adds your shop to the database. The name is optional.
|
Adds your shop to the database. The name is optional.
|
||||||
?addshop [Shop Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Name]
|
?addshop [X Coordinate] [Y Coordinate] [Z Coordinate] [Shop Name]
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if len(args) > 0:
|
if len(args) > 0:
|
||||||
name = args[0]
|
name = args[0]
|
||||||
else:
|
else:
|
||||||
name = '{}\'s Shop'.format(database_interface.find_player_by_discord_uuid(ctx.message.author.id).name)
|
name = '{}\'s_Shop'.format(database_interface.find_player_by_discord_uuid(ctx.message.author.id).name)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
shop = database_interface.add_shop(ctx.message.author.id, name, x_pos, y_pos, z_pos)
|
shop = database_interface.add_shop(ctx.message.author.id, name, x_pos, y_pos, z_pos)
|
||||||
except LocationInitError:
|
except LocationInitError:
|
||||||
raise commands.UserInputError
|
raise commands.UserInputError
|
||||||
except LocationNameNotUniqueError:
|
except EntryNameNotUniqueError:
|
||||||
await bot.say('{}, you already have a shop called {}. You need to specify a different name.'.format(
|
await bot.say('{}, a shop called {} already exists. You need to specify a different name.'.format(
|
||||||
ctx.message.author.mention, name))
|
ctx.message.author.mention, name))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -130,6 +132,35 @@ async def addshop(ctx, x_pos: int, y_pos: int, z_pos: int, *args):
|
||||||
' to the database.'.format(ctx.message.author.mention, shop.name, shop.pos_to_str()))
|
' to the database.'.format(ctx.message.author.mention, shop.name, shop.pos_to_str()))
|
||||||
|
|
||||||
|
|
||||||
|
@bot.command(pass_context=True)
|
||||||
|
async def tunnel(ctx, tunnel_color: str, tunnel_number: int, *args):
|
||||||
|
'''
|
||||||
|
Adds your tunnel to the database. The location name is optional. If the location has a tunnel, it is updated.
|
||||||
|
?addtunnel [Tunnel Color] [Tunnel_Number] [Location Name]
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
if len(args) == 0:
|
||||||
|
location_name = None
|
||||||
|
else:
|
||||||
|
location_name = args[0]
|
||||||
|
|
||||||
|
database_interface.add_tunnel(ctx.message.author.id, tunnel_color, tunnel_number, location_name)
|
||||||
|
except EntryNameNotUniqueError:
|
||||||
|
await bot.say('{}, you already have one tunnel in the database, please specify a location.'.format(
|
||||||
|
ctx.message.author.mention))
|
||||||
|
return
|
||||||
|
except LocationLookUpError:
|
||||||
|
await bot.say('{}, you do not have a location called {}.'.format(
|
||||||
|
ctx.message.author.mention, args[0]))
|
||||||
|
return
|
||||||
|
|
||||||
|
except ValueError:
|
||||||
|
raise commands.UserInputError
|
||||||
|
|
||||||
|
await bot.say('{}, your tunnel has been added to the database'.format(ctx.message.author.mention))
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
@bot.command(pass_context=True)
|
||||||
async def find(ctx, name: str):
|
async def find(ctx, name: str):
|
||||||
'''
|
'''
|
||||||
|
@ -146,6 +177,7 @@ async def find(ctx, name: str):
|
||||||
except PlayerNotFound:
|
except PlayerNotFound:
|
||||||
await bot.say('{}, the player **{}** is not in the database'.format(ctx.message.author.mention, name))
|
await bot.say('{}, the player **{}** is not in the database'.format(ctx.message.author.mention, name))
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
@bot.command(pass_context=True)
|
||||||
async def delete(ctx, name: str):
|
async def delete(ctx, name: str):
|
||||||
'''
|
'''
|
||||||
|
@ -219,7 +251,7 @@ async def additem(ctx, shop_name: str, item_name: str, amount: int, diamond_pric
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
@bot.command(pass_context=True)
|
||||||
async def selling(ctx, item_name: str):
|
async def selling(item_name: str):
|
||||||
'''
|
'''
|
||||||
Lists all the shops selling an item
|
Lists all the shops selling an item
|
||||||
|
|
||||||
|
@ -232,20 +264,15 @@ async def selling(ctx, item_name: str):
|
||||||
|
|
||||||
|
|
||||||
@bot.command(pass_context=True)
|
@bot.command(pass_context=True)
|
||||||
async def shopinfo(ctx, shop_name: str):
|
async def info(name: str):
|
||||||
'''
|
'''
|
||||||
Lists the information and inventory of a shop
|
Displays a location's info including inventory its a shop
|
||||||
|
|
||||||
?shopinfo [Shop Name]
|
?info [Location Name]
|
||||||
'''
|
'''
|
||||||
shop = database_interface.find_shop_by_name(shop_name)[0]
|
loc = database_interface.find_location_by_name(name)[0]
|
||||||
inv_list = database_interface.get_shop_inventory(shop)
|
|
||||||
|
|
||||||
item_list = ''
|
await bot.say('{}'.format(loc))
|
||||||
for item in inv_list:
|
|
||||||
item_list = item_list + '{}\n'.format(item.__str__())
|
|
||||||
|
|
||||||
await bot.say('{} \n Inventory:\n {}'.format(shop.__str__(), item_list))
|
|
||||||
|
|
||||||
# Helper Functions ************************************************************
|
# Helper Functions ************************************************************
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,14 @@ class TestGeoffreyDatabase(TestCase):
|
||||||
|
|
||||||
self.assertEqual(loc_list[1].id, shop2.id)
|
self.assertEqual(loc_list[1].id, shop2.id)
|
||||||
|
|
||||||
|
def test_add_tunnel(self):
|
||||||
|
self.add_player()
|
||||||
|
args=[]
|
||||||
|
tunnel1 = self.interface.add_tunnel('143072699567177728', 'green', 155, None)
|
||||||
|
|
||||||
|
tunnel2 = self.interface.find_tunnel_by_owner_name('ZeroHD')[0]
|
||||||
|
self.assertEqual(tunnel1, tunnel2)
|
||||||
|
|
||||||
def test_add_item(self):
|
def test_add_item(self):
|
||||||
owner = self.add_player()
|
owner = self.add_player()
|
||||||
self.add_shop()
|
self.add_shop()
|
||||||
|
@ -180,7 +188,7 @@ class TestGeoffreyDatabase(TestCase):
|
||||||
self.add_player()
|
self.add_player()
|
||||||
self.add_loc()
|
self.add_loc()
|
||||||
|
|
||||||
self.assertRaises(LocationNameNotUniqueError, self.interface.add_location,
|
self.assertRaises(EntryNameNotUniqueError, self.interface.add_location,
|
||||||
'143072699567177728', 'test', 0, 0, 0)
|
'143072699567177728', 'test', 0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue