Added features and bug fixes according to sprint 1. Added new location info to locations and made getting shop info easier. Also fixed bugs that caused db crahses.

doc_update
Joey Hines 2018-07-03 19:05:35 -05:00
parent 1783c58e2a
commit 06f5feae4e
3 changed files with 99 additions and 38 deletions

View File

@ -30,11 +30,11 @@ class GeoffreyDatabase:
self.add_object(shop)
return shop
def add_item(self, player_name, shop_name, item_name, price):
def add_item(self, player_name, shop_name, item_name, price, amount):
try:
shop = self.find_shop_by_name_and_owner(player_name, shop_name)
item = ItemListing(item_name, price, shop[0])
item = ItemListing(item_name, price, amount, shop[0])
self.add_object(item)
except IndexError:
raise LocationLookUpError
@ -65,11 +65,11 @@ class GeoffreyDatabase:
self.session.commit()
def find_location_by_name(self, name):
expr = Location.name.like('%{}%'.format(name))
expr = Location.name.ilike('%{}%'.format(name))
return self.query_by_filter(Location, expr)
def find_shop_by_name(self, name):
expr = Location.name.like('%{}%'.format(name))
expr = Location.name.ilike('%{}%'.format(name))
return self.query_by_filter(Shop, expr)
def find_location_by_owner(self, owner_name):
@ -79,22 +79,23 @@ class GeoffreyDatabase:
def find_shop_by_name_and_owner(self, owner_name, name):
player = self.find_player(owner_name)
expr = (Shop.owner == player) & (Shop.name == name)
expr = (Shop.owner == player) & (Shop.name.ilike(name))
return self.query_by_filter(Shop, expr)
def find_location_by_name_and_owner(self, owner_name, name):
player = self.find_player(owner_name)
expr = (Location.owner == player) & (Location.name == name)
expr = (Location.owner == player) & (Location.name.ilike(name))
return self.query_by_filter(Location, expr)
def find_location_around(self, x_pos, z_pos, radius):
radius = radius + 1 #gets a the correct area
expr = (Location.x < x_pos + radius) & (Location.x > x_pos - radius) & (Location.z < z_pos + radius) & \
(Location.z > z_pos - radius)
return self.query_by_filter(Location, expr)
def find_item(self, item_name):
expr = ItemListing.name.like(item_name)
expr = ItemListing.name.ilike('{}'.format(item_name))
return self.query_by_filter(ItemListing, expr)
def find_shop_selling_item(self, item_name):
@ -103,6 +104,7 @@ class GeoffreyDatabase:
shops = []
for listing in listings:
shops.append(listing.shop)
shops.append(listing.__str__())
return shops
@ -183,6 +185,38 @@ class TunnelDirection(enum.Enum):
raise ValueError
class TunnelSide(enum.Enum):
right = 'right'
left = 'left'
def str_to_tunnel_side(arg):
arg = arg.lower()
if arg == TunnelSide.right.value:
return TunnelSide.right
elif arg == TunnelSide.left.value:
return TunnelSide.left
else:
raise ValueError
class Dimension(enum.Enum):
overworld = 'overworld'
nether = 'nether'
end = 'end'
def str_to_dimension(arg):
arg = arg.lower()
if arg == Dimension.overworld.value:
return Dimension.overworld
elif arg == Dimension.nether.value:
return Dimension.nether
elif arg == Dimension.end.value:
return Dimension.end
else:
raise ValueError
class Player(SQL_Base):
__tablename__ = 'Players'
@ -205,6 +239,9 @@ class Location(SQL_Base):
z = Column(Integer)
tunnelNumber = Column(Integer)
direction = Column(Enum(TunnelDirection))
tunnel_side = Column(Enum(TunnelSide))
dimension = Column(Enum(Dimension))
owner_id = Column(Integer, ForeignKey('Players.id'))
owner = relationship("Player", back_populates="locations")
type = Column(String)
@ -225,15 +262,21 @@ class Location(SQL_Base):
if len(args) > 0:
self.direction = TunnelDirection.str_to_tunnel_dir(args[0])
self.tunnelNumber = int(args[1])
self.tunnel_side = TunnelSide.str_to_tunnel_side(args[2])
if len(args) > 3:
self.dimension = Dimension.str_to_dimension(args[3])
else:
self.dimension = Dimension.str_to_dimension("overworld")
except (ValueError, IndexError):
raise LocationInitError
def pos_to_str(self):
return '(x= {}, y= {}, z= {})'.format(self.x, self.y, self.z)
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.direction.value.title(), self.tunnelNumber)
return '{} {} {}'.format(self.direction.value.title(), self.tunnelNumber, self.tunnel_side.value.title())
def __str__(self):
if self.direction is not None:
@ -262,14 +305,16 @@ class ItemListing(SQL_Base):
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String)
price = Column(Integer)
amount = Column(Integer)
shop_id = Column(Integer, ForeignKey('Shops.shop_id'))
shop = relationship("Shop", back_populates="inventory")
def __init__(self, name, price, shop):
def __init__(self, name, price, amount, shop):
self.name = name
self.price = price
self.amount = amount
self.shop = shop
def __str__(self):
return "Item: {}, Price: {}D".format(self.name, self.price)
return "Item: {}, Price: {} for {}D".format(self.name, self.amount, self.price)

