from discord.ext import commands from GeoffreyBot.DiscordHelperFunctions import * from GeoffreyBot.GeoffreyApiHelper import * import requests default_error_messages = { "PlayerNotFound": "You are not in the database, do ?register first!", "NoLocationsInDatabase": "You have no locations in the database, you need to add some first!", "DataError": "Slow down their slugger, that's a long word or number you are trying to cram into me, try again with " "something smaller, please", "LocationHasTunnelError": "that location already has a tunnel you goober.", "EntryNameNotUniqueError": "that name has already been used, be more creative dingus kong" } class HandledError(Exception): pass class CommandError: def __init__(self, error, message): self.error = error self.message = message async def run_command(ctx, base_url, api_token, request_type, command, errors=None, **kwargs): URL = base_url + '/GeoffreyApp/api/command/{}/' kwargs["api"] = api_token if request_type == "GET": response = requests.get(url=URL.format(command), params=kwargs) elif request_type == "POST": response = requests.post(url=URL.format(command), data=kwargs) else: raise TypeError json = response.json() if "error" in json: error_name = json["error"] if error_name in errors: msg = errors[error_name] elif error_name in default_error_messages: msg = default_error_messages[error_name] else: raise Exception(json['error'], json["error_message"]) await ctx.send("{}, {}".format(ctx.message.author.mention, msg)) raise HandledError else: return json class GeoffreyCommands(commands.Cog): def __init__(self, bot): self.bot = bot self.base_url = bot.base_url self.api_token = bot.api_token @commands.command(pass_context=True) async def add_attraction(self, ctx, x_pos: int, z_pos: int, *args): """ {}add_attraction The Name parameter is optional if this is your first attraction """ errors = { "LocationLookUpError": "you have more than one location. Please specify a name." } name = get_name(args) attraction = await run_command(ctx, self.base_url, self.api_token, "POST", "add_attraction", x_pos=x_pos, z_pos=z_pos, name=name, discord_uuid=ctx.message.author.id, errors=errors) await ctx.send( '{}, your attraction has been added to the database: \n{}'.format(ctx.message.author.mention, formatted_location(attraction))) @commands.command(pass_context=True) async def add_base(self, ctx, x_pos: int, z_pos: int, *args): """ {}add_base The Name parameter is optional if this is your first base """ errors = { "LocationLookUpError": "you have more than one location. Please specify a name." } name = get_name(args) base = await run_command(ctx, self.base_url, self.api_token, "POST", "add_base", x_pos=x_pos, z_pos=z_pos, name=name, discord_uuid=ctx.message.author.id, errors=errors) await ctx.send( '{}, your base has been added to the database: \n{}'.format(ctx.message.author.mention, formatted_location(base))) @commands.command(pass_context=True) async def add_farm(self, ctx, x_pos: int, z_pos: int, *args): """ {}add_farm The Name parameter is optional if this is your first farm """ errors = { "LocationLookUpError": "you have more than one location. Please specify a name." } name = get_name(args) farm = await run_command(ctx, self.base_url, self.api_token, "POST", "add_farm", x_pos=x_pos, z_pos=z_pos, name=name, discord_uuid=ctx.message.author.id, errors=errors) await ctx.send( '{}, your farm has been added to the database: \n{}'.format(ctx.message.author.mention, formatted_location(farm))) @commands.command(pass_context=True) async def add_item(self, ctx, item_name, quantity: int, diamond_price: int, *args): """ {}add_item If item name contains spaces, it must be wrapped in quotes. eg "Diamond Pickaxe" The Shop Name parameter is optional if this is your first shop """ errors = { "LocationLookUpError": "You do not have a shop by that name, goober.", "EntryNameNotUniqueError": "You have more than one location. Please specify a name, dingus." } shop_name = get_name(args) item = await run_command(ctx, self.base_url, self.api_token, "POST", "add_item", item_name=item_name, quantity=quantity, diamond_price=diamond_price, shop_name=shop_name, discord_uuid=ctx.message.author.id, errors=errors) await ctx.send('{}, **{}** has been added to the inventory of **{}**'.format(ctx.message.author.mention, item["item_name"], item["shop"]["name"])) @commands.command(pass_context=True) async def add_market(self, ctx, x_pos: int, z_pos: int, *args): """ {}add_market The Name parameter is optional if this is your first market """ errors = { "LocationLookUpError": "you have more than one location. Please specify a name." } name = get_name(args) market = await run_command(ctx, self.base_url, self.api_token, "POST", "add_market", x_pos=x_pos, z_pos=z_pos, name=name, discord_uuid=ctx.message.author.id, errors=errors) await ctx.send( '{}, your market has been added to the database: \n{}'.format(ctx.message.author.mention, formatted_location(market))) @commands.command(pass_context=True) async def add_owner(self, ctx, new_owner_name, *args): """ {}add_owner WARNING: The new owner has just as much power as you to edit or delete this location. """ errors = { "OwnerNotFoundError": "ain't no one in this darn database named **{}** you goob".format(new_owner_name), "IsOwnerError": "**{}** is already an owner, stop having amosia.".format(new_owner_name), "LocationLookUpError": "you do not have a location by that name you ding dong goober." } location_name = get_name(args) location = await run_command(ctx, self.base_url, self.api_token, "POST", "add_owner", errors=errors, new_owner_name=new_owner_name, location_name=location_name, discord_uuid=ctx.message.author.id) await ctx.send('{}, **{}** has been added as an owner to **{}**'.format( ctx.message.author.mention, new_owner_name, location["name"])) @commands.command(pass_context=True) async def add_resident(self, ctx, new_resident_name, *args): """ {}add_resident """ errors = { "ResidentNotFoundError": "ain't no one in this darn database named **{}** you goob".format( new_resident_name), "IsResidentError": "**{}** is already a resident, stop having amosia.".format(new_resident_name), "LocationLookUpError": "you do not have a town by that name you ding dong goober." } town_name = get_name(args) location = await run_command(ctx, self.base_url, self.api_token, "POST", "add_resident", errors=errors, new_resident_name=new_resident_name, town_name=town_name, discord_uuid=ctx.message.author.id) await ctx.send('{}, **{}** has been added as a resident to **{}**'.format( ctx.message.author.mention, new_resident_name, location["name"])) @commands.command(pass_context=True) async def add_resource(self, ctx, resource_name, *args): """ {}add_item If resource name contains spaces, it must be wrapped in quotes. eg "Rotten Flesh" The Farm Name parameter is optional if this is your first farm """ errors = { "LocationLookUpError": "You do not have a farm by that name, goober.", "EntryNameNotUniqueError": "You have more than one farm. Please specify a name, dingus." } farm_name = get_name(args) resource = await run_command(ctx, self.base_url, self.api_token, "POST", "add_resource", errors=errors, resource_name=resource_name, farm_name=farm_name, discord_uuid=ctx.message.author.id) await ctx.send('{}, **{}** has been added to the farm.'.format(ctx.message.author.mention, resource["name"])) @commands.command(pass_context=True) async def add_shop(self, ctx, x_pos: int, z_pos: int, *args): """ {}add_shop The Shop Name parameter is optional if this is your first shop """ errors = { "LocationLookUpError": "you have more than one location. Please specify a name." } name = get_name(args) shop = await run_command(ctx, self.base_url, self.api_token, "POST", "add_shop", errors=errors, x_pos=x_pos, z_pos=z_pos, name=name, discord_uuid=ctx.message.author.id) await ctx.send('{}, your shop has been added to the database: \n{}'.format(ctx.message.author.mention, formatted_location(shop))) @commands.command(pass_context=True) async def add_town(self, ctx, x_pos: int, z_pos: int, *args): """ {}add_town The Town Name parameter is optional if this is your first town """ errors = { "LocationLookUpError": "you have more than one location. Please specify a name." } name = get_name(args) town = await run_command(ctx, self.base_url, self.api_token, "POST", "add_town", errors=errors, x_pos=x_pos, z_pos=z_pos, name=name, discord_uuid=ctx.message.author.id) await ctx.send( '{}, your town has been added to the database: \n{}'.format(ctx.message.author.mention, formatted_location(town))) @commands.command(pass_context=True) async def add_tunnel(self, ctx, tunnel_direction, tunnel_number: int, *args): """ {}add_tunnel The Name parameter is optional if you only have one location """ name = get_name(args) errors = { "InvalidTunnelError": "{} is not a valid tunnel direction ya gub".format(tunnel_direction), "LocationLookUpError": "you do not have a location by the name **{}** you ding dong goober.".format(name) } tunnel = await run_command(ctx, self.base_url, self.api_token, "POST", "add_tunnel", errors=errors, tunnel_direction=tunnel_direction, tunnel_number=tunnel_number, location_name=name, discord_uuid=ctx.message.author.id) await ctx.send("{}, your tunnel has been added to the database!".format(ctx.message.author.mention)) @commands.command(pass_context=True) async def delete(self, ctx, *args): """ {}delete """ name = get_name(args) errors = { "LocationLookUpError": "you do not have a location by the name **{}** you ding dong goober.".format(name) } location = await run_command(ctx, self.base_url, self.api_token, "POST", "delete", errors=errors, name=name, discord_uuid=ctx.message.author.id) await ctx.send("{}, **{}** has been deleted from Geoffrey, good riddance.".format(ctx.message.author.mention , location)) @commands.command(pass_context=True) async def delete_item(self, ctx, item_name: str, *args): """ {}delete_item The Shop Name parameter is optional if you only have one location. """ shop_name = get_name(args) errors = { "LocationLookUpError": "you do not have a shop by that name you ding dong goober.", "EntryNameNotUniqueError": "you have more than one location. Please specify a name, dingus.", "ItemNotFound": "your shop does not sell **{}**. Try again buddy boy.".format(item_name) } shop = await run_command(ctx, self.base_url, self.api_token, "POST", "delete_item", errors=errors, item=item_name, shop_name=shop_name, discord_uuid=ctx.message.author.id) await ctx.send("{}, **{}** has been deleted from {}, no one bought it anyway.".format( ctx.message.author.mention, item_name, shop["name"])) @commands.command(pass_context=True) async def delete_resource(self, ctx, resource_name: str, *args): """ {}delete_resource The Farm Name parameter is optional if you only have one location. """ farm_name = get_name(args) errors = { "LocationLookUpError": "you do not have a farm by that name you ding dong goober.", "EntryNameNotUniqueError": "you have more than one location. Please specify a name, dingus.", "ItemNotFound": "your farm does not produce **{}**. Try again buddy boy.".format(resource_name) } farm = await run_command(ctx, self.base_url, self.api_token, "POST", "delete_resource", errors=errors, resource=resource_name, farm_name=farm_name, discord_uuid=ctx.message.author.id) await ctx.send("{}, **{}** has been deleted from {}, Hythe's farm is better anyway.".format( ctx.message.author.mention, resource_name, farm["name"])) @commands.command(pass_conext=True) async def edit_name(self, ctx, new_name: str, old_name: str): """ {}edit_name If the name has spaces in it, it must be wrapped in quotes. eg "Cool Shop 123" """ errors = { "EntryNameNotUniqueError": "a location is already called **{}** you ding dong goober".format(old_name), "LocationLookUpError": "you do not have a location by the name **{}** you ding dong goober.".format( old_name) } location = await run_command(ctx, self.base_url, self.api_token, "POST", "edit_name", errors=errors, loc_name=old_name, new_name=new_name, discord_uuid=ctx.message.author.id) await ctx.send("{}, **{}** has been renamed to **{}**.".format(ctx.message.author.mention, old_name, location["name"])) @commands.command(pass_conext=True) async def edit_pos(self, ctx, new_x: int, new_z: int, *args): """ {}edit_pos """ loc_name = get_name(args) errors = { "LocationLookUpError", "you do not have a location by the name **{}** you ding dong goober.".format(loc_name) } location = await run_command(ctx, self.base_url, self.api_token, "POST", "edit_pos", errors=errors, x=new_x, z=new_z, loc_name=loc_name, discord_uuid=ctx.message.author.id) await ctx.send("{}, **{}** has been moved to **{}**".format(ctx.message.author.mention, location["name"], location["location"])) @commands.command(pass_conext=True) async def edit_tunnel(self, ctx, new_tunnel_direction: str, new_tunnel_number: int, *args): """ {}edit_tunnel """ loc_name = get_name(args) errors = { "LocationLookUpError": "you do not have a location by the name **{}** you ding dong goober.".format( loc_name), "InvalidTunnelError": "{} is not a valid tunnel direction ya gub".format(new_tunnel_direction) } location = await run_command(ctx, self.base_url, self.api_token, "POST", "edit_tunnel", errors=errors, tunnel_direction=new_tunnel_direction, tunnel_number=new_tunnel_number, loc_name=loc_name, discord_uuid=ctx.message.author.id) await ctx.send("{}, **{}**'s tunnel been moved to **{}**".format(ctx.message.author.mention, location["name"], location["tunnel"])) @commands.command(pass_context=True) async def find_around(self, ctx, x_pos, z_pos, *args): """ {}find_around The Radius parameter is optional and defaults to 200 blocks """ errors = { "LocationLookUpError": "there are no locations in that area." } if len(args) > 0: radius = int(args[0]) else: radius = 200 locations = await run_command(ctx, self.base_url, self.api_token, "GET", "find_around", errors=errors, x_pos=x_pos, z_pos=z_pos, radius=radius) message = ["{}, the following locations are within **{}** blocks of (x={}, z={}):".format( ctx.message.author.mention, radius, x_pos, z_pos)] for location in locations: message.append(formatted_location(location)) await self.bot.send_list(ctx, message) @commands.command(pass_context=True) async def find_farm(self, ctx, *args): """ {}find_farm """ search = get_name(args) errors = { "ResourceNotFoundError": "there are no farms that match **{}**.".format(search) } locations = await run_command(ctx, self.base_url, self.api_token, "GET", "find_farm", errors=errors, resource_name=search) message = ["{}, the following farms produce **{}**:".format(ctx.message.author.mention, search)] for location in locations: message.append(formatted_location(location)) await self.bot.send_list(ctx, message) @commands.command(pass_context=True, aliases=["find"]) async def find_location(self, ctx, *args): """ {}find_location """ search = get_name(args) errors = { "LocationLookUpError": "there are no locations that match **{}**.".format(search) } locations = await run_command(ctx, self.base_url, self.api_token, "GET", "find_location", errors=errors, search=search) message = ["{}, the following locations match **{}**:".format(ctx.message.author.mention, search)] for location in locations: message.append(formatted_location(location)) await self.bot.send_list(ctx, message) @commands.command(pass_context=True) async def help(self, ctx, *args): if ctx.message.guild is not None: await ctx.send("{}, I sent you some help in the DMs.".format(ctx.message.author.mention)) if len(args) > 0: command = args[0].lower() try: await self.bot.send_list(ctx.message.author, self.bot.help_dict[command]) except KeyError: await ctx.message.author.send("{}, no command named **{}** exists. Try {}help".format( ctx.message.author.mention, command, self.bot.prefix)) else: await self.bot.send_list(ctx.message.author, self.bot.help_page) @commands.command(pass_context=True) async def info(self, ctx, *args): """ {}info """ location_name = get_name(args) errors = { "LocationLookUpError": "there are no locations that match **{}**.".format(location_name) } location = await run_command(ctx, self.base_url, self.api_token, "GET", "info", location_name=location_name, errors=errors) message = "{}, info on {}:\n".format(ctx.message.author.mention, location["name"]) if location["type"] == "Shop": info_list = formatted_shop(location, self.base_url) elif location["type"] == "Town": info_list = formatted_town(location, self.base_url) elif location["type"] == "PublicFarm": info_list = formatted_farm(location, self.base_url) elif location["type"] == "Market": info_list = formatted_market(location, self.base_url) else: info_list = formatted_location_info(location, self.base_url) await ctx.send(message) await self.bot.send_list(ctx, info_list) @commands.command(pass_context=True) async def me(self, ctx): """ {}me """ locations = await run_command(ctx, self.base_url, self.api_token, "GET", "me", discord_uuid=ctx.message.author.id) message = ["{}, you have the following locations:".format(ctx.message.author.mention)] for location in locations: message.append(formatted_location(location)) await self.bot.send_list(ctx, message) @commands.command(pass_context=True) async def register(self, ctx): """ {}register """ errors = { "PlayerInDBError": "you are already registered with Geoffrey you ding dong." } await run_command(ctx, self.base_url, self.api_token, "POST", "register", errors=errors, player_name=ctx.message.author.display_name, discord_uuid=ctx.message.author.id) await ctx.send("{}, you have been added to the database. Do {}help to see what this bot can do.".format( ctx.message.author.mention, self.bot.prefix)) @commands.command(pass_context=True) async def remove_resident(self, ctx, resident_name, *args): """ {}remove_resident The Town Name is optional if you only have one town. """ town_name = get_name(args) errors = { "ResidentNotFoundError": "ain't no one in your town named {} you goob".format(resident_name), "LocationLookUpError": "you do not have a town called **{}** you ding dong goober.".format(town_name) } location = await run_command(ctx, self.base_url, self.api_token, "POST", "remove_resident", errors=errors, resident_name=resident_name, town_name=town_name, discord_uuid=ctx.message.author.id) await ctx.send('{}, **{}** has been remove as a resident of **{}**'.format( ctx.message.author.mention, resident_name, location["name"])) @commands.command(pass_context=True) async def selling(self, ctx, *args): """ {}selling Sorts by most recently added """ item = get_name(args) errors = { "ItemNotFound": "no shop was found selling {}".format(item) } results = await run_command(ctx, self.base_url, self.api_token, "GET", "selling", errors=errors, item_name=item) message = ["{} The following shop(s) sell **{}**:".format(ctx.message.author.mention, item)] for shop in results: for line in formatted_shop(shop, base_url=self.base_url): message.append(line) message.append('') await self.bot.send_list(ctx, message) @commands.command(pass_context=True) async def selling_price(self, ctx, *args): """ {}selling_price Sorts by best price """ item = get_name(args) errors = { "ItemNotFound": "no shop was found selling {}".format(item) } results = await run_command(ctx, self.base_url, self.api_token, "GET", "selling_price", errors=errors, item_name=item) message = ["{} The following shop(s) sell **{}**:".format(ctx.message.author.mention, item)] for shop in results: for line in formatted_shop(shop, base_url=self.base_url): message.append(line) message.append('') await self.bot.send_list(ctx, message) @commands.command(pass_context=True) async def restock(self, ctx, item_name, *args): """ {}restock The Shop Name is optional if you only have one shop. """ shop_name = get_name(args) errors = { "ItemNotFound": "that shop does not have **{}** in its inventory".format(item_name), "LocationLookUpError": "you do not have a shop named **{}**.".format(shop_name), "EntryNameNotUniqueError": "you have more than one location. Please specify a name, dingus." } item = await run_command(ctx, self.base_url, self.api_token, "POST", "restock", errors=errors, item_name=item_name, shop_name=shop_name, discord_uuid=ctx.message.author.id) await ctx.send('{}, **{}** has been restocked at **{}**'.format(ctx.message.author.mention, item_name, item[0]["shop"]["name"])) @commands.command(pass_context=True) async def tunnel(self, ctx, *args): """ {}tunnel """ player_name = get_name(args) errors = { "LocationLookUpError": "**{}** has no tunnels in the database.".format(player_name) } tunnels = await run_command(ctx, self.base_url, self.api_token, "GET", "tunnel", errors=errors, player_name=player_name) message = ["{}, **{}** has the following tunnels:".format(ctx.message.author.mention, player_name)] for tunnel in tunnels: message.append(formatted_tunnel(tunnel)) await self.bot.send_list(ctx, message) def setup(bot): bot.add_cog(GeoffreyCommands(bot))