diff --git a/api/BotErrors.py b/api/BotErrors.py new file mode 100644 index 0000000..2f6b53d --- /dev/null +++ b/api/BotErrors.py @@ -0,0 +1,87 @@ +class DataBaseError(Exception): + """Base class for exceptions in this module.""" + pass + + +class LocationInitError(DataBaseError): + """Error in initializing Location""" + + +class TunnelInitError(DataBaseError): + """Error in initializing Tunnel""" + + +class NoMatchFoundError(DataBaseError): + """No matches were found in the database""" + + +class LocationLookUpError(DataBaseError): + """Error in finding location in database""" + + +class DeleteEntryError(DataBaseError): + """Error in deleting entry""" + + +class UsernameLookupFailed(Exception): + """Error in username lookup, is the player's nickname set correctly? *stares at aeskdar*""" + + +class PlayerNotFound(DataBaseError): + """Player not found in database.""" + + +class EntryNameNotUniqueError(DataBaseError): + """A location by that name is already in the database.""" + + +class StringTooLong(DataBaseError): + """Given string is too long.""" + + +class DatabaseValueError(DataBaseError): + """'String too long or number too large""" + + +class ItemNotFound(DataBaseError): + """No item matches found in database""" + + +class InvalidDimError(DataBaseError): + """Invalid dimension name""" + + +class InvalidTunnelError(DataBaseError): + """Invalid tunnel name""" + + +class PlayerInDBError(DataBaseError): + """Player already registered in database""" + + +class LocationHasTunnelError(DataBaseError): + """That location already has a tunnel""" + + +class NoPermissionError(DataBaseError): + """You have no permission to run this command""" + + +class NotOnServerError(DataBaseError): + """You need to run this command on 24CC""" + + +class NoLocationsInDatabase(DataBaseError): + """This player has no locations in the database""" + + +class FuckyWucky: + """You made one.""" + + +class EmptryString(DataBaseError): + """Empty string provided""" + + +class CommandNotFound(DataBaseError): + """Command not found""" diff --git a/api/MinecraftAccountInfoGrabber.py b/api/MinecraftAccountInfoGrabber.py new file mode 100644 index 0000000..1d39070 --- /dev/null +++ b/api/MinecraftAccountInfoGrabber.py @@ -0,0 +1,36 @@ +from simplejson.errors import JSONDecodeError + +import requests + +from GeoffreyApp.api.BotErrors import UsernameLookupFailed + +uuid_lookup_url = 'https://api.mojang.com/users/profiles/minecraft/{}' +username_lookup_url = 'https://api.mojang.com/user/profiles/{}/names' + + +def grab_json(url): + try: + json = requests.get(url).json() + if 'error' in json: + raise UsernameLookupFailed + + except JSONDecodeError: + raise UsernameLookupFailed + + return json + + +def grab_UUID(username): + player_data = grab_json(uuid_lookup_url.format(username)) + return player_data['id'] + + +def grab_playername(uuid): + player_data = grab_json(username_lookup_url.format(uuid)) + + if len(player_data) == 0: + raise UsernameLookupFailed + else: + last_index = len(player_data) - 1 + + return player_data[last_index]['name'] diff --git a/api/commands.py b/api/commands.py index b55dd66..9ff7e8d 100644 --- a/api/commands.py +++ b/api/commands.py @@ -68,6 +68,15 @@ def register(player_name, discord_uuid): @post +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) + + +@post +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) + + def add_location(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None, loc_type=Location): player = get_player(discord_uuid, mc_uuid) try: @@ -139,14 +148,19 @@ def add_item(item_name, quantity, diamond_price, shop_name=None, discord_uuid=No # TODO Re-implement selling shop search @get def selling(item_name): + items = [] if len(item_name) == 0: raise EmptryString + query = ItemListing.objects.filter(item_name__icontains=item_name).values() + #items = ItemListing.objects.annotate(normalized_price=F('price') / F('amount'))\ + # .filter(item_name__icontains=item_name).order_by('normalized_price') - items = ItemListing.objects.annotate(normalized_price=F('price') / F('amount')).filter(item_name__icontains=item_name).order_by('normalized_price') - - if len(items) == 0: + if len(query) == 0: raise ItemNotFound + for item in query: + items.append(item) + return items diff --git a/api/views.py b/api/views.py index bc732fb..9cd85b2 100644 --- a/api/views.py +++ b/api/views.py @@ -1,24 +1,45 @@ from django.views.generic import View from django.http import JsonResponse from django.conf import settings +import inspect import GeoffreyApp.api.commands as commands from GeoffreyApp.api.BotErrors import * +def getRequiredArgs(func): + args = inspect.getfullargspec(func) + ''' + if defaults: + args = args[:-len(kwonlyargs)] + ''' + return args.args + args.kwonlyargs + + +GET = [] +POST = [] +DELETE = [] + +for command in commands.get_list: + GET.append({"name": command.__name__, "params": getRequiredArgs(command)}) +for command in commands.post_list: + POST.append({"name": command.__name__, "params": getRequiredArgs(command)}) +for command in commands.delete_list: + DELETE.append({"name": command.__name__, "params": getRequiredArgs(command)}) +command_response = {"GET": GET, "POST": POST, "DELETE": DELETE} + + def run_command(request, command, command_list): command = command.lower() - response = [] try: for c in command_list: if command == c.__name__: - ret = c(**request.dict()) - response.append(ret) + response = c(**request.dict()) return JsonResponse(response, safe=False) raise CommandNotFound except Exception as e: - response.append({"error": e.__class__.__name__}) + response = {"error": e.__class__.__name__} return JsonResponse(response, safe=False) @@ -26,7 +47,10 @@ def run_command(request, command, command_list): class CommandAPI(View): def get(self, request, command): get = request.GET - return run_command(get, command, commands.get_list) + if command.lower() != "commands": + return run_command(get, command, commands.get_list) + else: + return JsonResponse(command_response) def post(self, request, command): post = request.POST @@ -38,7 +62,7 @@ class CommandAPI(View): class SettingsAPI(View): - def get(self, reuqest): + def get(self, request): response = { "BOT_PREFIX": getattr(settings, 'BOT_PREFIX', '?'), "ERROR_USERS": getattr(settings, 'ERROR_USERS', []), diff --git a/apps.py b/apps.py index b613bf9..a7c3efe 100644 --- a/apps.py +++ b/apps.py @@ -12,7 +12,6 @@ class GeoffreyAppConfig(AppConfig): def ready(self): subprocess.run('screen -X -S "{0}" quit'.format("geoffrey"), shell=True) - print('screen -S geoffrey -d -m {} {}'.format(sys.executable, path)) - subprocess.run( - 'screen -S geoffrey -d -m {} {}'.format(sys.executable, path), - shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + #subprocess.run( + # 'screen -S geoffrey -d -m {} {}'.format(sys.executable, path), + # shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)