View File

@ -3,6 +3,7 @@ from DatabaseModels import *
from BotErrors import *
from MinecraftAccountInfoGrabber import *
import configparser
import sqlite3
#from WebInterface import *
TOKEN = ''
@ -38,6 +39,12 @@ async def on_command_error(error, ctx):
.format(ctx.invoked_with, ctx.invoked_with)
elif isinstance(error.original, UsernameLookupFailed):
error_str = error.original.__doc__
elif isinstance(error.original, OverflowError):
error_str = 'Wow buddy, that\'s a big number. Please don\'t do that.'
database.session.rollback()
elif isinstance(error.original, sqlite3.IntegrityError):
error_str = 'Off, the fuck did you do? Try the command again but be less of a ding dong with it.'
database.session.rollback()
else:
error_str = bad_error_message.format(ctx.invoked_with, error)
@ -57,7 +64,8 @@ async def addbase(ctx, name: str, x_pos: int, y_pos: int, z_pos: int, * args):
'''
Add your base to the database.
The tunnel address is optional.
?addbase [Base Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Tunnel Color] [Tunnel Position]
The default dimension is the overworld. Valid options: overworld, nether, end
?addbase [Base Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Tunnel Color] [Tunnel Position] [Side] [Dimension]
'''
player_name = get_nickname(ctx.message.author)
@ -75,7 +83,8 @@ 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.
?addbase [Shop name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Tunnel Color] [Tunnel Position]
The default dimension is the overworld. Valid options: overworld, nether, end
?addbase [Base Name] [X Coordinate] [Y Coordinate] [Z Coordinate] [Tunnel Color] [Tunnel Position] [Side] {Dimension]
'''
player_name = get_nickname(ctx.message.author)
@ -100,7 +109,7 @@ async def find(ctx, name: str):
loc_list = database.find_location_by_owner(name)
loc_string = loc_list_to_string(loc_list, '{} \n{}')
await bot.say('{}, **{}** has **{}** base(s): \n {}'.format(ctx.message.author.mention, name, len(loc_list),
await bot.say('{}, **{}** has **{}** locations(s): \n {}'.format(ctx.message.author.mention, name, len(loc_list),
loc_string))
except PlayerNotFound:
await bot.say('{}, the player **{}** is not in the database'.format(ctx.message.author.mention, name))
@ -123,7 +132,7 @@ async def delete(ctx, name: str):
@bot.command(pass_context=True)
async def findaround(ctx, x_pos: int, z_pos: int, * args):
'''
Finds all the bases/shops around a certain point that are registered in the database
Finds all the locations around a certain point that are registered in the database
The Radius argument defaults to 200 blocks if no value is given
?findbasearound [X Coordinate] [Z Coordinate] [Radius]
'''
@ -140,23 +149,23 @@ async def findaround(ctx, x_pos: int, z_pos: int, * args):
if len(base_list) != 0:
base_string = loc_list_to_string(base_list, '{} \n{}')
await bot.say('{}, there are {} base(s) within {} blocks of that point: \n {}'.format(
await bot.say('{}, there are {} locations(s) within {} blocks of that point: \n {}'.format(
ctx.message.author.mention, len(base_list), radius, base_string))
else:
await bot.say('{}, there are no bases within {} blocks of that point'
await bot.say('{}, there are no locations within {} blocks of that point'
.format(ctx.message.author.mention, radius))
@bot.command(pass_context=True)
async def additem(ctx, shop_name: str, item_name: str, diamond_price: int):
async def additem(ctx, shop_name: str, item_name: str, amount: int, diamond_price: int):
'''
Adds an item to a shop's inventory
?additem [Shop name] [Item Name] [Price]
Adds an item to a shop's inventory. Amount for diamond price.
?additem [Shop name] [Item Name] [Amount] [Price]
'''
try:
player_name = get_nickname(ctx.message.author)
database.add_item(player_name, shop_name, item_name, diamond_price)
database.add_item(player_name, shop_name, item_name, diamond_price, amount)
await bot.say('{}, **{}** has been added to the inventory of **{}**.'.format(ctx.message.author.mention,
item_name, shop_name))

View File

@ -8,7 +8,7 @@ class TestGeoffreyDatabase(TestCase):
def setUp(self):
self.database = GeoffreyDatabase('sqlite:///:memory:')
self.owner = Player('ZeroHD')
self.loc = Location('test', 1, 2, 3, self.owner, ['Green', 0])
self.loc = Location('test', 1, 2, 3, self.owner, ['Green', 0, 'Right'])
def test_add_object(self):
self.database.add_object(self.loc)
@ -43,41 +43,41 @@ class TestGeoffreyDatabase(TestCase):
self.assertRaises(DeleteEntryError, self.database.delete_entry, Location, expr)
def test_add_shop(self):
shop = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0])
shop = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0, 'Right'])
self.assertEqual(type(shop), Shop)
def test_add_two_shops(self):
shop1 = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0])
shop2 = self.database.add_shop('ZeroHD', 'no u', 1, 2, 3, ['Green', 0])
shop1 = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0, 'Right'])
shop2 = self.database.add_shop('ZeroHD', 'no u', 1, 2, 3, ['Green', 0, 'Right'])
loc_list = self.database.find_location_by_owner('ZeroHD')
self.assertEqual(loc_list[1].id, shop2.id)
def test_add_item(self):
self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0])
self.database.add_item('ZeroHD', 'test', 'dirt', 1)
self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0, "Right"])
self.database.add_item('ZeroHD', 'test', 'dirt', 1, 15)
shops = self.database.find_shop_selling_item('dirt')
self.assertEqual(shops[0].name, 'test')
def test_find_location_by_owner(self):
shop = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0])
shop = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0, "Right"])
loc_list = self.database.find_location_by_owner('ZeroHD')
self.assertEqual(loc_list[0].id, shop.id)
def test_find_location_by_name_and_owner(self):
shop = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0])
shop = self.database.add_shop('ZeroHD', 'test', 1, 2, 3, ['Green', 0, "Right"])
loc_list = self.database.find_location_by_name_and_owner('ZeroHD','test')
self.assertEqual(loc_list[0].id, shop.id)
def test_delete_base(self):
self.database.add_location('ZeroHD', 'test', 1, 2, 3, ['Green', 0])
self.database.add_location('ZeroHD', 'test', 1, 2, 3, ['Green', 0, "Right"])
self.database.delete_base('ZeroHD', 'test')
@ -86,35 +86,35 @@ class TestGeoffreyDatabase(TestCase):
self.assertEqual(len(loc_list), 0)
def test_find_location_around(self):
loc = self.database.add_location('ZeroHD', 'test', 0, 0, 0, ['Green', 0])
loc = self.database.add_location('ZeroHD', 'test', 0, 0, 0, ['Green', 0, "Right"])
loc_list = self.database.find_location_around(100, 100, 200)
loc_list = self.database.find_location_around(100, 100, 100)
self.assertEqual(loc_list[0].name, loc.name)
loc_list = self.database.find_location_around(200, 200, 200)
loc_list = self.database.find_location_around(200, 200, 100)
self.assertEqual(len(loc_list), 0)
def test_find_location_by_name(self):
loc = self.database.add_location('ZeroHD', 'test', 0, 0, 0, ['Green', 0])
loc = self.database.add_location('ZeroHD', 'test', 0, 0, 0, ['Green', 0, "Right"])
loc_list = self.database.find_location_by_name('test')
self.assertEqual(loc_list[0].name, loc.name)
def test_wrong_case(self):
loc = self.database.add_location('ZeroHD', 'test', 0, 0, 0, ['Green', 0])
loc = self.database.add_location('ZeroHD', 'test', 0, 0, 0, ['Green', 0, "right"])
loc_list = self.database.find_location_by_owner('zerohd')
self.assertEqual(loc_list[0].id, loc.id)
self.database.add_shop('ZeroHD', 'testshop', 1, 2, 3, ['Green', 0])
self.database.add_shop('ZeroHD', 'testshop', 1, 2, 3, ['Green', 0, "lEft", "neThEr"])
self.database.add_item('ZeroHD', 'testshop', 'dirt', 1)
self.database.add_item('ZeroHD', 'testshop', 'dirt', 1, 15)
shops = self.database.find_shop_selling_item('Dirt')
shops = self.database.find_shop_selling_item('Dirts')
self.assertEqual(shops[0].name, 'testshop')
@ -122,6 +122,13 @@ class TestGeoffreyDatabase(TestCase):
self.assertEqual(loc_list[0].name, 'test')
def test_big_input(self):
loc = self.database.add_location('ZeroHD',
'TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT', 0, 0, 0, ['Green', 0, "Right"])
loc_list = self.database.find_location_by_owner('zerohd')
self.assertEqual(loc_list[0].id, loc.id)