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):
|
||||
'''Player not found in database.'''
|
||||
|
||||
class LocationNameNotUniqueError(DataBaseError):
|
||||
class EntryNameNotUniqueError(DataBaseError):
|
||||
'''A location by that name is already in the database.'''
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ from difflib import SequenceMatcher
|
|||
|
||||
SQL_Base = declarative_base()
|
||||
|
||||
|
||||
def check_similarity(a, b):
|
||||
ratio = SequenceMatcher(None, a, b).ratio()
|
||||
|
||||
|
@ -19,6 +20,7 @@ def check_similarity(a, b):
|
|||
else:
|
||||
return False
|
||||
|
||||
|
||||
class DatabaseInterface:
|
||||
|
||||
def __init__(self, db_engine_arg):
|
||||
|
@ -34,6 +36,23 @@ class DatabaseInterface:
|
|||
self.database.add_object(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):
|
||||
try:
|
||||
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)
|
||||
|
||||
def find_location_by_owner_name(self, owner_name):
|
||||
owner = self.find_player(owner_name)
|
||||
return self.find_location_by_owner(owner)
|
||||
expr = Location.owner.has(Player.name.ilike(owner_name))
|
||||
return self.database.query_by_filter(Location, expr)
|
||||
|
||||
def find_shop_by_name_and_owner(self, owner, name):
|
||||
expr = (Shop.owner == owner) & (Shop.name.ilike(name))
|
||||
|
@ -93,6 +112,15 @@ class DatabaseInterface:
|
|||
|
||||
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):
|
||||
expr = ItemListing.name.ilike('%{}%'.format(item_name))
|
||||
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)
|
||||
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):
|
||||
owner = DatabaseInterface.find_player_by_discord_uuid(self, owner_uuid)
|
||||
return DatabaseInterface.add_item(self, owner, shop_name, item_name, price, amount)
|
||||
|
@ -209,7 +241,7 @@ class GeoffreyDatabase:
|
|||
self.session.add(obj)
|
||||
self.session.commit()
|
||||
except IntegrityError:
|
||||
raise LocationNameNotUniqueError
|
||||
raise EntryNameNotUniqueError
|
||||
|
||||
def query_by_filter(self, obj_type, * args):
|
||||
filter_value = self.combine_filter(args)
|
||||
|
@ -309,7 +341,7 @@ class Tunnel(SQL_Base):
|
|||
raise TunnelInitError
|
||||
|
||||
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):
|
||||
__tablename__ = 'Locations'
|
||||
|
@ -320,7 +352,7 @@ class Location(SQL_Base):
|
|||
y = Column(Integer)
|
||||
z = Column(Integer)
|
||||
|
||||
tunnel = relationship("Tunnel", back_populates="location")
|
||||
tunnel = relationship("Tunnel", back_populates="location", uselist=False)
|
||||
dimension = Column(Enum(Dimension))
|
||||
|
||||
owner_id = Column(Integer, ForeignKey('Players.id'))
|
||||
|
@ -369,6 +401,18 @@ class Shop(Location):
|
|||
'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):
|
||||
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):
|
||||
error_str = 'Make sure to use ?register first you ding dong.'
|
||||
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.'
|
||||
database_interface.database.session.rollback()
|
||||
else:
|
||||
|
@ -65,6 +65,7 @@ async def test():
|
|||
'''
|
||||
await bot.say('I\'m here you ding dong')
|
||||
|
||||
|
||||
@bot.command(pass_context=True)
|
||||
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):
|
||||
'''
|
||||
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:
|
||||
name = args[0]
|
||||
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:
|
||||
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(
|
||||
except EntryNameNotUniqueError:
|
||||
await bot.say('{}, a based called {} already exists. 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()))
|
||||
|
||||
|
||||
@bot.command(pass_context=True)
|
||||
async def addshop(ctx, x_pos: int, y_pos: int, z_pos: int, *args):
|
||||
'''
|
||||
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:
|
||||
name = args[0]
|
||||
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:
|
||||
shop = 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(
|
||||
except EntryNameNotUniqueError:
|
||||
await bot.say('{}, a shop called {} already exists. You need to specify a different name.'.format(
|
||||
ctx.message.author.mention, name))
|
||||
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()))
|
||||
|
||||
|
||||
@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)
|
||||
async def find(ctx, name: str):
|
||||
'''
|
||||
|
@ -146,6 +177,7 @@ async def find(ctx, name: str):
|
|||
except PlayerNotFound:
|
||||
await bot.say('{}, the player **{}** is not in the database'.format(ctx.message.author.mention, name))
|
||||
|
||||
|
||||
@bot.command(pass_context=True)
|
||||
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)
|
||||
async def selling(ctx, item_name: str):
|
||||
async def selling(item_name: str):
|
||||
'''
|
||||
Lists all the shops selling an item
|
||||
|
||||
|
@ -232,20 +264,15 @@ async def selling(ctx, item_name: str):
|
|||
|
||||
|
||||
@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]
|
||||
inv_list = database_interface.get_shop_inventory(shop)
|
||||
loc = database_interface.find_location_by_name(name)[0]
|
||||
|
||||
item_list = ''
|
||||
for item in inv_list:
|
||||
item_list = item_list + '{}\n'.format(item.__str__())
|
||||
|
||||
await bot.say('{} \n Inventory:\n {}'.format(shop.__str__(), item_list))
|
||||
await bot.say('{}'.format(loc))
|
||||
|
||||
# Helper Functions ************************************************************
|
||||
|
||||
|
|
|
@ -71,6 +71,14 @@ class TestGeoffreyDatabase(TestCase):
|
|||
|
||||
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):
|
||||
owner = self.add_player()
|
||||
self.add_shop()
|
||||
|
@ -180,7 +188,7 @@ class TestGeoffreyDatabase(TestCase):
|
|||
self.add_player()
|
||||
self.add_loc()
|
||||
|
||||
self.assertRaises(LocationNameNotUniqueError, self.interface.add_location,
|
||||
self.assertRaises(EntryNameNotUniqueError, self.interface.add_location,
|
||||
'143072699567177728', 'test', 0, 0, 0)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue