876 lines
27 KiB
Python
876 lines
27 KiB
Python
from django.db.models import Q, F
|
|
from GeoffreyApp.models import *
|
|
from GeoffreyApp.errors import *
|
|
from GeoffreyApp.minecraft_api import *
|
|
import inspect
|
|
import datetime
|
|
import re
|
|
import enum
|
|
|
|
from GeoffreyApp.util import objects_list_to_json
|
|
|
|
|
|
class RequestTypes(enum.Enum):
|
|
POST = "POST"
|
|
GET = "GET"
|
|
|
|
|
|
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, command_name=None):
|
|
def command_dec(func):
|
|
def add_command():
|
|
command_obj = Command(func, permission_level, command_name=command_name)
|
|
command_dict[type][command_obj.name] = command_obj
|
|
return func
|
|
|
|
return add_command()
|
|
|
|
return command_dec
|
|
|
|
|
|
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_player_by_name(mc_username):
|
|
try:
|
|
uuid = grab_UUID(mc_username)
|
|
return get_player(mc_uuid=uuid)
|
|
except UsernameLookupFailed:
|
|
raise PlayerNotFound
|
|
|
|
|
|
def get_player(discord_uuid=None, mc_uuid=None):
|
|
try:
|
|
discord_uuid = str(discord_uuid) if discord_uuid else None
|
|
mc_uuid = str(mc_uuid) if mc_uuid else None
|
|
|
|
if discord_uuid is not None:
|
|
player = Player.objects.get(discord_uuid__iexact=discord_uuid)
|
|
elif mc_uuid is not None:
|
|
player = Player.objects.get(mc_uuid__iexact=mc_uuid)
|
|
else:
|
|
raise AttributeError
|
|
except Player.DoesNotExist:
|
|
raise PlayerNotFound
|
|
|
|
return player
|
|
|
|
|
|
def get_location(owner, name=None, loc_type=Location):
|
|
if name is None:
|
|
loc_list = loc_type.objects.filter(owner=owner).all()
|
|
|
|
if len(loc_list) == 1:
|
|
loc = loc_list[0]
|
|
elif len(loc_list) == 0:
|
|
raise NoLocationsInDatabase
|
|
else:
|
|
raise EntryNameNotUniqueError
|
|
else:
|
|
loc_list = loc_type.objects.filter(owner=owner, name__iexact=name).all()
|
|
|
|
if len(loc_list) == 1:
|
|
loc = loc_list[0]
|
|
else:
|
|
raise LocationLookUpError
|
|
|
|
return loc
|
|
|
|
|
|
def add_location(x_pos, z_pos, dimension, name=None, discord_uuid=None, mc_uuid=None, loc_type=Location):
|
|
player = get_player(discord_uuid, mc_uuid)
|
|
|
|
name_was_none = False
|
|
if name is None:
|
|
name = "{}'s {}".format(player.name, loc_type.__name__)
|
|
name_was_none = True
|
|
|
|
if Location.objects.filter(name__iexact=name).all().count() > 0:
|
|
if name_was_none:
|
|
raise LocationLookUpError
|
|
else:
|
|
raise EntryNameNotUniqueError
|
|
else:
|
|
location = loc_type.objects.create(name=name, x_coord=x_pos, z_coord=z_pos, dimension=dimension)
|
|
location.owner.add(player)
|
|
location.save()
|
|
|
|
return location.json
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def register(player_name, discord_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param player_name: Minecraft in-game name
|
|
:param discord_uuid: Discord UUID if registering from Discord
|
|
:return: JSON representation of the new Player
|
|
:raise: PlayerInDBError
|
|
:help: Registers your Discord and Minecraft account with the the database
|
|
"""
|
|
|
|
mc_uuid = grab_UUID(player_name)
|
|
|
|
try:
|
|
player = get_player(mc_uuid=mc_uuid)
|
|
|
|
if discord_uuid is not None and player.discord_uuid is None:
|
|
player.discord_uuid = discord_uuid
|
|
player.save()
|
|
return player.json
|
|
else:
|
|
raise PlayerInDBError
|
|
except PlayerNotFound:
|
|
player = Player.objects.create(name=player_name, mc_uuid=mc_uuid, discord_uuid=discord_uuid)
|
|
player.save()
|
|
return player.json
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_base(x_pos, z_pos, dimension="O", name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param x_pos: MC X Coordinate
|
|
:param z_pos: MC Z Coordinate
|
|
:param dimension: MC Dimension
|
|
:param name: Base Name (If None, Defaults to Player's Base)
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: JSON representation of the new base
|
|
:raises: EntryNameNotUniqueError, PlayerNotFound, LocationLookupError
|
|
:help: Adds your base to the database.
|
|
"""
|
|
|
|
return add_location(x_pos, z_pos, dimension, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Base)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_shop(x_pos, z_pos, dimension="O", name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param x_pos: MC X Coordinate
|
|
:param z_pos: MC Z Coordinate
|
|
:param dimension: MC Dimension
|
|
:param name: Shop Name (If None, Defaults to Player's Shop)
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: JSON representation of the new shop
|
|
:raises: EntryNameNotUniqueError, PlayerNotFound, LocationLookupError
|
|
:help: Adds your shop to the database.
|
|
"""
|
|
|
|
return add_location(x_pos, z_pos, dimension, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Shop)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_town(x_pos, z_pos, dimension="O", name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param x_pos: MC X Coordinate
|
|
:param z_pos: MC Z Coordinate
|
|
:param dimension: MC Dimension
|
|
:param name: Town Name (If None, Defaults to Player's Town)
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: JSON representation of the new town
|
|
:raises: EntryNameNotUniqueError, PlayerNotFound, LocationLookupError
|
|
:help: Adds your town to the database.
|
|
"""
|
|
|
|
return add_location(x_pos, z_pos, dimension, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Town)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_farm(x_pos, z_pos, dimension="O", name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param x_pos: MC X Coordinate
|
|
:param z_pos: MC Z Coordinate
|
|
:param dimension: MC Dimension
|
|
:param name: Farm Name (If None, Defaults to Player's Farm)
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: JSON representation of the new farm
|
|
:raises: EntryNameNotUniqueError, PlayerNotFound, LocationLookupError
|
|
:help: Adds your public farm to the database.
|
|
"""
|
|
|
|
return add_location(x_pos, z_pos, dimension, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=PublicFarm)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_market(x_pos, z_pos, dimension="O", name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param x_pos: MC X Coordinate
|
|
:param z_pos: MC Z Coordinate
|
|
:param dimension: MC Dimension
|
|
:param name: Market Name (If None, Defaults to Player's Market)
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: JSON representation of the market
|
|
:raises: EntryNameNotUniqueError, PlayerNotFound, LocationLookupError
|
|
:help: Adds your market to the database.
|
|
"""
|
|
|
|
return add_location(x_pos, z_pos, dimension, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Market)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_attraction(x_pos, z_pos, dimension="O", name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param x_pos: MC X Coordinate
|
|
:param z_pos: MC Z Coordinate
|
|
:param dimension: MC Dimension
|
|
:param name: Market Name (If None, Defaults to Player's Attraction)
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: JSON representation of the attraction
|
|
:raises: EntryNameNotUniqueError, PlayerNotFound, LocationLookupError
|
|
:help: Adds your attraction to the database.
|
|
"""
|
|
|
|
return add_location(x_pos, z_pos, dimension, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Attraction)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param tunnel_direction: Tunnel Direction
|
|
:param tunnel_number: Tunnel Coordinate
|
|
:param location_name: Name of the Location to attach the tunnel to
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: JSON Representation of the Tunnel
|
|
:raises: PlayerNotFound, LocationHasTunnelError, EntryNameNotUniqueError, NoLocationsInDatabase, InvalidTunnelError
|
|
:help: Adds your tunnel to the database.
|
|
"""
|
|
player = get_player(discord_uuid, mc_uuid)
|
|
if location_name is None:
|
|
loc = get_location(player)
|
|
location_name = loc.name
|
|
else:
|
|
loc = get_location(player, name=location_name)
|
|
|
|
tunnel_direction = match_tunnel(tunnel_direction)
|
|
|
|
if Tunnel.objects.filter(location=loc).first():
|
|
raise LocationHasTunnelError
|
|
|
|
tunnel = Tunnel.objects.create(tunnel_direction=tunnel_direction, tunnel_number=tunnel_number,
|
|
location=get_location(player, location_name))
|
|
|
|
return tunnel.json
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def find_location(search, limit=25):
|
|
"""
|
|
:request: GET
|
|
:param search: Location name or owner to search for
|
|
:param limit: How man locations to return
|
|
:return: List of the matching locations
|
|
:raises: LocationLookupError
|
|
:help: Finds all the locations matching the search term
|
|
"""
|
|
|
|
locations = Location.objects.filter(Q(name__icontains=search) | Q(owner__name__icontains=search)).all()[:limit]
|
|
|
|
if len(locations) == 0:
|
|
raise LocationLookUpError
|
|
|
|
return objects_list_to_json(locations)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def delete(name, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param name: Name of location to delete
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: Location Name
|
|
:raises: LocationLookUpError
|
|
:help: Deletes a location from the database
|
|
"""
|
|
|
|
owner = get_player(discord_uuid, mc_uuid)
|
|
try:
|
|
if Location.objects.get(name__iexact=name, owner=owner).delete() == 0:
|
|
raise Location.DoesNotExist
|
|
except Location.DoesNotExist:
|
|
raise LocationLookUpError
|
|
|
|
return name
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def find_around(x_pos, z_pos, radius=200):
|
|
"""
|
|
:request: GET
|
|
:param x_pos: MC X Coordinate
|
|
:param z_pos: MC Z Coordinate
|
|
:param radius: Radius to each around (default 200)
|
|
:return: List of all locations in the radius
|
|
:raises: LocationLookupError
|
|
: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()
|
|
|
|
if len(locations) == 0:
|
|
raise LocationLookUpError
|
|
|
|
return objects_list_to_json(locations)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_item(item_name, quantity, diamond_price, shop_name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param item_name: name of the item
|
|
:param quantity: number of items being sold
|
|
:param diamond_price: price in diamonds
|
|
:param shop_name: Name of the shop, can be blank if the user only has one shop
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: Item Listing
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase
|
|
:help: Adds an item to a shop's inventory.
|
|
"""
|
|
|
|
player = get_player(discord_uuid, mc_uuid)
|
|
|
|
shop = get_location(player, shop_name, Shop).shop
|
|
|
|
item_listing = ItemListing.objects.create(shop=shop, amount=int(quantity), price=int(diamond_price),
|
|
item_name=item_name)
|
|
|
|
return item_listing.json
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_resource(resource_name, farm_name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param resource_name: name of the resource
|
|
:param farm_name: name of the farm to add the resource to. Can be none.
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: Item Listing
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase
|
|
:help: Adds a resource to a farm.
|
|
"""
|
|
|
|
player = get_player(discord_uuid, mc_uuid)
|
|
|
|
farm = get_location(player, farm_name, PublicFarm).publicfarm
|
|
|
|
resource = Resource.objects.create(farm=farm, resource_name=resource_name)
|
|
|
|
return resource.json
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def find_farm(resource_name):
|
|
"""
|
|
:request: GET
|
|
:param resource_name: Resource to search for
|
|
:return: List of top matching farms
|
|
:raises: ResourceNotFoundError
|
|
:help: Lists farms that produce a resource.
|
|
"""
|
|
if len(resource_name) == 0:
|
|
raise EmptryString
|
|
|
|
farms = PublicFarm.objects.filter(resource__resource_name__icontains=resource_name).all()[:10]
|
|
|
|
if len(farms) == 0:
|
|
raise ResourceNotFoundError
|
|
|
|
return objects_list_to_json(farms)
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def selling(item_name):
|
|
"""
|
|
:request: GET
|
|
:param item_name: Item name to search for
|
|
:return: List of top matching shops, sorted by the date last restocke
|
|
:raises: ItemNotFound
|
|
:help: Lists shops selling an item. Sorted by when they were last restocked.
|
|
"""
|
|
|
|
return get_selling(item_name, sort="-date_restocked")
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def selling_price(item_name):
|
|
"""
|
|
:request: GET
|
|
:param item_name: Item name to search for
|
|
:return: List of top matching shops, sorted by the
|
|
:raises: ItemNotFound
|
|
:help: Lists shops selling an item. Sorted lowest price to highest price.
|
|
"""
|
|
|
|
return get_selling(item_name, sort="normalized_price")
|
|
|
|
|
|
def get_selling(item_name, sort):
|
|
items = []
|
|
if len(item_name) == 0:
|
|
raise EmptryString
|
|
|
|
all_shop_ids = ItemListing.objects.filter(item_name__icontains=item_name).annotate(normalized_price=F('price') / F('amount')).order_by(sort).values("shop_id").all()
|
|
|
|
if all_shop_ids.count() == 0:
|
|
raise ItemNotFound
|
|
|
|
# Removes duplicates
|
|
shop_ids = []
|
|
|
|
for shop_id in all_shop_ids:
|
|
if shop_id not in shop_ids:
|
|
shop_ids.append(shop_id)
|
|
|
|
for shop_id in shop_ids:
|
|
shop = Shop.objects.get(pk=shop_id['shop_id']).json
|
|
|
|
item_query = ItemListing.objects.filter(
|
|
item_name__icontains=item_name, shop_id=shop_id['shop_id']).order_by("-date_restocked")
|
|
|
|
item_list = []
|
|
for item in item_query:
|
|
item_list.append(item)
|
|
|
|
shop["items"] = objects_list_to_json(item_list)
|
|
items.append(shop)
|
|
|
|
return items
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def info(location_name):
|
|
"""
|
|
:request: GET
|
|
:param location_name: Name of the location to get info on.
|
|
:return: JSON representation of location
|
|
:raises: LocationLookupError
|
|
:help: Gives additional info about a location.
|
|
"""
|
|
|
|
location = Location.objects.filter(name__iexact=location_name).first()
|
|
|
|
if location is None:
|
|
location = Location.objects.filter(name__iregex=".*{}.*".format(location_name)).first()
|
|
|
|
if location is not None:
|
|
loc = location.loc_child_obj
|
|
loc_json = loc.json
|
|
|
|
if type(loc) == Shop:
|
|
loc_json["items"] = []
|
|
for item in loc.shop_selling.order_by("item_name").all():
|
|
loc_json["items"].append(item.json)
|
|
elif type(loc) == PublicFarm:
|
|
loc_json["resources"] = []
|
|
for resource in loc.resource.order_by("resource_name").all():
|
|
loc_json["resources"].append(resource.json)
|
|
|
|
return loc_json
|
|
else:
|
|
raise LocationLookUpError
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def tunnel(player_name):
|
|
"""
|
|
:request: GET
|
|
:param player_name: MC player name
|
|
:return: List of all the tunnels a user owns
|
|
:raises: LocationLookUpError
|
|
:raises: LocationLookupError
|
|
:help: Finds all the tunnels a player owns.
|
|
"""
|
|
|
|
tunnels = Tunnel.objects.filter(location__owner__name__icontains=player_name).all()
|
|
|
|
if len(tunnels) == 0:
|
|
raise LocationLookUpError
|
|
|
|
return objects_list_to_json(tunnels)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def edit_pos(x, z, loc_name, dimension="O", discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param x: New MC X coordinate
|
|
:param z: New MC Z Coordinate
|
|
:param dimension: MC Dimension
|
|
:param loc_name: Location Name to edit
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: MC UUID
|
|
:return: Edited Location
|
|
:raises:
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase
|
|
:help: Edits the position of a location.
|
|
"""
|
|
|
|
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
|
|
location = get_location(player, loc_name)
|
|
|
|
location.x_coord = x
|
|
location.z_coord = z
|
|
location.dimension = dimension
|
|
location.save()
|
|
|
|
return location.json
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def edit_tunnel(tunnel_direction, tunnel_number, loc_name, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param tunnel_direction: New Tunnel Direction
|
|
:param tunnel_number: New Tunnel Address
|
|
:param loc_name: Location Name to edit
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: Edited Location
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase
|
|
:help: Edits the tunnel of a location.
|
|
"""
|
|
|
|
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
|
|
location = get_location(player, loc_name)
|
|
tunnel_direction = match_tunnel(tunnel_direction)
|
|
|
|
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
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def edit_name(new_name, loc_name, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param new_name: New Location Name
|
|
:param loc_name: Old Location name
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: MC UUID
|
|
:return: Edited Location
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase
|
|
:help: Edits the name of a location.
|
|
"""
|
|
|
|
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(RequestTypes.POST)
|
|
def delete_item(item, shop_name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
: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: Shop where the item was deleted from
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase, ItemNotFound
|
|
:help: Deletes an item from a shop.
|
|
"""
|
|
|
|
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
|
|
|
|
shop = get_location(player, shop_name, Shop)
|
|
|
|
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
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def delete_resource(resource, farm_name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param resource: resource to delete
|
|
:param farm_name: Farm with resource, can be None if the user only has one farm
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: PublicFarm where the resource was deleted from
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase, ItemNotFound
|
|
:help: Deletes a resource from a farm.
|
|
"""
|
|
|
|
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
|
|
|
|
farm = get_location(player, farm_name, PublicFarm)
|
|
|
|
delete_list = Resource.objects.filter(resource_name=resource, farm=farm).all()
|
|
|
|
if len(delete_list) == 0:
|
|
raise ResourceNotFoundError
|
|
|
|
delete_list.delete()
|
|
|
|
return farm.json
|
|
|
|
|
|
@command(RequestTypes.GET)
|
|
def me(discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: GET
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: MC UUID
|
|
:return: Returns a list of all the locations owned by a user
|
|
:raises: NoLocationsInDatabase, PlayerNotFound
|
|
:help: Find all the locations owned by a player in the database.
|
|
"""
|
|
|
|
try:
|
|
player = get_player(discord_uuid=discord_uuid, mc_uuid=mc_uuid)
|
|
except Player.DoesNotExist:
|
|
raise PlayerNotFound
|
|
|
|
locations = Location.objects.filter(owner=player).all()
|
|
|
|
if len(locations) == 0:
|
|
raise NoLocationsInDatabase
|
|
|
|
return objects_list_to_json(locations)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def restock(item_name, shop_name=None, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param item_name: Item to restock
|
|
:param shop_name: Shop the item is in, can be none if the only one location is owned by the user
|
|
:param discord_uuid: Discord UUID
|
|
:param mc_uuid: Minecraft UUID
|
|
:return: List of items updated
|
|
:raises: PlayerNotFound, LocationLookupError, EntryNameNotUniqueError, NoLocationsInDatabase, ItemNotFound
|
|
:help: Restocks items matching the item name in your shop.
|
|
"""
|
|
owner = get_player(discord_uuid, mc_uuid)
|
|
shop = get_location(owner, shop_name, Shop)
|
|
|
|
items = ItemListing.objects.filter(item_name__iregex=item_name, shop=shop).all()
|
|
|
|
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)
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_owner(new_owner_name, location_name, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param new_owner_name: The MC username of the new owner
|
|
:param location_name: The name of the location to add them to
|
|
:param discord_uuid: Discord UUID of the current owner
|
|
:param mc_uuid: MC UUID of the current owner
|
|
:return: Update Location
|
|
:raises: PlayerNotFound, LocationLookupError, IsOwnerError, OwnerNotFound
|
|
:help: Adds a co-owner to a location.
|
|
"""
|
|
owner = get_player(discord_uuid, mc_uuid)
|
|
|
|
try:
|
|
new_owner = Player.objects.get(name__iexact=new_owner_name)
|
|
except Player.DoesNotExist:
|
|
raise OwnerNotFoundError
|
|
|
|
location = get_location(owner, location_name, Location)
|
|
|
|
if location.owner.filter(id=new_owner.id):
|
|
raise IsOwnerError
|
|
|
|
location.owner.add(new_owner)
|
|
|
|
location.save()
|
|
|
|
return location.json
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def add_resident(new_resident_name, town_name, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param new_resident_name: The MC username of the new resident
|
|
:param town_name: The name of the town to add the resident to, can be blank if the owner has one town
|
|
:param discord_uuid: Discord UUID of the town owner
|
|
:param mc_uuid: MC UUID of the town owner
|
|
:return: Updated Location
|
|
:raises: PlayerNotFound, LocationLookupError, IsResidentError, ResidentNotFoundError
|
|
:help: Adds a resident to a town.
|
|
"""
|
|
owner = get_player(discord_uuid, mc_uuid)
|
|
|
|
try:
|
|
new_resident = Player.objects.get(name__iexact=new_resident_name)
|
|
except Player.DoesNotExist:
|
|
raise ResidentNotFoundError
|
|
|
|
town = get_location(owner, town_name, Town)
|
|
|
|
if town.residents.filter(id=new_resident.id).exists() | town.owner.filter(id=new_resident.id).exists():
|
|
raise IsResidentError
|
|
|
|
town.residents.add(new_resident)
|
|
|
|
town.save()
|
|
|
|
return town.json
|
|
|
|
|
|
@command(RequestTypes.POST)
|
|
def remove_resident(resident_name, town_name, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param resident_name: Name of the resident to remove
|
|
:param town_name: Name of the town, can be blank if the owner has one town
|
|
:param discord_uuid: Owner discord uuid
|
|
:param mc_uuid: Owner mc uuid
|
|
:raises: PlayerNotFound, LocationLookupError, ResidentNotFoundError
|
|
:return: Updated town
|
|
:help: Removes a resident from a town.
|
|
"""
|
|
|
|
owner = get_player(discord_uuid, mc_uuid)
|
|
town = get_location(owner, town_name, Town)
|
|
try:
|
|
resident = town.residents.get(name__iexact=resident_name)
|
|
except Player.DoesNotExist:
|
|
raise ResidentNotFoundError
|
|
|
|
town.residents.remove(resident)
|
|
|
|
town.save()
|
|
return town.json
|
|
|
|
|
|
@command(RequestTypes.POST, permission_level=PermissionLevel.MOD)
|
|
def mod_delete(player_name, location_name):
|
|
uuid = grab_UUID(player_name)
|
|
delete(location_name, mc_uuid=uuid)
|
|
|
|
|
|
@command(RequestTypes.POST, permission_level=PermissionLevel.MOD)
|
|
def mod_delete_item(player_name, item_name, shop_name):
|
|
uuid = grab_UUID(player_name)
|
|
delete_item(item_name, shop_name=shop_name, mc_uuid=uuid)
|
|
|
|
|
|
@command(RequestTypes.POST, permission_level=PermissionLevel.MOD)
|
|
def mod_edit_name(player_name, new_name, loc_name):
|
|
uuid = grab_UUID(player_name)
|
|
edit_name(new_name, loc_name, mc_uuid=uuid)
|
|
|
|
|
|
@command(RequestTypes.POST, permission_level=PermissionLevel.MOD)
|
|
def mod_remove_resident(player_name, resident_name, town_name):
|
|
uuid = grab_UUID(player_name)
|
|
remove_resident(resident_name, town_name, mc_uuid=uuid)
|
|
|
|
|
|
@command(RequestTypes.POST, permission_level=PermissionLevel.MOD)
|
|
def mod_remove_owner(player_name, loc_name):
|
|
uuid = grab_UUID(player_name)
|
|
owner = get_player(mc_uuid=uuid)
|
|
|
|
location = get_location(owner, loc_name)
|
|
location.owner.remove(owner)
|
|
|
|
|
|
@command(RequestTypes.POST, permission_level=PermissionLevel.PLAYER)
|
|
def primary_location(loc_name, discord_uuid=None, mc_uuid=None):
|
|
"""
|
|
:request: POST
|
|
:param loc_name: location to set as primary
|
|
:param discord_uuid: player discord uuid
|
|
:param mc_uuid: player mc uuid
|
|
:return: json representation of the primary location
|
|
"""
|
|
player = get_player(discord_uuid, mc_uuid)
|
|
loc = get_location(player, loc_name)
|
|
|
|
player.primary_location = loc
|
|
|
|
player.save()
|
|
|
|
return loc.json
|
|
|