from django.db import models from django.conf import settings from django.urls import reverse from sys import maxsize from GeoffreyApp.util import create_token, objects_list_to_json # Create your models here. class APIToken(models.Model): key = models.CharField(default=create_token, max_length=25, unique=True) ''' Key used to access the Geoffrey API ''' name = models.CharField(max_length=50, blank=True) ''' Name of the key ''' commands_perm = models.BooleanField(default=False) ''' Permission to use the command api ''' def __str__(self): if len(self.name): return "{}: {}".format(self.name, self.key) else: return self.key class Player(models.Model): name = models.CharField(max_length=30, unique=True) ''' Player username ''' mc_uuid = models.CharField(max_length=36, unique=True) ''' Minecraft UUID ''' discord_uuid = models.CharField(max_length=50, unique=True) ''' Discord UUID ''' @property def loc_count(self): return Location.objects.filter(owner=self).count() @property def json(self): return {"name": self.name, "mc_uuid": self.mc_uuid, "discord_uuid": self.discord_uuid } def __str__(self): return self.name class Location(models.Model): DIMENSIONS = ( ('O', 'Overworld'), ('N', 'Nether'), ('E', 'The End') ) name = models.CharField(max_length=128, unique=True) ''' Name of the location ''' x_coord = models.IntegerField() ''' X Position ''' z_coord = models.IntegerField() ''' Z Position ''' dimension = models.CharField(max_length=1, choices=DIMENSIONS) owner = models.ManyToManyField(Player) ''' Owner of Location ''' @property def location(self): return "(x={}, z={})".format(self.x_coord, self.z_coord) @property def tunnel(self): try: tunnel = Tunnel.objects.get(location=self) except Tunnel.DoesNotExist: tunnel = None return tunnel @property def get_owners(self): owner_list = [] for owner in self.owner.all(): owner_list.append(owner.json) return owner_list @property def link(self): return "" @property def json(self): return {"type": self.__class__.__name__, "name": self.name, "x_coord": self.x_coord, "z_coord": self.z_coord, "dimension": self.dimension, "owner": self.get_owners, "location": self.location, "tunnel": None if self.tunnel is None else self.tunnel.tunnel_str, "link": self.link } @property def loc_type(self): str = self.loc_child_obj.__class__.__name__ return str @property def link(self): return self.loc_child_obj.link() @property def loc_child_obj(self): if hasattr(self, "shop"): return self.shop elif hasattr(self, "base"): return self.base elif hasattr(self, "town"): return self.town else: return self @property def dynmap_url(self): base_url = getattr(settings, "GEOFFREY_DYNMAP_BASE_URL") world_name = getattr(settings, "GEOFFREY_DYNMAP_WORLD_NAME") if base_url is not None: url = base_url + "/?worldname={}&mapname=surface&zoom=4&x={}&y=65&z={}".format(world_name, self.x_coord, self.z_coord) return url else: return None def __str__(self): return self.name class Shop(Location): def __str__(self): return "Shop: %s" % self.name @property def link(self): return reverse("GeoffreyShopInfo", kwargs={"id": self.id}) class Base(Location): def __str__(self): return "Base: %s" % self.name @property def link(self): return reverse("GeoffreyBaseInfo", kwargs={"id": self.id}) 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.get_residents return json @property def link(self): return reverse("GeoffreyTownInfo", kwargs={"id": self.id}) class ItemListing(models.Model): item_name = models.CharField(max_length=128) ''' Name of the item ''' price = models.IntegerField() ''' Number of diamonds per amount of items ''' amount = models.IntegerField() ''' Number of items ''' date_restocked = models.DateTimeField(auto_now=True) ''' Datetime the item was last restocked ''' shop = models.ForeignKey(Shop, related_name="shop_selling", on_delete=models.CASCADE) ''' Shop the item is sold at ''' @property def normalized_price(self): if self.amount == 0: return maxsize else: return self.price/self.amount @property def json(self): return {"item_name": self.item_name, "price": self.price, "amount": self.amount, "date_restocked": self.date_restocked, "normalized_price": self.normalized_price, "shop": self.shop.json, } def __str__(self): return "Item: %d %s for %d" % (self.amount, self.item_name, self.amount) class Tunnel(models.Model): TUNNEL_NAMES = ( ('N', getattr(settings, 'GEOFFREY_NORTH_TUNNEL', '')), ('E', getattr(settings, 'GEOFFREY_EAST_TUNNEL', '')), ('S', getattr(settings, 'GEOFFREY_SOUTH_TUNNEL', '')), ('W', getattr(settings, 'GEOFFREY_WEST_TUNNEL', '')) ) ''' Tunnel Direction ''' tunnel_number = models.IntegerField() ''' Tunnel coordinate ''' tunnel_direction = models.CharField(max_length=1, choices=TUNNEL_NAMES) ''' Tunnel Direction ''' location = models.ForeignKey(Location, related_name="tunnel_location", on_delete=models.CASCADE) ''' Location that the tunnel is for ''' def __str__(self): return "Tunnel: %s %d" % (self.get_tunnel_direction_display(), self.tunnel_number) @property def json(self): return {"location_name": self.location.name, "tunnel_direction": self.get_tunnel_direction_display(), "tunnel_number": self.tunnel_number } @property def tunnel_str(self): return "{} {}".format(self.get_tunnel_direction_display(), self.tunnel_number)