From 690d076d16bf2d9cb9e22aa28442a4d45ceeb3c5 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Mon, 14 Jan 2019 14:22:18 -0600 Subject: [PATCH] Model and CommandAPI changes needed to implement the discord bot fully --- api/commands.py | 69 ++++++++++++++++++++++++++++++++----------------- api/views.py | 3 +++ models.py | 21 ++++++++++++--- 3 files changed, 67 insertions(+), 26 deletions(-) diff --git a/api/commands.py b/api/commands.py index 1a88c17..9fbdf3a 100644 --- a/api/commands.py +++ b/api/commands.py @@ -18,6 +18,14 @@ def objects_list_to_json(obj_list): return json_list +def match_tunnel(tunnel_direction): + for direction in Tunnel.TUNNEL_NAMES: + if re.search("{}.*".format(tunnel_direction), direction[1], re.IGNORECASE): + return direction[0] + + raise InvalidTunnelError + + def get_required_args(func): args = inspect.getfullargspec(func) @@ -150,7 +158,7 @@ def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid :param discord_uuid: Discord UUID :param mc_uuid: Minecraft UUID :return: JSON Representation of the Tunnel - :raises: PlayerNotFound, LocationHasTunnelError, EntryNameNotUniqueError, NoLocationsInDatabase + :raises: PlayerNotFound, LocationHasTunnelError, EntryNameNotUniqueError, NoLocationsInDatabase, InvalidTunnelError :help: Adds your tunnel to the database. If you only have one location, you do not need to specify a location name ''' player = get_player(discord_uuid, mc_uuid) @@ -160,10 +168,7 @@ def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid else: loc = get_location(player, name=location_name) - for direction in Tunnel.TUNNEL_NAMES: - if re.search("{}.*".format(tunnel_direction), direction[1], re.IGNORECASE): - tunnel_direction = direction[0] - break + tunnel_direction = match_tunnel(tunnel_direction) if Tunnel.objects.filter(location=loc).first(): raise LocationHasTunnelError @@ -193,10 +198,10 @@ def find_location(search, limit=25): return objects_list_to_json(locations) -@command("DELETE") +@command("POST") def delete(name, discord_uuid=None, mc_uuid=None): ''' - :request: DELETE + :request: POST :param name: Name of location to delete :param discord_uuid: Discord UUID :param mc_uuid: Minecraft UUID @@ -225,6 +230,10 @@ def find_around(x_pos, z_pos, radius=200): :help: Finds all the locations around a certain point ''' + x_pos = int(x_pos) + z_pos = int(z_pos) + radius = int(radius) + locations = Location.objects.filter(x_coord__range=(x_pos - radius, x_pos + radius), z_coord__range=(z_pos - radius, z_pos + radius)).all() @@ -311,10 +320,10 @@ def info(location_name): :help: Finds all the locations matching the search term ''' - location = Location.objects.get(name__iexact=location_name) + location = Location.objects.filter(name__iexact=location_name).first() if location is None: - location = Location.objects.get(name__iregex="*{}*".format(location_name)) + location = Location.objects.filter(name__iregex=".*{}.*".format(location_name)).first() if location is not None: return location.json @@ -382,11 +391,14 @@ def edit_tunnel(tunnel_direction, tunnel_number, loc_name, discord_uuid=None, mc player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid) location = get_location(player, loc_name) + tunnel_direction = match_tunnel(tunnel_direction) - if location.tunnel is not None: - location.tunnel.tunnel_direction = tunnel_direction - location.tunnel.tunnel_number = tunnel_number - else: + try: + tunnel = Tunnel.objects.get(location=location) + tunnel.tunnel_direction = tunnel_direction + tunnel.tunnel_number = tunnel_number + tunnel.save() + except Tunnel.DoesNotExist: Tunnel.objects.create(tunnel_direction=tunnel_direction, tunnel_number=tunnel_number, location=location) return location.json @@ -406,24 +418,27 @@ def edit_name(new_name, loc_name, discord_uuid=None, mc_uuid=None): ''' player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid) + + if Location.objects.filter(name__iexact=new_name).count(): + raise EntryNameNotUniqueError + location = get_location(player, loc_name) location.name = new_name location.save() - return location.json -@command("DELETE") +@command("POST") def delete_item(item, shop_name=None, discord_uuid=None, mc_uuid=None): ''' - :request: DELETE + :request: POST :param item: Item name to delete :param shop_name: Shop selling item, can be None if the user only has one shop :param discord_uuid: Discord UUID :param mc_uuid: Minecraft UUID - :return: Deletes an item from the database - :raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase + :return: Shop where the item was deleted from + :raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase, ItemNotFound :help: Deletes an item from a shop ''' @@ -431,7 +446,12 @@ def delete_item(item, shop_name=None, discord_uuid=None, mc_uuid=None): shop = get_location(player, shop_name, Shop) - ItemListing.objects.filter(item_name__iexact=item, shop=shop).delete() + delete_list = ItemListing.objects.filter(item_name__iexact=item, shop=shop).all() + + if len(delete_list) == 0: + raise ItemNotFound + + delete_list.delete() return shop.json @@ -469,7 +489,7 @@ def restock(item_name, shop_name=None, discord_uuid=None, mc_uuid=None): :param discord_uuid: Discord UUID :param mc_uuid: Minecraft UUID :return: List of items updated - :raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase + :raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase, ItemNotFound :help: Restocks items matching the item name in your shop ''' owner = get_player(discord_uuid, mc_uuid) @@ -477,8 +497,11 @@ def restock(item_name, shop_name=None, discord_uuid=None, mc_uuid=None): items = ItemListing.objects.filter(item_name__iexact=item_name, shop=shop).all() - for item in items: - item.date_restocked = datetime.datetime.now() - item.save() + if len(items) == 0: + raise ItemNotFound + else: + for item in items: + item.date_restocked = datetime.datetime.now() + item.save() return objects_list_to_json(items) diff --git a/api/views.py b/api/views.py index 82a5b55..df38596 100644 --- a/api/views.py +++ b/api/views.py @@ -1,6 +1,8 @@ from django.views.generic import View from django.http import JsonResponse from django.conf import settings +import traceback +import sys import GeoffreyApp.api.commands as commands from GeoffreyApp.errors import * @@ -28,6 +30,7 @@ def run_command(request, command, req_type): raise CommandNotFound except Exception as e: response = {"error": e.__class__.__name__, "error_message": str(e)} + traceback.print_exception(type(e), e, e.__traceback__, file=sys.stderr) return JsonResponse(response, safe=False) diff --git a/models.py b/models.py index 8596c8b..dd5c97a 100644 --- a/models.py +++ b/models.py @@ -94,6 +94,15 @@ class Location(models.Model): def location(self): return "(x={}, z={})".format(self.x_coord, self.z_coord) + @property + def tunnel(self): + try: + tunnel = Tunnel.objects.get(location=self) + except Tunnel.DoesNotExist: + tunnel = None + + return tunnel + @property def json(self): return {"type": self.__class__.__name__, @@ -101,7 +110,9 @@ class Location(models.Model): "x_coord": self.x_coord, "z_coord": self.z_coord, "dimension": self.dimension, - "owner": self.owner.json + "owner": self.owner.json, + "location": self.location, + "tunnel": None if self.tunnel is None else self.tunnel.tunnel_str } @property @@ -212,11 +223,15 @@ class Tunnel(models.Model): ''' def __str__(self): - return "Tunnel: %s %d" % (self.tunnel_direction, self.tunnel_number) + return "Tunnel: %s %d" % (self.get_tunnel_direction_display(), self.tunnel_number) @property def json(self): return {"location_name": self.location.name, - "tunnel_direction": self.tunnel_direction, + "tunnel_direction": self.get_tunnel_direction_display(), "tunnel_number": self.tunnel_number } + + @property + def tunnel_str(self): + return "{} {}".format(self.get_tunnel_direction_display(), self.tunnel_number)