Merge pull request 'First pass of a GraphQL API' (#25) from graphql-api into v2
Reviewed-on: https://git.etztech.xyz/ZeroHD/Geoffrey/pulls/25doc_update
commit
abaeba3b52
|
@ -853,3 +853,23 @@ def mod_remove_owner(player_name, loc_name):
|
||||||
|
|
||||||
location = get_location(owner, loc_name)
|
location = get_location(owner, loc_name)
|
||||||
location.owner.remove(owner)
|
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
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
from django.db import models
|
|
|
@ -0,0 +1,215 @@
|
||||||
|
import graphene
|
||||||
|
from django.http import JsonResponse
|
||||||
|
from graphene_django import DjangoObjectType
|
||||||
|
|
||||||
|
from GeoffreyApp.models import *
|
||||||
|
from GeoffreyApp.api.key import check_key
|
||||||
|
|
||||||
|
|
||||||
|
class UnauthorizedQuery(Exception):
|
||||||
|
"""
|
||||||
|
Unauthorized Query
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__("GraphQL Request Not Authorized")
|
||||||
|
|
||||||
|
|
||||||
|
class PlayerType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = Player
|
||||||
|
fields = ("id", "name", "discord_uuid", "mc_uuid", "primary_location")
|
||||||
|
|
||||||
|
primary_location = graphene.Field("GeoffreyApp.api.schema.LocationType")
|
||||||
|
|
||||||
|
|
||||||
|
class TunnelType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = Tunnel
|
||||||
|
fields = ("tunnel_number", "tunnel_direction")
|
||||||
|
|
||||||
|
|
||||||
|
class ItemListingType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = ItemListing
|
||||||
|
fields = ("item_name", "price", "amount", "date_restocked", "normalized_price", "id")
|
||||||
|
|
||||||
|
normalized_price = graphene.Float()
|
||||||
|
shop = graphene.Field("GeoffreyApp.api.schema.ShopType")
|
||||||
|
|
||||||
|
def resolve_shop(self, info):
|
||||||
|
return self.shop
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = Resource
|
||||||
|
fields = ("resource_name", "id")
|
||||||
|
|
||||||
|
|
||||||
|
class LocationType(DjangoObjectType):
|
||||||
|
class Meta:
|
||||||
|
model = Location
|
||||||
|
fields = ("id", "name", "loc_type", "x_coord", "z_coord", "dimension", "owner", "tunnel", "link")
|
||||||
|
|
||||||
|
loc_type = graphene.String()
|
||||||
|
owner = graphene.List(PlayerType)
|
||||||
|
link = graphene.String()
|
||||||
|
tunnel = graphene.Field(TunnelType)
|
||||||
|
|
||||||
|
def resolve_owner(self, info):
|
||||||
|
return self.owner.all()
|
||||||
|
|
||||||
|
|
||||||
|
class ShopType(LocationType):
|
||||||
|
class Meta:
|
||||||
|
model = Shop
|
||||||
|
|
||||||
|
inventory = graphene.List(ItemListingType)
|
||||||
|
|
||||||
|
def resolve_inventory(self, info):
|
||||||
|
return self.shop_selling.all()
|
||||||
|
|
||||||
|
|
||||||
|
class PublicFarmType(LocationType):
|
||||||
|
class Meta:
|
||||||
|
model = PublicFarm
|
||||||
|
|
||||||
|
resource = graphene.List(ResourceType)
|
||||||
|
|
||||||
|
def resolve_resource(self, info):
|
||||||
|
return self.resource.all()
|
||||||
|
|
||||||
|
|
||||||
|
class BaseType(LocationType):
|
||||||
|
class Meta:
|
||||||
|
model = Base
|
||||||
|
|
||||||
|
|
||||||
|
class PointOfInterestType(LocationType):
|
||||||
|
class Meta:
|
||||||
|
model = PointOfInterest
|
||||||
|
|
||||||
|
|
||||||
|
class MarketType(LocationType):
|
||||||
|
class Meta:
|
||||||
|
model = Market
|
||||||
|
|
||||||
|
shops = graphene.List(ShopType)
|
||||||
|
|
||||||
|
def resolve_shops(self, info):
|
||||||
|
return self.get_shops()
|
||||||
|
|
||||||
|
|
||||||
|
class AttractionType(LocationType):
|
||||||
|
class Meta:
|
||||||
|
model = Attraction
|
||||||
|
|
||||||
|
|
||||||
|
class TownType(LocationType):
|
||||||
|
class Meta:
|
||||||
|
model = Attraction
|
||||||
|
|
||||||
|
residents = graphene.List(PlayerType)
|
||||||
|
|
||||||
|
def resolve_residents(self, info):
|
||||||
|
return self.residents.all()
|
||||||
|
|
||||||
|
|
||||||
|
class ProtectedAPI():
|
||||||
|
def __init__(self, func):
|
||||||
|
self.func = func
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def protected_api():
|
||||||
|
def wrapper(func):
|
||||||
|
return ProtectedAPI(func)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
def __call__(self, root, info, **kwargs):
|
||||||
|
if "X-GeoffreyAPI-Token" in info.context.headers:
|
||||||
|
token = info.context.headers["X-GeoffreyAPI-Token"]
|
||||||
|
elif "token" in info.context.GET:
|
||||||
|
token = info.context.GET["token"]
|
||||||
|
else:
|
||||||
|
raise UnauthorizedQuery
|
||||||
|
|
||||||
|
if check_key(token, model_api_perm=True):
|
||||||
|
return self.func(root, info, **kwargs)
|
||||||
|
else:
|
||||||
|
return UnauthorizedQuery
|
||||||
|
|
||||||
|
|
||||||
|
class Query(graphene.ObjectType):
|
||||||
|
player = graphene.Field(PlayerType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False), mc_uuid=graphene.Argument(graphene.String, required=False), discord_uuid=graphene.Argument(graphene.String, required=False))
|
||||||
|
locations = graphene.List(LocationType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False))
|
||||||
|
shops = graphene.List(ShopType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False))
|
||||||
|
towns = graphene.List(TownType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False))
|
||||||
|
farms = graphene.List(PublicFarmType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False))
|
||||||
|
bases = graphene.List(BaseType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False))
|
||||||
|
attractions = graphene.List(AttractionType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False))
|
||||||
|
points_of_interest = graphene.List(PointOfInterestType, id=graphene.Argument(graphene.Int, required=False), name=graphene.Argument(graphene.String, required=False))
|
||||||
|
item_listing = graphene.List(ItemListingType, item=graphene.Argument(graphene.String, required=False))
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolve_player(root, info, id=None, name=None, discord_uuid=None, mc_uuid=None):
|
||||||
|
query = Player.objects
|
||||||
|
if id is not None:
|
||||||
|
query = query.filter(id=id)
|
||||||
|
elif name is not None:
|
||||||
|
query = query.filter(name__iexact=name)
|
||||||
|
elif discord_uuid is not None:
|
||||||
|
query = query.filter(discord_uuid=discord_uuid)
|
||||||
|
elif mc_uuid is not None:
|
||||||
|
query = query.filter(mc_uuid=mc_uuid)
|
||||||
|
|
||||||
|
return query.get()
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolve_locations(root, info, id=None, name=None):
|
||||||
|
return get_location(root, info, id=id, name=name, location_type=Location)
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolve_shops(root, info, id=None, name=None):
|
||||||
|
return get_location(root, info, id=id, name=name, location_type=Shop)
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolved_towns(root, info, id=None, name=None):
|
||||||
|
return get_location(root, info, id=id, name=name, location_type=Town)
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolved_farms(root, info, id=None, name=None):
|
||||||
|
return get_location(root, info, id=id, name=name, location_type=PublicFarm)
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolved_bases(root, info, id=None, name=None):
|
||||||
|
return get_location(root, info, id=id, name=name, location_type=Base)
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolved_attractions(root, info, id=None, name=None):
|
||||||
|
return get_location(root, info, id=id, name=name, location_type=Attraction)
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolved_points_of_interest(root, info, id=None, name=None):
|
||||||
|
return get_location(root, info, id=id, name=name, location_type=PointOfInterest)
|
||||||
|
|
||||||
|
@ProtectedAPI.protected_api()
|
||||||
|
def resolve_item_listing(root, info, item=None):
|
||||||
|
query = ItemListing.objects
|
||||||
|
if item is not None:
|
||||||
|
query = query.filter(item_name=item)
|
||||||
|
|
||||||
|
return query.all()
|
||||||
|
|
||||||
|
|
||||||
|
def get_location(root, info, id=None, name=None, location_type=Location):
|
||||||
|
if id is not None:
|
||||||
|
return location_type.objects.get(pk=id)
|
||||||
|
elif name is not None:
|
||||||
|
return location_type.objects.get(name__icontains=name)
|
||||||
|
else:
|
||||||
|
return location_type.objects.all()
|
||||||
|
|
||||||
|
|
||||||
|
schema = graphene.Schema(query=Query)
|
|
@ -83,6 +83,11 @@ class Player(models.Model):
|
||||||
Discord UUID
|
Discord UUID
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
primary_location = models.OneToOneField("Location", on_delete=models.DO_NOTHING, null=True)
|
||||||
|
"""
|
||||||
|
User's primary location
|
||||||
|
"""
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def loc_count(self):
|
def loc_count(self):
|
||||||
"""
|
"""
|
||||||
|
@ -101,12 +106,14 @@ class Player(models.Model):
|
||||||
"name" : "self.name",
|
"name" : "self.name",
|
||||||
"mc_uuid": "self.mc_uuid",
|
"mc_uuid": "self.mc_uuid",
|
||||||
"discord_uuid": "self.discord_uuid",
|
"discord_uuid": "self.discord_uuid",
|
||||||
|
"primary_location": "self.primary_location"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return {"name": self.name,
|
return {"name": self.name,
|
||||||
"mc_uuid": self.mc_uuid,
|
"mc_uuid": self.mc_uuid,
|
||||||
"discord_uuid": self.discord_uuid
|
"discord_uuid": self.discord_uuid,
|
||||||
|
"primary_location": self.primary_location.json
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -218,7 +225,8 @@ class Location(models.Model):
|
||||||
"owner": self.get_owners,
|
"owner": self.get_owners,
|
||||||
"location": self.position,
|
"location": self.position,
|
||||||
"tunnel": None if self.tunnel is None else self.tunnel.tunnel_str,
|
"tunnel": None if self.tunnel is None else self.tunnel.tunnel_str,
|
||||||
"link": self.link
|
"link": self.link,
|
||||||
|
"primary_location": self.player.primary_location
|
||||||
}
|
}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -18,5 +18,5 @@ setup(
|
||||||
url='https:/geoffrey.zerohighdef.com/',
|
url='https:/geoffrey.zerohighdef.com/',
|
||||||
author='ZeroHD',
|
author='ZeroHD',
|
||||||
author_email='zero@zerohighdef.com',
|
author_email='zero@zerohighdef.com',
|
||||||
install_requires=['django', 'requests', 'simplejson']
|
install_requires=['django', 'requests', 'simplejson', 'graphene_django']
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue