diff --git a/geoffrey/Commands.py b/geoffrey/Commands.py index 9970046..4c35440 100644 --- a/geoffrey/Commands.py +++ b/geoffrey/Commands.py @@ -1,6 +1,15 @@ from geoffrey.DatabaseInterface import * +def list_to_string(loc_list, str_format='{}\n{}'): + loc_string = '' + + for loc in loc_list: + loc_string = str_format.format(loc_string, loc) + + return loc_string + + class Commands: def __init__(self, bot_config, debug=False): self.bot_config = bot_config @@ -107,13 +116,25 @@ class Commands: return tunnel_info def find(self, search): + limit = 25 session = self.interface.database.Session() try: - result = self.interface.search_all_fields(session, search) + locations = self.interface.search_all_fields(session, search, limit) + locations_string = '' + + if len(locations) > 0: + + for loc in locations: + locations_string = "{}\n{}".format(locations_string, loc) + + if len(locations) == limit: + locations_string = locations_string + '\n**. . .**' + else: + raise LocationLookUpError finally: session.close() - return result + return locations_string def delete(self, name, discord_uuid=None, mc_uuid=None): @@ -130,10 +151,12 @@ class Commands: try: loc_list = self.interface.find_location_around(session, x_pos, z_pos, radius, dimension) + + loc_list_str = list_to_string(loc_list) finally: session.close() - return loc_list + return loc_list_str def add_item(self, item_name, quantity, diamond_price, shop_name=None, discord_uuid=None, mc_uuid=None): session = self.interface.database.Session() @@ -157,10 +180,12 @@ class Commands: if len(shop_list) == 0: raise ItemNotFound + + shop_list_str = list_to_string(shop_list) finally: session.close() - return shop_list + return shop_list_str def info(self, location_name): session = self.interface.database.Session() @@ -277,8 +302,7 @@ class Commands: shop = self.get_location(session, player, shop_name, Shop) - expr = (ItemListing.name == item) & (ItemListing.shop == shop) - self.interface.database.delete_entry(session, ItemListing, expr) + self.interface.delete_item(session, shop, item) shop_str = shop.name finally: diff --git a/geoffrey/DatabaseInterface.py b/geoffrey/DatabaseInterface.py index a55c77a..51db217 100644 --- a/geoffrey/DatabaseInterface.py +++ b/geoffrey/DatabaseInterface.py @@ -87,7 +87,7 @@ class DatabaseInterface: (loc_type.z < z_pos + radius + 1) \ & (loc_type.z > z_pos - radius - 1) & (loc_type.dimension == dimension_obj) - return list_to_string(self.database.query_by_filter(session, Location, expr)) + return self.database.query_by_filter(session, Location, expr) def find_tunnel_by_owner(self, session, owner): expr = Tunnel.owner == owner @@ -100,11 +100,10 @@ class DatabaseInterface: def find_item(self, session, item_name): expr = ItemListing.name.ilike('%{}%'.format(item_name)) - return self.database.query_by_filter(session, ItemListing, expr) + return self.database.query_by_filter(session, ItemListing, expr, sort=ItemListing.normalized_price) def find_shop_selling_item(self, session, item_name): - listings = self.find_item(session, item_name) - return list_to_string(listings) + return self.find_item(session, item_name) def find_player(self, session, player_name): expr = Player.name.ilike(player_name) @@ -136,47 +135,16 @@ class DatabaseInterface: raise PlayerNotFound return player - def search_all_fields(self, session, search): - loc_string = '' - limit = 10 - + def search_all_fields(self, session, search, limit=25): expr = Location.owner.has(Player.name.ilike('%{}%'.format(search))) | Location.name.ilike('%{}%'.format(search)) locations = self.database.query_by_filter(session, Location, expr, limit=limit) - if len(locations) > 0: - loc_string = loc_string + '\n**Locations:**' - - for loc in locations: - loc_string = "{}\n{}".format(loc_string, loc) - - if len(locations) == limit: - loc_string = loc_string + '\n**. . .**' - - expr = Tunnel.owner.has(Player.name.ilike('%{}%'.format(search))) & Tunnel.location is None - tunnels = self.database.query_by_filter(session, Tunnel, expr) - - if len(tunnels) > 0: - loc_string = loc_string + '\n\n**Tunnels:**' - for tunnel in tunnels: - loc_string = "{}\n{}".format(loc_string, tunnel.full_str()) - - if len(tunnels) == limit: - loc_string = loc_string + '\n**. . .**' - - if len(tunnels) + len(locations) == 0: - raise LocationLookUpError - else: - return loc_string + return locations def delete_location(self, session, owner, name): expr = (Location.owner == owner) & (Location.name == name) self.database.delete_entry(session, Location, expr) - -def list_to_string(loc_list, str_format='{}\n{}'): - loc_string = '' - - for loc in loc_list: - loc_string = str_format.format(loc_string, loc) - - return loc_string + def delete_item(self, session, shop, item_name): + expr = (ItemListing.name == item_name) & (ItemListing.shop == shop) + self.database.delete_entry(session, ItemListing, expr) diff --git a/geoffrey/DatabaseModels.py b/geoffrey/DatabaseModels.py index 6e853ca..5308d04 100644 --- a/geoffrey/DatabaseModels.py +++ b/geoffrey/DatabaseModels.py @@ -6,6 +6,7 @@ from sqlalchemy.exc import IntegrityError, DataError from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship, column_property, sessionmaker from sqlalchemy.sql import expression +from sqlalchemy.ext.hybrid import hybrid_property from geoffrey.BotErrors import * from geoffrey.MinecraftAccountInfoGrabber import * @@ -56,9 +57,9 @@ class GeoffreyDatabase: session.rollback() raise Exception - def query_by_filter(self, session, obj_type, *args, limit=10): + def query_by_filter(self, session, obj_type, *args, sort=None, limit=10): filter_value = self.combine_filter(args) - return session.query(obj_type).filter(filter_value).limit(limit).all() + return session.query(obj_type).filter(filter_value).order_by(sort).limit(limit).all() def delete_entry(self, session, obj_type, *args): @@ -290,6 +291,14 @@ class ItemListing(SQL_Base): self.amount = amount self.shop = shop + @hybrid_property + def normalized_price(self): + return self.price / self.amount + + @normalized_price.expression + def normalized_price(cls): + return cls.price / cls.amount + def listing_str(self): return '**{}** **{}** for **{}D**'.format(self.amount, self.name, self.price) diff --git a/geoffrey/tests/test_geoffreyDatabase.py b/geoffrey/tests/test_geoffreyDatabase.py index 5a308c0..d9f94cb 100644 --- a/geoffrey/tests/test_geoffreyDatabase.py +++ b/geoffrey/tests/test_geoffreyDatabase.py @@ -133,7 +133,7 @@ class TestGeoffreyDatabase(TestCase): p1 = self.add_player() p2 = self.interface.find_player_by_discord_uuid(self.session, 143072699567177728) - self.assertEquals(p1, p2) + self.assertEqual(p1, p2) self.assertRaises(PlayerNotFound, self.interface.find_player_by_discord_uuid, self.session, 143072698) @@ -141,7 +141,7 @@ class TestGeoffreyDatabase(TestCase): p1 = self.add_player() p2 = self.interface.find_player_by_mc_uuid(self.session, 'fe7e84132570458892032b69ff188bc3') - self.assertEquals(p1, p2) + self.assertEqual(p1, p2) self.assertRaises(PlayerNotFound, self.interface.find_player_by_discord_uuid, self.session, 143072698)