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 residentsdoc_update
parent
8b0f3867e0
commit
39302bb136
1
admin.py
1
admin.py
|
@ -8,3 +8,4 @@ admin.site.register(Shop)
|
||||||
admin.site.register(Tunnel)
|
admin.site.register(Tunnel)
|
||||||
admin.site.register(ItemListing)
|
admin.site.register(ItemListing)
|
||||||
admin.site.register(APIToken)
|
admin.site.register(APIToken)
|
||||||
|
admin.site.register(Town)
|
||||||
|
|
|
@ -6,18 +6,11 @@ import inspect
|
||||||
import datetime
|
import datetime
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from GeoffreyApp.util import objects_list_to_json
|
||||||
|
|
||||||
command_dict = {"GET": {}, "POST": {}, "DELETE": {}}
|
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):
|
def match_tunnel(tunnel_direction):
|
||||||
for direction in Tunnel.TUNNEL_NAMES:
|
for direction in Tunnel.TUNNEL_NAMES:
|
||||||
if re.search("{}.*".format(tunnel_direction), direction[1], re.IGNORECASE):
|
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)
|
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")
|
@command("POST")
|
||||||
def add_tunnel(tunnel_direction, tunnel_number, location_name=None, discord_uuid=None, mc_uuid=None):
|
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 location_name: The name of the location to add them to
|
||||||
:param discord_uuid: Discord UUID of the current owner
|
:param discord_uuid: Discord UUID of the current owner
|
||||||
:param mc_uuid: MC UUID of the current owner
|
:param mc_uuid: MC UUID of the current owner
|
||||||
:return: Updated Location
|
:return: Update Location
|
||||||
:raises: PlayerNotFound, LocationLookupError, PlayerInDBError
|
:raises: PlayerNotFound, LocationLookupError, IsOwnerError, OwnerNotFound
|
||||||
:help: Adds a co-owner to a location
|
:help: Adds a co-owner to a location
|
||||||
'''
|
'''
|
||||||
owner = get_player(discord_uuid, mc_uuid)
|
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:
|
try:
|
||||||
new_owner = Player.objects.get(name__iexact=new_owner_name)
|
new_owner = Player.objects.get(name__iexact=new_owner_name)
|
||||||
except Player.DoesNotExist:
|
except Player.DoesNotExist:
|
||||||
raise PlayerNotFound("New Owner Not in DB")
|
raise OwnerNotFoundError
|
||||||
|
|
||||||
location = get_location(owner, location_name, Location)
|
location = get_location(owner, location_name, Location)
|
||||||
|
|
||||||
if location.owner.filter(location__owner__name__iexact=new_owner_name):
|
if location.owner.filter(location__owner__name__iexact=new_owner_name):
|
||||||
raise PlayerInDBError
|
raise IsOwnerError
|
||||||
|
|
||||||
location.owner.add(new_owner)
|
location.owner.add(new_owner)
|
||||||
|
|
||||||
location.save()
|
location.save()
|
||||||
|
|
||||||
return location.json
|
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
|
||||||
|
|
17
errors.py
17
errors.py
|
@ -86,5 +86,22 @@ class EmptryString(DataBaseError):
|
||||||
class CommandNotFound(DataBaseError):
|
class CommandNotFound(DataBaseError):
|
||||||
"""Command not found"""
|
"""Command not found"""
|
||||||
|
|
||||||
|
|
||||||
class ExternalLookupFailed(DataBaseError):
|
class ExternalLookupFailed(DataBaseError):
|
||||||
"""Entry not found on external database"""
|
"""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"""
|
||||||
|
|
|
@ -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',),
|
||||||
|
),
|
||||||
|
]
|
25
models.py
25
models.py
|
@ -2,7 +2,7 @@ from django.db import models
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from sys import maxsize
|
from sys import maxsize
|
||||||
|
|
||||||
from GeoffreyApp.util import create_token
|
from GeoffreyApp.util import create_token, objects_list_to_json
|
||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
|
@ -129,6 +129,8 @@ class Location(models.Model):
|
||||||
return "shop"
|
return "shop"
|
||||||
elif hasattr(self, "base"):
|
elif hasattr(self, "base"):
|
||||||
return "base"
|
return "base"
|
||||||
|
elif hasattr(self, "town"):
|
||||||
|
return "town"
|
||||||
else:
|
else:
|
||||||
return "location"
|
return "location"
|
||||||
|
|
||||||
|
@ -157,6 +159,27 @@ class Base(Location):
|
||||||
return "Base: %s" % self.name
|
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):
|
class ItemListing(models.Model):
|
||||||
item_name = models.CharField(max_length=128)
|
item_name = models.CharField(max_length=128)
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -28,6 +28,11 @@ class CommandsAPITestCase(TestCase):
|
||||||
self.base.owner.add(self.player)
|
self.base.owner.add(self.player)
|
||||||
self.shop = Shop.objects.create(name="test shop", x_coord=500, z_coord=500,
|
self.shop = Shop.objects.create(name="test shop", x_coord=500, z_coord=500,
|
||||||
dimension="O")
|
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.shop.owner.add(self.player)
|
||||||
self.item = ItemListing.objects.create(shop=self.shop, price=1, amount=5, item_name="sed")
|
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")
|
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):
|
def test_add_tunnel(self):
|
||||||
base = Base.objects.create(name="Test", x_coord=0, z_coord=0)
|
base = Base.objects.create(name="Test", x_coord=0, z_coord=0)
|
||||||
|
|
||||||
|
@ -93,7 +105,7 @@ class CommandsAPITestCase(TestCase):
|
||||||
|
|
||||||
count = len(locations)
|
count = len(locations)
|
||||||
|
|
||||||
self.assertEqual(count, 2)
|
self.assertGreater(count, 1)
|
||||||
|
|
||||||
def test_find_around(self):
|
def test_find_around(self):
|
||||||
self.populate()
|
self.populate()
|
||||||
|
@ -126,16 +138,18 @@ class CommandsAPITestCase(TestCase):
|
||||||
|
|
||||||
locations = me(discord_uuid=DISCORD_UUID)
|
locations = me(discord_uuid=DISCORD_UUID)
|
||||||
|
|
||||||
self.assertEqual(len(locations), 2)
|
self.assertGreater(len(locations), 1)
|
||||||
|
|
||||||
def test_delete(self):
|
def test_delete(self):
|
||||||
self.populate()
|
self.populate()
|
||||||
|
|
||||||
|
count = Location.objects.filter(name__icontains="test").all().count()
|
||||||
|
|
||||||
delete(name="test", discord_uuid=DISCORD_UUID)
|
delete(name="test", discord_uuid=DISCORD_UUID)
|
||||||
|
|
||||||
locations = Location.objects.filter(name__icontains="test").all()
|
locations = Location.objects.filter(name__icontains="test").all()
|
||||||
|
|
||||||
self.assertEqual(len(locations), 1)
|
self.assertEqual(len(locations), count - 1)
|
||||||
|
|
||||||
def test_delete_item(self):
|
def test_delete_item(self):
|
||||||
self.populate()
|
self.populate()
|
||||||
|
@ -168,3 +182,29 @@ class CommandsAPITestCase(TestCase):
|
||||||
self.assertEquals(shop.id, self.shop.id)
|
self.assertEquals(shop.id, self.shop.id)
|
||||||
|
|
||||||
self.assertRaises(PlayerInDBError, add_owner, new_owner.name, self.shop.name, discord_uuid=DISCORD_UUID)
|
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)
|
||||||
|
|
Loading…
Reference in New Issue