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)