From bec4e6c1c5183b6bf4c10095d8db8fdd0e7b012e Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Fri, 16 Aug 2019 12:00:26 -0500 Subject: [PATCH] Added class for commands + Easier to expand upon than the dict + Foundation for adding the permission level system --- GeoffreyApp/api/commands.py | 143 ++++++++++++++++++++++-------------- GeoffreyApp/api/views.py | 32 ++++---- 2 files changed, 101 insertions(+), 74 deletions(-) diff --git a/GeoffreyApp/api/commands.py b/GeoffreyApp/api/commands.py index f630d25..ad3155b 100644 --- a/GeoffreyApp/api/commands.py +++ b/GeoffreyApp/api/commands.py @@ -5,10 +5,67 @@ from GeoffreyApp.minecraft_api import * import inspect import datetime import re +import enum from GeoffreyApp.util import objects_list_to_json -command_dict = {"GET": {}, "POST": {}, "DELETE": {}} + +class RequestTypes(enum.Enum): + POST = "POST" + GET = "GET" + + +class PermissionLevel(enum.Enum): + ADMIN = enum.auto() + MOD = enum.auto() + PLAYER = enum.auto() + + +command_dict = {RequestTypes.GET: {}, RequestTypes.POST: {}} + + +class Command: + def __init__(self, func, permission_level, command_name=None): + self.func = func + self.params = self.get_required_args(func) + self.help = self.parse_help(func) + self.permission_level = permission_level + + if command_name is None: + self.name = func.__name__ + else: + self.name = command_name + + @staticmethod + def parse_help(func): + try: + match = re.search(".*:help:.*", func.__doc__) + + return match.group(0).partition(":help: ")[-1] + except: + return ' ' + + @staticmethod + def get_required_args(func): + args = inspect.getfullargspec(func) + + return args.args + args.kwonlyargs + + @property + def json(self): + return {"command": self.name, "help": self.help, "permission_level": self.permission_level.name} + + +def command(type, permission_level=PermissionLevel.PLAYER): + def command_dec(func): + def add_command(): + command = Command(func, permission_level) + command_dict[type][command.name] = command + return func + + return add_command() + + return command_dec def match_tunnel(tunnel_direction): @@ -19,34 +76,6 @@ def match_tunnel(tunnel_direction): raise InvalidTunnelError -def get_required_args(func): - args = inspect.getfullargspec(func) - - return args.args + args.kwonlyargs - - -def command(type): - def command_dec(func): - def add_command(): - command_dict[type][func.__name__] = {"func": func, - "params": get_required_args(func), - "help": parse_help(func)} - return func - - return add_command() - - return command_dec - - -def parse_help(func): - try: - match = re.search(".*:help:.*", func.__doc__) - - return match.group(0).partition(":help: ")[-1] - except: - return ' ' - - def get_player(discord_uuid=None, mc_uuid=None): try: discord_uuid = str(discord_uuid) @@ -106,7 +135,7 @@ def add_location(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None, loc_t return location.json -@command("POST") +@command(RequestTypes.POST) def register(player_name, discord_uuid): """ :request: POST @@ -128,7 +157,7 @@ def register(player_name, discord_uuid): return player.json -@command("POST") +@command(RequestTypes.POST) def add_base(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -145,7 +174,7 @@ def add_base(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): return add_location(x_pos, z_pos, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Base) -@command("POST") +@command(RequestTypes.POST) def add_shop(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -162,7 +191,7 @@ def add_shop(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): return add_location(x_pos, z_pos, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Shop) -@command("POST") +@command(RequestTypes.POST) def add_town(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -179,7 +208,7 @@ def add_town(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): return add_location(x_pos, z_pos, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Town) -@command("POST") +@command(RequestTypes.POST) def add_farm(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -196,7 +225,7 @@ def add_farm(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): return add_location(x_pos, z_pos, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=PublicFarm) -@command("POST") +@command(RequestTypes.POST) def add_market(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -213,7 +242,7 @@ def add_market(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): return add_location(x_pos, z_pos, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Market) -@command("POST") +@command(RequestTypes.POST) def add_attraction(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -230,7 +259,7 @@ def add_attraction(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None): return add_location(x_pos, z_pos, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Attraction) -@command("POST") +@command(RequestTypes.POST) def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -261,7 +290,7 @@ def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid return tunnel.json -@command("GET") +@command(RequestTypes.GET) def find_location(search, limit=25): """ :request: GET @@ -280,7 +309,7 @@ def find_location(search, limit=25): return objects_list_to_json(locations) -@command("POST") +@command(RequestTypes.POST) def delete(name, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -302,7 +331,7 @@ def delete(name, discord_uuid=None, mc_uuid=None): return name -@command("GET") +@command(RequestTypes.GET) def find_around(x_pos, z_pos, radius=200): """ :request: GET @@ -327,7 +356,7 @@ def find_around(x_pos, z_pos, radius=200): return objects_list_to_json(locations) -@command("POST") +@command(RequestTypes.POST) def add_item(item_name, quantity, diamond_price, shop_name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -352,7 +381,7 @@ def add_item(item_name, quantity, diamond_price, shop_name=None, discord_uuid=No return item_listing.json -@command("POST") +@command(RequestTypes.POST) def add_resource(resource_name, farm_name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -374,7 +403,7 @@ def add_resource(resource_name, farm_name=None, discord_uuid=None, mc_uuid=None) return resource.json -@command("GET") +@command(RequestTypes.GET) def find_farm(resource_name): """ :request: GET @@ -394,7 +423,7 @@ def find_farm(resource_name): return objects_list_to_json(farms) -@command("GET") +@command(RequestTypes.GET) def selling(item_name): """ :request: GET @@ -407,7 +436,7 @@ def selling(item_name): return get_selling(item_name, sort="-date_restocked") -@command("GET") +@command(RequestTypes.GET) def selling_price(item_name): """ :request: GET @@ -454,7 +483,7 @@ def get_selling(item_name, sort): return items -@command("GET") +@command(RequestTypes.GET) def info(location_name): """ :request: GET @@ -487,7 +516,7 @@ def info(location_name): raise LocationLookUpError -@command("GET") +@command(RequestTypes.GET) def tunnel(player_name): """ :request: GET @@ -506,7 +535,7 @@ def tunnel(player_name): return objects_list_to_json(tunnels) -@command("POST") +@command(RequestTypes.POST) def edit_pos(x, z, loc_name, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -531,7 +560,7 @@ def edit_pos(x, z, loc_name, discord_uuid=None, mc_uuid=None): return location.json -@command("POST") +@command(RequestTypes.POST) def edit_tunnel(tunnel_direction, tunnel_number, loc_name, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -560,7 +589,7 @@ def edit_tunnel(tunnel_direction, tunnel_number, loc_name, discord_uuid=None, mc return location.json -@command("POST") +@command(RequestTypes.POST) def edit_name(new_name, loc_name, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -585,7 +614,7 @@ def edit_name(new_name, loc_name, discord_uuid=None, mc_uuid=None): return location.json -@command("POST") +@command(RequestTypes.POST) def delete_item(item, shop_name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -612,7 +641,7 @@ def delete_item(item, shop_name=None, discord_uuid=None, mc_uuid=None): return shop.json -@command("POST") +@command(RequestTypes.POST) def delete_resource(resource_name, farm_name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -639,7 +668,7 @@ def delete_resource(resource_name, farm_name=None, discord_uuid=None, mc_uuid=No return farm.json -@command("GET") +@command(RequestTypes.GET) def me(discord_uuid=None, mc_uuid=None): """ :request: GET @@ -663,7 +692,7 @@ def me(discord_uuid=None, mc_uuid=None): return objects_list_to_json(locations) -@command("POST") +@command(RequestTypes.POST) def restock(item_name, shop_name=None, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -690,7 +719,7 @@ def restock(item_name, shop_name=None, discord_uuid=None, mc_uuid=None): return objects_list_to_json(items) -@command("POST") +@command(RequestTypes.POST) def add_owner(new_owner_name, location_name, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -721,7 +750,7 @@ def add_owner(new_owner_name, location_name, discord_uuid=None, mc_uuid=None): return location.json -@command("POST") +@command(RequestTypes.POST) def add_resident(new_resident_name, town_name, discord_uuid=None, mc_uuid=None): """ :request: POST @@ -753,7 +782,7 @@ def add_resident(new_resident_name, town_name, discord_uuid=None, mc_uuid=None): return town.json -@command("POST") +@command(RequestTypes.POST) def remove_resident(resident_name, town_name, discord_uuid=None, mc_uuid=None): """ :request: POST diff --git a/GeoffreyApp/api/views.py b/GeoffreyApp/api/views.py index f185c06..cbdbd88 100644 --- a/GeoffreyApp/api/views.py +++ b/GeoffreyApp/api/views.py @@ -4,6 +4,7 @@ from django.conf import settings import traceback import sys +from GeoffreyApp.api.commands import RequestTypes import GeoffreyApp.api.commands as commands from GeoffreyApp.errors import * from GeoffreyApp.models import APIToken @@ -19,13 +20,15 @@ def check_token(request, **kwargs): return False -def run_command(request, command, req_type): - command = command.lower() +def run_command(request, command_name, req_type): + params = request.dict() + params.pop("api") + + command_name = command_name.lower() try: - if command in commands.command_dict[req_type]: - params = request.dict() - params.pop("api") - response = commands.command_dict[req_type][command]["func"](**params) + if command_name in commands.command_dict[req_type]: + command = commands.command_dict[req_type][command_name] + response = command.func(**params) else: raise CommandNotFound except Exception as e: @@ -40,8 +43,10 @@ def get_commands(): command_list = [] for request in commands.command_dict: - for c in commands.command_dict[request]: - command_list.append({"command": c, "help": commands.command_dict[request][c]["help"]}) + for command_name in commands.command_dict[request]: + command = commands.command_dict[request][command_name] + json = command.json + command_list.append(json) return command_list @@ -53,21 +58,14 @@ class CommandAPI(View): if command.lower() == "commands": return JsonResponse(get_commands(), safe=False) else: - return run_command(get, command, "GET") + return run_command(get, command, RequestTypes.GET) else: return JsonResponse({}) def post(self, request, command): post = request.POST if check_token(post, commands_perm=True): - return run_command(post, command, "POST") - else: - return JsonResponse({}) - - def delete(self, request, command): - delete = request.DELETE - if check_token(delete, commands_perm=True): - return run_command(delete, command, "DELETE") + return run_command(post, command, RequestTypes.POST) else: return JsonResponse({})