Geoffrey-Django/api/commands.py

251 lines
6.7 KiB
Python

from django.db.models import Q, F
from GeoffreyApp.models import *
from GeoffreyApp.errors import *
from GeoffreyApp.minecraft_api import *
post_list = []
get_list = []
delete_list = []
def post(func):
def command():
post_list.append(func)
return command()
def delete(func):
def command():
delete_list.append(func)
return command()
def get(func):
def command():
get_list.append(func)
return command()
def get_player(discord_uuid=None, mc_uuid=None):
if discord_uuid is not None:
player = Player.objects.get(discord_uuid=discord_uuid)
elif mc_uuid is not None:
player = Player.objects.get(mc_uuid=discord_uuid)
else:
raise AttributeError
return player
def get_location(owner, name=None, loc_type=Location):
if name is None:
loc_list = Location.objects.all().select_related(loc_type.__name__).get(owner=owner)
if len(loc_list) == 1:
loc = loc_list[0]
elif len(loc_list) == 0:
raise NoLocationsInDatabase
else:
raise EntryNameNotUniqueError
else:
loc_list = Location.objects.all().select_related(loc_type.__name__).get(owner=owner, name=name)
if len(loc_list) == 1:
loc = loc_list[0]
else:
raise LocationLookUpError
return loc
@post
def register(player_name, discord_uuid):
mc_uuid = grab_UUID(player_name)
player = Player.objects.create(name=player_name, mc_uuid=mc_uuid, discord_uuid=discord_uuid)
return player.json
@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:
get_location(player, name, loc_type=loc_type)
raise EntryNameNotUniqueError
except (NoLocationsInDatabase, LocationLookUpError):
if name is None:
name = "{}'s {}".format(player.name, loc_type.__name__)
if loc_type == Base:
location = Base.objects.create(owner=player, name=name, x_coord=x_pos, z_coord=z_pos)
elif loc_type == Shop:
location = Shop.objects.create(owner=player, name=name, x_coord=x_pos, z_coord=z_pos)
else:
raise DataBaseError
return location
@post
def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid=None, mc_uuid=None):
player = get_player(discord_uuid, mc_uuid)
if location_name is None:
loc = get_location(player, name=location_name)
location_name = loc.name
tunnel = Tunnel.objects.create(tunnel_direction, tunnel_number, Location=get_location(player, location_name))
return tunnel
@get
def find_location(search):
limit = 25
locations = Location.objects.filter(Q(name__icontains=search) | Q(owner__name__icontains=search))[:limit]
if len(locations) == 0:
raise LocationLookUpError
return locations
@delete
def delete(name, discord_uuid=None, mc_uuid=None):
owner = get_player(discord_uuid, mc_uuid)
Location.objects.get(name__iexact=name, owner=owner)
@get
def find_around(x_pos, z_pos, radius=200):
locations = Location.objects.get(x_coord__range=(x_pos - radius, x_pos + radius),
z_coord__range=(z_pos - radius, z_pos + radius), dimension='O')
return locations
@post
def add_item(item_name, quantity, diamond_price, shop_name=None, discord_uuid=None, mc_uuid=None):
player = get_player(discord_uuid, mc_uuid)
shop = get_location(player, shop_name, Shop)
item_listing = ItemListing.objects.create(shop=shop, quantity=quantity, price=diamond_price, item_name=item_name)
return item_listing
# TODO Re-implement selling shop search
@get
def selling(item_name):
items = []
if len(item_name) == 0:
raise EmptryString
shops = ItemListing.objects.annotate(normalized_price=F('price') / F('amount'))\
.filter(item_name__icontains=item_name).order_by('normalized_price').values('shop_id').distinct()
if len(shops) == 0:
raise ItemNotFound
for shop_id in shops:
shop = Shop.objects.get(pk=shop_id['shop_id']).json
item_query = ItemListing.objects.annotate(normalized_price=F('price') / F('amount')).\
filter(item_name__icontains=item_name).order_by('normalized_price').all()
item_list = []
for item in item_query:
item_list.append(item)
shop["items"] = item_list
items.append(shop)
return items
@get
def info(location_name):
loc = Location.objects.get(name__iexact=location_name)
return loc
@get
def tunnel(player_name):
tunnels = Tunnel.objects.get(location__owner__name__icontains=player_name)
if len(tunnels) == 0:
raise LocationLookUpError
return tunnel
@post
def edit_pos(x, z, loc_name, discord_uuid=None, mc_uuid=None):
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
location = get_location(player, loc_name)
location.x = x
location.z = z
location.save()
return location
@post
def edit_tunnel(tunnel_direction, tunnel_number, loc_name, discord_uuid=None, mc_uuid=None):
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
location = get_location(player, loc_name)
if location.tunnel is not None:
location.tunnel.tunnel_direction = tunnel_direction
location.tunnel.tunnel_number = tunnel_number
else:
Tunnel.objects.create(tunnel_direction=tunnel_direction, tunnel_number=tunnel_number, location=location)
return location
@post
def edit_name(new_name, loc_name, discord_uuid=None, mc_uuid=None):
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
location = get_location(player, loc_name)
location.name = new_name
location.save()
return location
@post
def delete_item(item, shop_name, discord_uuid=None, mc_uuid=None):
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
shop = get_location(player, shop_name, Shop)
ItemListing.objects.filter(item_name__iexact=item, shop=shop).delete()
return shop
@get
def me(discord_uuid=None, mc_uuid=None):
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
locations = Location.objects.get(owner=player)
if len(locations) == 0:
raise PlayerNotFound
return locations