diff --git a/BH/settings.py b/BH/settings.py index a876ea9..53c5e7a 100644 --- a/BH/settings.py +++ b/BH/settings.py @@ -40,12 +40,14 @@ INSTALLED_APPS = [ 'crispy_forms', 'crispy_bootstrap4', 'blog.apps.BlogConfig', + 'api.apps.APIConfig', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'rest_framework', ] MIDDLEWARE = [ @@ -112,6 +114,13 @@ AUTH_PASSWORD_VALIDATORS = [ }, ] +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.BasicAuthentication', + 'rest_framework.authentication.SessionAuthentication', + ) +} + # Internationalization # https://docs.djangoproject.com/en/3.0/topics/i18n/ @@ -138,3 +147,8 @@ MEDIA_URL = '/media/' CRISPY_TEMPLATE_PACK = 'bootstrap4' LOGIN_REDIRECT_URL = 'News' LOGIN_URL = 'Login' + +# Default primary key field type +# https://docs.djangoproject.com/en/5.0/ref/settings/#default-auto-field + +DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' diff --git a/BH/urls.py b/BH/urls.py index ce5310a..f79c930 100644 --- a/BH/urls.py +++ b/BH/urls.py @@ -20,6 +20,7 @@ from django.urls import path, include urlpatterns = [ path('', include('blog.urls')), + path('api/', include('api.urls')), path('admin/', admin.site.urls), ] diff --git a/api/__init__.py b/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/api/admin.py b/api/admin.py new file mode 100644 index 0000000..bc78181 --- /dev/null +++ b/api/admin.py @@ -0,0 +1,9 @@ +from django.contrib import admin +from .models import * + + +# Register your models here. +admin.site.register(Province) +admin.site.register(AssaultTroop) +admin.site.register(Player) +admin.site.register(Server) \ No newline at end of file diff --git a/api/apps.py b/api/apps.py new file mode 100644 index 0000000..93127e4 --- /dev/null +++ b/api/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class APIConfig(AppConfig): + name = 'api' diff --git a/api/models.py b/api/models.py new file mode 100644 index 0000000..e8ed5c9 --- /dev/null +++ b/api/models.py @@ -0,0 +1,68 @@ +from django.db import models +from django.contrib.auth.models import User + +# Create your models here. +class Province(models.Model): + id = models.IntegerField(primary_key = True) + name = models.CharField(max_length = 100, blank = False) + faction = models.IntegerField() # 0 - Neutral, 1 - Allies, 2 - Axis + map = models.CharField(max_length=255) + mov_speed = models.IntegerField() + ats = models.JSONField(null=True) + + class Meta: + ordering = ['id'] + + def __str__(self): + return f"{self.name} - {self.faction}" + + +class AssaultTroop(models.Model): + id = models.IntegerField(primary_key = True) + name = models.CharField(max_length = 100, blank = False) + faction = models.IntegerField() # 0 - Neutral, 1 - Allies, 2 - Axis + type = models.IntegerField() + province = models.IntegerField() # Province ID (-1 for not deployed) + orders = models.JSONField(null=True) + owner = models.ForeignKey( + 'auth.User', + related_name='ats', + on_delete=models.CASCADE + ) + + class Meta: + ordering = ['id'] + + def __str__(self): + return f"{self.name} - {self.province},{self.faction}" + + + +class Player(models.Model): + id = models.IntegerField(primary_key = True) + name = models.CharField(max_length = 50, blank = False) + faction = models.IntegerField() + server = CharField(max_length = 20, blank = False) + + class Meta: + ordering = ['id'] + + def __str__(self): + return self.name + + + +class Server(models.Model): + id = IntegerField(primary_key = True) + players = IntegerField() # total current players + capacity = IntegerField() # max player capacity + region = CharField(max_length = 3, blank = False) # 3 letter abb. for region + address = CharField(max_length = 20, blank = False) + + class Meta: + ordering = ['id'] + + def __str__(self): + return f"{self.address} - {self.region}" + + diff --git a/api/serializers.py b/api/serializers.py new file mode 100644 index 0000000..400fa05 --- /dev/null +++ b/api/serializers.py @@ -0,0 +1,25 @@ +from rest_framework import serializers +from .models import * + +class ProvinceSerializer(serializers.ModelSerializer): + class Meta: + model = Province + fields = ['id', 'name', 'faction', 'map', 'mov_speed', 'ats'] + + +class AssaultTroopSerializer(serializers.ModelSerializer): + class Meta: + model = AssaultTroop + fields = ['id', 'name', 'faction', 'type', 'province', 'deployed', 'orders', 'owner'] + + +class PlayerSerializer(serializers.ModelSerializer): + class Meta: + model = Player + fields = ['id', 'name', 'faction', 'server'] + + +class ServerSerializer(serializers.ModelSerializer): + class Meta: + model = Server + fields = ['id', 'players', 'capacity', 'region', 'address'] diff --git a/api/templatetags/markdown_extras.py b/api/templatetags/markdown_extras.py new file mode 100644 index 0000000..b3b708c --- /dev/null +++ b/api/templatetags/markdown_extras.py @@ -0,0 +1,12 @@ +from django import template +from django.template.defaultfilters import stringfilter + +import markdown as md + + +register = template.Library() + +@register.filter() +@stringfilter +def markdown(value): + return md.markdown(value, extensions=['markdown.extensions.fenced_code']) \ No newline at end of file diff --git a/api/tests.py b/api/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/api/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/api/urls.py b/api/urls.py new file mode 100644 index 0000000..3ca7b29 --- /dev/null +++ b/api/urls.py @@ -0,0 +1,13 @@ +from django.urls import path +from .views import * + +urlpatterns = [ + path('provinces/', ProvincesView), + path('provinces//', ProvinceView), + path('assault_troops/', AssaultTroopsView), + path('assault_troops//', AssaultTroopView), + path('players/', PlayersView), + path('players//', PlayerView), + path('servers/', ServersView), + path('servers//', ServerView), +] diff --git a/api/views.py b/api/views.py new file mode 100644 index 0000000..174ec6c --- /dev/null +++ b/api/views.py @@ -0,0 +1,180 @@ +from django.shortcuts import render, HttpResponseRedirect, Http404 +from rest_framework.parsers import JSONParser +from django.http import HttpResponse, JsonResponse +from django.views.decorators.csrf import csrf_exempt +from .models import * +from .serializers import * + +# Create your views here. +@csrf_exempt +def ProvincesView(request): + + if request.method == 'GET': + items = Province.objects.all() + serializer = ProvinceSerializer(items, many = True) + return JsonResponse(serializer.data, safe = False) + + elif request.method == 'POST': + data = JSONParser().parse(request) + serializer = ProvinceSerializer(data = data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data,status = 201) + return JsonResponse(serializer.errors,status = 400) + + +@csrf_exempt +def AssaultTroopsView(request): + + if request.method == 'GET': + items = AssaultTroop.objects.all() + serializer = AssaultTroopSerializer(items, many = True) + return JsonResponse(serializer.data, safe = False) + + elif request.method == 'POST': + data = JSONParser().parse(request) + serializer = AssaultTroopSerializer(data = data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data,status = 201) + return JsonResponse(serializer.errors,status = 400) + + + +@csrf_exempt +def ProvinceView(request, nm): + try: + item = Province.objects.get(id = nm) + except Province.DoesNotExist: + raise Http404('Not found') + + if request.method == 'GET': + serializer = ProvinceSerializer(item) + return JsonResponse(serializer.data) + + if request.method == 'PUT': + data = JSONParser().parse(request) + serializer = ProvinceSerializer(item,data =data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data) + return JsonResponse(serializer.errors, status =400) + + if request.method == "DELETE": + item.delete() + return HttpResponse(status =204) + + +@csrf_exempt +def AssaultTroopView(request, nm): + try: + item = AssaultTroop.objects.get(id = nm) + except AssaultTroop.DoesNotExist: + raise Http404('Not found') + + if request.method == 'GET': + serializer = AssaultTroopSerializer(item) + return JsonResponse(serializer.data) + + if request.method == 'PUT': + data = JSONParser().parse(request) + serializer = AssaultTroopSerializer(item,data =data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data) + return JsonResponse(serializer.errors, status =400) + + if request.method == "DELETE": + item.delete() + return HttpResponse(status =204) + + +@csrf_exempt +def PlayersView(request): + + if request.method == 'GET': + items = Player.objects.all() + serializer = PlayerSerializer(items, many = True) + return JsonResponse(serializer.data, safe = False) + + elif request.method == 'POST': + data = JSONParser().parse(request) + serializer = PlayerSerializer(data = data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data,status = 201) + return JsonResponse(serializer.errors,status = 400) + + +@csrf_exempt +def ServersView(request): + + if request.method == 'GET': + items = Server.objects.all() + serializer = ServerSerializer(items, many = True) + return JsonResponse(serializer.data, safe = False) + + elif request.method == 'POST': + data = JSONParser().parse(request) + serializer = ServerSerializer(data = data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data,status = 201) + return JsonResponse(serializer.errors,status = 400) + + + +@csrf_exempt +def PlayerView(request, nm): + try: + item = Player.objects.get(id = nm) + except Player.DoesNotExist: + raise Http404('Not found') + + if request.method == 'GET': + serializer = PlayerSerializer(item) + return JsonResponse(serializer.data) + + if request.method == 'PUT': + data = JSONParser().parse(request) + serializer = PlayerSerializer(item,data =data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data) + return JsonResponse(serializer.errors, status =400) + + if request.method == "DELETE": + item.delete() + return HttpResponse(status =204) + + +@csrf_exempt +def ServerView(request, nm): + try: + item = Server.objects.get(id = nm) + except Server.DoesNotExist: + raise Http404('Not found') + + if request.method == 'GET': + serializer = ServerSerializer(item) + return JsonResponse(serializer.data) + + if request.method == 'PUT': + data = JSONParser().parse(request) + serializer = ServerSerializer(item,data =data) + + if serializer.is_valid(): + serializer.save() + return JsonResponse(serializer.data) + return JsonResponse(serializer.errors, status =400) + + if request.method == "DELETE": + item.delete() + return HttpResponse(status =204) \ No newline at end of file