major player game data schema update
This commit is contained in:
parent
cd89bba8ad
commit
244af4792f
@ -4,7 +4,7 @@
|
||||
<title>Simple Frontend</title>
|
||||
<script>
|
||||
function fetchData() {
|
||||
fetch('http://localhost:8000/games')
|
||||
fetch('http://localhost:8000/api/games')
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
// Assuming 'data' is an array of games
|
||||
|
@ -9,15 +9,15 @@ from server.models import (
|
||||
Game,
|
||||
Guild,
|
||||
Player,
|
||||
PlayerGameProfile,
|
||||
WowProfile,
|
||||
ValorantProfile,
|
||||
PlayerGuild,
|
||||
PlayerGameData,
|
||||
GuildGameDataSchema,
|
||||
WowClasses,
|
||||
)
|
||||
|
||||
|
||||
def populate_games():
|
||||
games = ["World of Warcraft", "Valorant"]
|
||||
games = ["World of Warcraft", "Counter Strike: Global Offensive"]
|
||||
for game in games:
|
||||
g = Game.objects.get_or_create(name=game)[0]
|
||||
|
||||
@ -47,47 +47,170 @@ def populate_player_guilds():
|
||||
)[0]
|
||||
|
||||
|
||||
def populate_player_game_profiles():
|
||||
player_game_profiles = [
|
||||
{"player": "Pixel", "game": "World of Warcraft"},
|
||||
{"player": "Zman", "game": "World of Warcraft"},
|
||||
{"player": "Skip", "game": "Valorant"},
|
||||
{"player": "Skip", "game": "World of Warcraft"},
|
||||
def populate_wow_classes():
|
||||
wow_classes = [
|
||||
"Warrior",
|
||||
"Mage",
|
||||
"Rogue",
|
||||
"Priest",
|
||||
"Warlock",
|
||||
"Druid",
|
||||
"Hunter",
|
||||
"Shaman",
|
||||
"Paladin",
|
||||
]
|
||||
for profile in player_game_profiles:
|
||||
p = PlayerGameProfile.objects.get_or_create(
|
||||
player=Player.objects.get(name=profile["player"]),
|
||||
game=Game.objects.get(name=profile["game"]),
|
||||
)[0]
|
||||
for wow_class in wow_classes:
|
||||
w = WowClasses.objects.get_or_create(name=wow_class)[0]
|
||||
|
||||
|
||||
def populate_wow_profiles():
|
||||
wow_profiles = [
|
||||
{"player": "Pixel", "level": 60, "class_name": "Mage"},
|
||||
{"player": "Zman", "level": 60, "class_name": "Warrior"},
|
||||
{"player": "Skip", "level": 60, "class_name": "Rogue"},
|
||||
]
|
||||
for profile in wow_profiles:
|
||||
p = WowProfile.objects.get_or_create(
|
||||
player_game_profile=PlayerGameProfile.objects.get(
|
||||
player=Player.objects.get(name=profile["player"]),
|
||||
game=Game.objects.get(name="World of Warcraft"),
|
||||
),
|
||||
level=profile["level"],
|
||||
class_name=profile["class_name"],
|
||||
)[0]
|
||||
def populate_guild_game_data_schema():
|
||||
wow_gamer_schema = {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"playerName": {"type": "string"},
|
||||
"playerDiscordId": {"type": "string"},
|
||||
"playerAvailabilities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"day": {"type": "string"},
|
||||
"time": {"type": "string"},
|
||||
"timeZone": {"type": "string"},
|
||||
},
|
||||
"required": ["day", "time", "timeZone"],
|
||||
},
|
||||
},
|
||||
"playerRaids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
},
|
||||
"required": ["name"],
|
||||
},
|
||||
},
|
||||
"characters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {"type": "string"},
|
||||
"class": {"type": "string"},
|
||||
"level": {"type": "number"},
|
||||
},
|
||||
"required": ["name", "class", "level"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"required": ["playerName"],
|
||||
}
|
||||
wow_gamer1 = {
|
||||
"playerName": "Pixel",
|
||||
"discordId": "sseagull_caw",
|
||||
"playerAvailabilities": [
|
||||
{"day": "Monday", "time": "20:00", "timeZone": "America/New_York"},
|
||||
{"day": "Wednesday", "time": "20:00", "timeZone": "America/New_York"},
|
||||
{"day": "Friday", "time": "20:00", "timeZone": "America/New_York"},
|
||||
],
|
||||
"playerRaids": [{"name": "Molten Core"}, {"name": "Blackwing Lair"}],
|
||||
"characters": [
|
||||
{"name": "Pixelwar", "class": "Warrior", "level": 60},
|
||||
{"name": "Pixelmage", "class": "Mage", "level": 60},
|
||||
],
|
||||
}
|
||||
wow_gamer2 = {
|
||||
"playerName": "Zman",
|
||||
"discordId": "zmanplex",
|
||||
"playerAvailabilities": [
|
||||
{"day": "Monday", "time": "20:30", "timeZone": "America/Chicago"},
|
||||
{"day": "Wednesday", "time": "20:30", "timeZone": "America/Chicago"},
|
||||
{"day": "Friday", "time": "20:30", "timeZone": "America/Chicago"},
|
||||
],
|
||||
"playerRaids": [{"name": "Naxxramas"}, {"name": "Blackwing Lair"}],
|
||||
"characters": [
|
||||
{"name": "Zmanlock", "class": "Warlock", "level": 60},
|
||||
{"name": "Zmanhunt", "class": "Hunter", "level": 60},
|
||||
],
|
||||
}
|
||||
|
||||
csgo_epic_nerd_schema = {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"playerName": {"type": "string"},
|
||||
"playerDiscordId": {"type": "string"},
|
||||
"playerRank": {"type": "string"},
|
||||
"playerFavoriteMaps": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
},
|
||||
"playerFavoriteWeapons": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
},
|
||||
"playerAvailabilities": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"day": {"type": "string"},
|
||||
"time": {"type": "string"},
|
||||
"timeZone": {"type": "string"},
|
||||
},
|
||||
"required": ["day", "time", "timeZone"],
|
||||
},
|
||||
},
|
||||
},
|
||||
"required": ["playerName"],
|
||||
}
|
||||
csgo_epic_nerd1 = {
|
||||
"playerName": "Skip",
|
||||
"discordId": "tenpull",
|
||||
"playerRank": "Global Elite",
|
||||
"playerFavoriteMaps": ["Dust 2", "Mirage"],
|
||||
"playerFavoriteWeapons": ["AWP", "AK-47"],
|
||||
"playerAvailabilities": [
|
||||
{"day": "Monday", "time": "20:00", "timeZone": "America/New_York"},
|
||||
{"day": "Wednesday", "time": "20:00", "timeZone": "America/New_York"},
|
||||
{"day": "Friday", "time": "20:00", "timeZone": "America/New_York"},
|
||||
],
|
||||
}
|
||||
|
||||
def populate_valorant_profiles():
|
||||
valorant_profiles = [{"player": "Skip", "rank": "Diamond"}]
|
||||
for profile in valorant_profiles:
|
||||
p = ValorantProfile.objects.get_or_create(
|
||||
player_game_profile=PlayerGameProfile.objects.get(
|
||||
player=Player.objects.get(name=profile["player"]),
|
||||
game=Game.objects.get(name="Valorant"),
|
||||
),
|
||||
rank=profile["rank"],
|
||||
)[0]
|
||||
# get or create schema
|
||||
s = GuildGameDataSchema.objects.get_or_create(
|
||||
game=Game.objects.get(name="World of Warcraft"),
|
||||
guild=Guild.objects.get(name="Gamers"),
|
||||
schema=wow_gamer_schema,
|
||||
)[0]
|
||||
|
||||
# get or create player game data
|
||||
p1 = PlayerGameData.objects.get_or_create(
|
||||
player=Player.objects.get(name=wow_gamer1["playerName"]),
|
||||
game=Game.objects.get(name="World of Warcraft"),
|
||||
data=wow_gamer1,
|
||||
)[0]
|
||||
p2 = PlayerGameData.objects.get_or_create(
|
||||
player=Player.objects.get(name=wow_gamer2["playerName"]),
|
||||
game=Game.objects.get(name="World of Warcraft"),
|
||||
data=wow_gamer2,
|
||||
)[0]
|
||||
|
||||
# get or create schema
|
||||
s = GuildGameDataSchema.objects.get_or_create(
|
||||
game=Game.objects.get(name="Counter Strike: Global Offensive"),
|
||||
guild=Guild.objects.get(name="Epic Nerds"),
|
||||
schema=csgo_epic_nerd_schema,
|
||||
)[0]
|
||||
|
||||
# get or create player game data
|
||||
p1 = PlayerGameData.objects.get_or_create(
|
||||
player=Player.objects.get(name=csgo_epic_nerd1["playerName"]),
|
||||
game=Game.objects.get(name="Counter Strike: Global Offensive"),
|
||||
data=csgo_epic_nerd1,
|
||||
)[0]
|
||||
|
||||
|
||||
def populate():
|
||||
@ -95,9 +218,9 @@ def populate():
|
||||
populate_games()
|
||||
populate_guilds()
|
||||
populate_players()
|
||||
populate_player_game_profiles()
|
||||
populate_wow_profiles()
|
||||
populate_valorant_profiles()
|
||||
populate_player_guilds()
|
||||
populate_wow_classes()
|
||||
populate_guild_game_data_schema()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
Binary file not shown.
@ -0,0 +1,75 @@
|
||||
# Generated by Django 4.2.7 on 2023-12-05 14:47
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('server', '0003_remove_player_guild_playerguild'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='GuildGameDataSchema',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('schema', models.JSONField()),
|
||||
('game', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='schemas', to='server.game')),
|
||||
('guild', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='schemas', to='server.guild')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Guild Game Data Schema',
|
||||
'verbose_name_plural': 'Guild Game Data Schemas',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='PlayerGameData',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('creation_date', models.DateTimeField(auto_now_add=True, verbose_name='date created')),
|
||||
('data', models.JSONField()),
|
||||
('game', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='player_profiles', to='server.game')),
|
||||
('player', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='game_profiles', to='server.player')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Player Game Data',
|
||||
'verbose_name_plural': 'Player Game Data',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='WowClasses',
|
||||
fields=[
|
||||
('id', models.AutoField(primary_key=True, serialize=False)),
|
||||
('name', models.CharField(max_length=200)),
|
||||
('creation_date', models.DateTimeField(auto_now_add=True, verbose_name='date created')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'WoW Class',
|
||||
'verbose_name_plural': 'WoW Classes',
|
||||
},
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='valorantprofile',
|
||||
name='player_game_profile',
|
||||
),
|
||||
migrations.RemoveField(
|
||||
model_name='wowprofile',
|
||||
name='player_game_profile',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='playerguild',
|
||||
name='role',
|
||||
field=models.CharField(default='member', max_length=200),
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='PlayerGameProfile',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='ValorantProfile',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='WowProfile',
|
||||
),
|
||||
]
|
@ -5,6 +5,7 @@ class Guild(models.Model):
|
||||
"""
|
||||
This model is used to store the guild data.
|
||||
"""
|
||||
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=200)
|
||||
tag = models.CharField(max_length=10)
|
||||
@ -22,6 +23,7 @@ class Player(models.Model):
|
||||
"""
|
||||
This model is used to store the player data.
|
||||
"""
|
||||
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=200)
|
||||
creation_date = models.DateTimeField("date created", auto_now_add=True)
|
||||
@ -38,10 +40,13 @@ class PlayerGuild(models.Model):
|
||||
"""
|
||||
This model is used to store the player's guild data.
|
||||
"""
|
||||
|
||||
id = models.AutoField(primary_key=True)
|
||||
player = models.ForeignKey(Player, on_delete=models.CASCADE, related_name="guilds")
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE, related_name="players")
|
||||
role = models.CharField(max_length=200) # admin, officer, member, etc. eventually tie to permissions and account stuff
|
||||
role = models.CharField(
|
||||
max_length=200, default="member"
|
||||
) # admin, officer, member, etc. eventually tie to permissions and account stuff
|
||||
creation_date = models.DateTimeField("date created", auto_now_add=True)
|
||||
|
||||
def __str__(self):
|
||||
@ -56,6 +61,7 @@ class Game(models.Model):
|
||||
"""
|
||||
This model is used to store the game data.
|
||||
"""
|
||||
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=200)
|
||||
creation_date = models.DateTimeField("date created", auto_now_add=True)
|
||||
@ -74,6 +80,7 @@ class PlayerGameData(models.Model):
|
||||
Anything can be stored in the data field, but it will
|
||||
be validated against the schema before being stored.
|
||||
"""
|
||||
|
||||
id = models.AutoField(primary_key=True)
|
||||
player = models.ForeignKey(
|
||||
Player, on_delete=models.CASCADE, related_name="game_profiles"
|
||||
@ -100,13 +107,10 @@ class GuildGameDataSchema(models.Model):
|
||||
|
||||
Player Game Data will be validated against this schema.
|
||||
"""
|
||||
|
||||
id = models.AutoField(primary_key=True)
|
||||
guild = models.ForeignKey(
|
||||
Guild, on_delete=models.CASCADE, related_name="schemas"
|
||||
)
|
||||
game = models.ForeignKey(
|
||||
Game, on_delete=models.CASCADE, related_name="schemas"
|
||||
)
|
||||
guild = models.ForeignKey(Guild, on_delete=models.CASCADE, related_name="schemas")
|
||||
game = models.ForeignKey(Game, on_delete=models.CASCADE, related_name="schemas")
|
||||
schema = models.JSONField()
|
||||
|
||||
def __str__(self):
|
||||
@ -122,6 +126,7 @@ class WowClasses(models.Model):
|
||||
Example of a model that could be used to pre-populate
|
||||
dropdowns in the UI.
|
||||
"""
|
||||
|
||||
id = models.AutoField(primary_key=True)
|
||||
name = models.CharField(max_length=200)
|
||||
creation_date = models.DateTimeField("date created", auto_now_add=True)
|
||||
|
@ -1,3 +1,5 @@
|
||||
from jsonschema import validate
|
||||
from jsonschema.exceptions import ValidationError
|
||||
from rest_framework import serializers
|
||||
from .models import (
|
||||
Guild,
|
||||
@ -39,11 +41,21 @@ class PlayerGameDataSerializer(serializers.ModelSerializer):
|
||||
|
||||
def validate_data(self, value):
|
||||
game_id = self.initial_data["game"]
|
||||
# pull schema from guildgameschema
|
||||
schema = GuildGameDataSchema.objects.get(game=game_id)
|
||||
# validate data against schema
|
||||
# if valid, return value
|
||||
# if not valid, raise serializers.ValidationError("Invalid data")
|
||||
try:
|
||||
schema_obj = GuildGameDataSchema.objects.get(
|
||||
game=game_id, guild=self.initial_data["guild"]
|
||||
)
|
||||
schema = schema_obj.schema
|
||||
|
||||
validate(value, schema)
|
||||
|
||||
except GuildGameDataSchema.DoesNotExist:
|
||||
raise serializers.ValidationError(
|
||||
"Schema does not exist for this guild and game"
|
||||
)
|
||||
except ValidationError as e:
|
||||
raise serializers.ValidationError(e.message)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
|
@ -53,6 +53,7 @@ INSTALLED_APPS = [
|
||||
"rest_framework",
|
||||
"server",
|
||||
"corsheaders",
|
||||
"drf_yasg",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -1,26 +1,56 @@
|
||||
from django.urls import path, include
|
||||
from django.urls import path, include, re_path
|
||||
from django.contrib import admin
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from rest_framework import permissions
|
||||
from drf_yasg.views import get_schema_view
|
||||
from drf_yasg import openapi
|
||||
from .views import (
|
||||
GameViewSet,
|
||||
GuildViewSet,
|
||||
PlayerViewSet,
|
||||
PlayerGameProfileViewSet,
|
||||
WowProfileViewSet,
|
||||
ValorantProfileViewSet,
|
||||
hello_world,
|
||||
PlayerGameDataViewSet,
|
||||
GuildGameDataSchemaViewSet,
|
||||
PlayerGuildViewSet,
|
||||
WowClassesViewSet,
|
||||
)
|
||||
|
||||
router = DefaultRouter()
|
||||
router.register(r"games", GameViewSet)
|
||||
router.register(r"guilds", GuildViewSet)
|
||||
router.register(r"players", PlayerViewSet)
|
||||
router.register(r"player-game-profiles", PlayerGameProfileViewSet)
|
||||
router.register(r"wow-profiles", WowProfileViewSet)
|
||||
router.register(r"valorant-profiles", ValorantProfileViewSet)
|
||||
router.register(r"playergamedata", PlayerGameDataViewSet)
|
||||
router.register(r"guildgamedataschema", GuildGameDataSchemaViewSet)
|
||||
router.register(r"playerguild", PlayerGuildViewSet)
|
||||
router.register(r"wowclasses", WowClassesViewSet)
|
||||
|
||||
schema_view = get_schema_view(
|
||||
openapi.Info(
|
||||
title="Guild Data API",
|
||||
default_version="v1",
|
||||
description="API for Guild Data",
|
||||
terms_of_service="https://www.google.com/policies/terms/",
|
||||
contact=openapi.Contact(email="yourmom@lole.com"),
|
||||
license=openapi.License(name="License"),
|
||||
),
|
||||
public=True,
|
||||
permission_classes=(permissions.AllowAny,),
|
||||
)
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
path("", hello_world, name="index"),
|
||||
path("", include(router.urls)),
|
||||
path("admin/", admin.site.urls),
|
||||
path("api/", include(router.urls)),
|
||||
# Swagger
|
||||
re_path(
|
||||
r"^swagger(?P<format>\.json|\.yaml)$",
|
||||
schema_view.without_ui(cache_timeout=0),
|
||||
name="schema-json",
|
||||
),
|
||||
re_path(
|
||||
r"^swagger/$",
|
||||
schema_view.with_ui("swagger", cache_timeout=0),
|
||||
name="schema-swagger-ui",
|
||||
),
|
||||
]
|
||||
|
@ -4,19 +4,19 @@ from .models import (
|
||||
Game,
|
||||
Guild,
|
||||
Player,
|
||||
PlayerGameProfile,
|
||||
WowProfile,
|
||||
ValorantProfile,
|
||||
PlayerGuild,
|
||||
PlayerGameData,
|
||||
GuildGameDataSchema,
|
||||
WowClasses,
|
||||
)
|
||||
from .serializers import (
|
||||
GameSerializer,
|
||||
GuildSerializer,
|
||||
PlayerSerializer,
|
||||
PlayerGameProfileSerializer,
|
||||
WowProfileSerializer,
|
||||
ValorantProfileSerializer,
|
||||
PlayerGuildSerializer,
|
||||
PlayerGameDataSerializer,
|
||||
GuildGameDataSchemaSerializer,
|
||||
WowClassesSerializer,
|
||||
)
|
||||
|
||||
|
||||
@ -39,21 +39,21 @@ class PlayerViewSet(viewsets.ModelViewSet):
|
||||
serializer_class = PlayerSerializer
|
||||
|
||||
|
||||
class PlayerGameProfileViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlayerGameProfile.objects.all()
|
||||
serializer_class = PlayerGameProfileSerializer
|
||||
class PlayerGameDataViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlayerGameData.objects.all()
|
||||
serializer_class = PlayerGameDataSerializer
|
||||
|
||||
|
||||
class WowProfileViewSet(viewsets.ModelViewSet):
|
||||
queryset = WowProfile.objects.all()
|
||||
serializer_class = WowProfileSerializer
|
||||
|
||||
|
||||
class ValorantProfileViewSet(viewsets.ModelViewSet):
|
||||
queryset = ValorantProfile.objects.all()
|
||||
serializer_class = ValorantProfileSerializer
|
||||
class GuildGameDataSchemaViewSet(viewsets.ModelViewSet):
|
||||
queryset = GuildGameDataSchema.objects.all()
|
||||
serializer_class = GuildGameDataSchemaSerializer
|
||||
|
||||
|
||||
class PlayerGuildViewSet(viewsets.ModelViewSet):
|
||||
queryset = PlayerGuild.objects.all()
|
||||
serializer_class = PlayerGuildSerializer
|
||||
|
||||
|
||||
class WowClassesViewSet(viewsets.ModelViewSet):
|
||||
queryset = WowClasses.objects.all()
|
||||
serializer_class = WowClassesSerializer
|
||||
|
Loading…
x
Reference in New Issue
Block a user