Added the town location type

+Added the Towns Model, a location type with a residents field
+Added Commands to add/remove residents
+Added new errors for adding owners and residents
doc_update
Joey Hines 2019-02-02 16:31:02 -06:00
parent 8b0f3867e0
commit 39302bb136
7 changed files with 196 additions and 17 deletions

View File

@ -8,3 +8,4 @@ admin.site.register(Shop)
admin.site.register(Tunnel)
admin.site.register(ItemListing)
admin.site.register(APIToken)
admin.site.register(Town)

View File

@ -6,18 +6,11 @@ import inspect
import datetime
import re
from GeoffreyApp.util import objects_list_to_json
command_dict = {"GET": {}, "POST": {}, "DELETE": {}}
def objects_list_to_json(obj_list):
json_list = []
for obj in obj_list:
json_list.append(obj.json)
return json_list
def match_tunnel(tunnel_direction):
for direction in Tunnel.TUNNEL_NAMES:
if re.search("{}.*".format(tunnel_direction), direction[1], re.IGNORECASE):
@ -161,6 +154,22 @@ 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")
def add_town(x_pos, z_pos, name=None, discord_uuid=None, mc_uuid=None):
'''
:request: POST
:param x_pos: MC X Coordinate
:param z_pos: MC Z Coordinate
: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 town
:raises: EntryNameNotUniqueError, PlayerNotFound, LocationLookupError
:help: Adds your town to the database. The name is optional if this is your first town
'''
return add_location(x_pos, z_pos, name=name, discord_uuid=discord_uuid, mc_uuid=mc_uuid, loc_type=Town)
@command("POST")
def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid=None, mc_uuid=None):
'''
@ -529,8 +538,8 @@ def add_owner(new_owner_name, location_name, discord_uuid=None, mc_uuid=None):
: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: Updated Location
:raises: PlayerNotFound, LocationLookupError, PlayerInDBError
:return: Update Location
:raises: PlayerNotFound, LocationLookupError, IsOwnerError, OwnerNotFound
:help: Adds a co-owner to a location
'''
owner = get_player(discord_uuid, mc_uuid)
@ -538,15 +547,72 @@ def add_owner(new_owner_name, location_name, discord_uuid=None, mc_uuid=None):
try:
new_owner = Player.objects.get(name__iexact=new_owner_name)
except Player.DoesNotExist:
raise PlayerNotFound("New Owner Not in DB")
raise OwnerNotFoundError
location = get_location(owner, location_name, Location)
if location.owner.filter(location__owner__name__iexact=new_owner_name):
raise PlayerInDBError
raise IsOwnerError
location.owner.add(new_owner)
location.save()
return location.json
@command("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(Q(town__owner__name__iexact=new_resident_name) |
Q(town__residents__name__iexact=new_resident_name)).all().count():
raise IsResidentError
town.residents.add(new_resident)
town.save()
return town.json
@command("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, IsResidentError, ResidentNotFoundError
:return: Updated town
'''
owner = get_player(discord_uuid, mc_uuid)
town = get_location(owner, town_name, Town)
try:
resident = town.residents.get(town__residents__name__iexact=resident_name)
except Player.DoesNotExist:
raise ResidentNotFoundError
town.residents.remove(resident)
town.save()
return town.json

View File

@ -86,5 +86,22 @@ class EmptryString(DataBaseError):
class CommandNotFound(DataBaseError):
"""Command not found"""
class ExternalLookupFailed(DataBaseError):
"""Entry not found on external database"""
class IsOwnerError(DataBaseError):
"""Player is already an owner of the location"""
class IsResidentError(DataBaseError):
"""Player is already a resident in the town"""
class ResidentNotFoundError(DataBaseError):
"""No resident matches"""
class OwnerNotFoundError(DataBaseError):
"""No owner matches"""

View File

@ -0,0 +1,23 @@
# Generated by Django 2.1.2 on 2019-02-02 20:57
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('GeoffreyApp', '0006_auto_20190131_1822'),
]
operations = [
migrations.CreateModel(
name='Town',
fields=[
('location_ptr',
models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True,
primary_key=True, serialize=False, to='GeoffreyApp.Location')),
('residents', models.ManyToManyField(to='GeoffreyApp.Player')),
],
bases=('GeoffreyApp.location',),
),
]

View File

@ -2,7 +2,7 @@ from django.db import models
from django.conf import settings
from sys import maxsize
from GeoffreyApp.util import create_token
from GeoffreyApp.util import create_token, objects_list_to_json
# Create your models here.
@ -129,6 +129,8 @@ class Location(models.Model):
return "shop"
elif hasattr(self, "base"):
return "base"
elif hasattr(self, "town"):
return "town"
else:
return "location"
@ -157,6 +159,27 @@ class Base(Location):
return "Base: %s" % self.name
class Town(Location):
residents = models.ManyToManyField(Player)
def __str__(self):
return "Town: %s" % self.name
@property
def get_residents(self):
residents = self.residents.all()
return objects_list_to_json(residents)
@property
def json(self):
json = super().json
json["residents"] = self.residents
return json
class ItemListing(models.Model):
item_name = models.CharField(max_length=128)
'''

View File

@ -28,6 +28,11 @@ class CommandsAPITestCase(TestCase):
self.base.owner.add(self.player)
self.shop = Shop.objects.create(name="test shop", x_coord=500, z_coord=500,
dimension="O")
self.town = Town.objects.create(name="test town", x_coord=-500, z_coord=-500,
dimension="O")
self.town.owner.add(self.player)
self.shop.owner.add(self.player)
self.item = ItemListing.objects.create(shop=self.shop, price=1, amount=5, item_name="sed")
@ -58,6 +63,13 @@ class CommandsAPITestCase(TestCase):
self.assertEqual(shop.owner.all()[0].name, "ZeroHD")
def test_add_town(self):
add_town(x_pos=0, z_pos=0, name=None, discord_uuid=DISCORD_UUID)
town = Town.objects.filter(name__icontains=USERNAME).all().first()
self.assertEqual(town.owner.all()[0].name, "ZeroHD")
def test_add_tunnel(self):
base = Base.objects.create(name="Test", x_coord=0, z_coord=0)
@ -93,7 +105,7 @@ class CommandsAPITestCase(TestCase):
count = len(locations)
self.assertEqual(count, 2)
self.assertGreater(count, 1)
def test_find_around(self):
self.populate()
@ -126,16 +138,18 @@ class CommandsAPITestCase(TestCase):
locations = me(discord_uuid=DISCORD_UUID)
self.assertEqual(len(locations), 2)
self.assertGreater(len(locations), 1)
def test_delete(self):
self.populate()
count = Location.objects.filter(name__icontains="test").all().count()
delete(name="test", discord_uuid=DISCORD_UUID)
locations = Location.objects.filter(name__icontains="test").all()
self.assertEqual(len(locations), 1)
self.assertEqual(len(locations), count - 1)
def test_delete_item(self):
self.populate()
@ -168,3 +182,29 @@ class CommandsAPITestCase(TestCase):
self.assertEquals(shop.id, self.shop.id)
self.assertRaises(PlayerInDBError, add_owner, new_owner.name, self.shop.name, discord_uuid=DISCORD_UUID)
def test_add_resident(self):
self.populate()
new_resident = Player.objects.create(name="Vakky", mc_uuid="5", discord_uuid="5")
add_resident(new_resident.name, self.town.name, discord_uuid=DISCORD_UUID)
town = Town.objects.get(residents__name__icontains="Vakky")
self.assertEquals(town.id, self.town.id)
self.assertRaises(PlayerInDBError, add_resident, new_resident.name, self.town.name, discord_uuid=DISCORD_UUID)
self.assertRaises(PlayerInDBError, add_resident, self.player.name, self.town.name, discord_uuid=DISCORD_UUID)
def test_remove_resident(self):
self.populate()
new_resident = Player.objects.create(name="Vakky", mc_uuid="5", discord_uuid="5")
add_resident(new_resident.name, self.town.name, discord_uuid=DISCORD_UUID)
Town.objects.get(residents__name__icontains="Vakky")
remove_resident(new_resident.name, self.town.name, discord_uuid=DISCORD_UUID)
self.assertRaises(Town.DoesNotExist, Town.objects.get, residents__name__icontains="Vakky")
self.assertRaises(ResidentNotFoundError, remove_resident, new_resident.name, self.town.name,
discord_uuid=DISCORD_UUID)

View File

@ -10,3 +10,12 @@ def create_token(length=25):
token += d
return token
def objects_list_to_json(obj_list):
json_list = []
for obj in obj_list:
json_list.append(obj.json)
return json_list