diff --git a/EscapeGame/settings.py b/EscapeGame/settings.py index 286932a..ee648a0 100644 --- a/EscapeGame/settings.py +++ b/EscapeGame/settings.py @@ -11,6 +11,9 @@ https://docs.djangoproject.com/en/4.1/ref/settings/ """ from pathlib import Path +import os + +from django.contrib.messages import constants as messages # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -50,12 +53,14 @@ MIDDLEWARE = [ 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] +SESSION_ENGINE = 'django.contrib.sessions.backends.file' + ROOT_URLCONF = 'EscapeGame.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': ['EscapeGame/templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -104,21 +109,36 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/4.1/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = 'fr-FR' -TIME_ZONE = 'UTC' +TIME_ZONE = 'Europe/Paris' USE_I18N = True -USE_TZ = True +USE_TZ = False # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/4.1/howto/static-files/ STATIC_URL = 'static/' +STATIC_ROOT = os.path.join(BASE_DIR, 'static') + +STATICFILES_DIRS = [ + BASE_DIR / "EscapeGame/static" +] # Default primary key field type # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' + +CSRF_TRUSTED_ORIGINS=['https://*.christophe-scaya.fr'] + +MESSAGE_TAGS = { + messages.DEBUG: 'alert-secondary', + messages.INFO: 'alert-info', + messages.SUCCESS: 'alert-success', + messages.WARNING: 'alert-warning', + messages.ERROR: 'alert-danger', + } diff --git a/EscapeGame/urls.py b/EscapeGame/urls.py index 414805a..06a81d8 100644 --- a/EscapeGame/urls.py +++ b/EscapeGame/urls.py @@ -14,8 +14,9 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path +from django.urls import include, path urlpatterns = [ + path('', include('app.urls')), path('admin/', admin.site.urls), ] diff --git a/app/admin.py b/app/admin.py index 01de278..89e0c17 100644 --- a/app/admin.py +++ b/app/admin.py @@ -1,7 +1,8 @@ from django.contrib import admin -from .models import Zone, Distance +from .models import Zone, Distance, Equipe, Challenge admin.site.register(Zone) admin.site.register(Distance) - +admin.site.register(Equipe) +admin.site.register(Challenge) diff --git a/app/apps.py b/app/apps.py index ed327d2..efdbf2e 100644 --- a/app/apps.py +++ b/app/apps.py @@ -1,6 +1,6 @@ from django.apps import AppConfig - class AppConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'app' + nb_challenges = 5 diff --git a/app/models.py b/app/models.py index b4482ea..e6e9627 100644 --- a/app/models.py +++ b/app/models.py @@ -2,6 +2,9 @@ import random from django.db import models +def random_string(): + return str(random.randint(1000, 9999)) + class Zone(models.Model): ETATS = ( ('L', 'Libre'), @@ -10,7 +13,8 @@ class Zone(models.Model): ) nom = models.CharField(max_length=50) etat = models.CharField(max_length=1, choices=ETATS, default = 'L') - code = models.IntegerField(default = random.randint(1000, 9999)) + code = models.IntegerField(default = random_string, unique=True) + description = models.TextField(default = '') def __str__(self): return self.nom+" : "+self.get_etat_display()+" ("+str(self.code)+")" @@ -22,3 +26,21 @@ class Distance(models.Model): unique_together = (('zone1','zone2'),) def __str__(self): return self.zone1.nom+" -> "+self.zone2.nom+" : "+str(self.distance) + +class Equipe(models.Model): + nom = models.CharField(max_length=50) + code = models.IntegerField(default = random_string, unique=True) + start_time = models.TimeField(null=True, blank=True) + end_time = models.TimeField(null=True, blank=True) + def __str__(self): + return self.nom+" ("+str(self.code)+")" + +class Challenge(models.Model): + equipe = models.ForeignKey(Equipe, on_delete=models.CASCADE) + zone = models.ForeignKey(Zone, on_delete=models.CASCADE) + code = models.IntegerField(default = random_string, unique=True)#code pour valider le challenge en cours + rank = models.IntegerField(default = 1)#rang du challenge dans la liste + start_time = models.TimeField(null=True, blank=True) + end_time = models.TimeField(null=True, blank=True) + def __str__(self): + return self.equipe.nom+" ("+str(self.code)+") -> rang : "+str(self.rank) diff --git a/app/views.py b/app/views.py index 91ea44a..9da5048 100644 --- a/app/views.py +++ b/app/views.py @@ -1,3 +1,128 @@ -from django.shortcuts import render +import random +from django.db.models import Max; +from django.http import HttpResponse +from django.template import loader +from django.contrib import admin +from django.conf import settings +from django.shortcuts import redirect +from django.contrib import messages +from .forms import LoginForm +from .models import * +from django.apps import apps +from .functions import * -# Create your views here. +""" +Fonction displayZone +Cette vue permet de charger les données d'une zone +Si zone_id n'est pas fourni, cela affiche la première vue du jeu qui démarre le chrono de l'équipe +et qui +""" +def displayZone(request, zone_id=None): + if 'equipe_code' not in request.session: + return redirect('app:setEquipe') + + equipe = Equipe.objects.get(code=request.session['equipe_code']) + template = loader.get_template('app/zone.html') + context = { + 'zone':None + } + challenge = getMaxChallenge(equipe) + + if zone_id is None: + messages.error(request, "Merci d'indiquer une zone à charger !") + else: + try: + zone = Zone.objects.filter(code=challenge.zone.code)[0] + if zone_id == zone.code: + startChallengeTime(challenge) + context = { + 'zone':zone, + 'title': "Bienvenue dans la zone "+zone.nom, + } + else: + messages.warning(request, "Mauvaise zone ! vous devez vous rendre dans la zone "+zone.nom) + except Zone.DoesNotExist: + messages.error(request, "Cette zone n'existe pas !") + + return HttpResponse(template.render(context, request)) + +""" +Fonction setEquipe +Fonction permettant d'enregistrer une équipe et de lui donner la prochaine zone de destination. +Lors de la première exécution, la fonction démarre le chrono de l'équipe. +""" +def setEquipe(request): + template = loader.get_template('app/setEquipe.html') + if 'equipe_code' not in request.session: + if request.method == 'POST': + form = LoginForm(request.POST) + if form.is_valid(): + equipe = Equipe.objects.get(code=int(form.cleaned_data['equipe'])) + request.session['equipe_code'] = equipe.code + request.session['equipe_nom'] = equipe.nom + + challenge = getMaxChallenge(equipe) + if challenge is None: + startEquipeTime(equipe) + challenge = createChallenge(equipe) + + context = { + 'zone': challenge.zone.nom, + 'equipe_nom': request.session['equipe_nom'], + } + else: + context = { + 'form': LoginForm(request.POST), + } + else: + context = { + 'form': LoginForm(), + } + else: + context = { + 'zone': getMaxChallenge(Equipe.objects.get(code=request.session['equipe_code'])).zone.nom, + 'equipe_nom': request.session['equipe_nom'], + } + return HttpResponse(template.render(context, request)) + +def dashboard(request): + if not request.user.is_authenticated & request.user.is_superuser: + return redirect("/admin/login/?next=/dashboard") + template = loader.get_template('app/dashboard.html') + liste_equipe = Equipe.objects.all() + context = { + 'liste_equipe': liste_equipe + } + return HttpResponse(template.render(context, request)) + +""" +Fonction createNewGame +Cette fonction efface les challenges présents en base pour en créer de nouveaux pour chacune des équipes +""" +def createNewGame(request): + + #On efface toutes les session existantes + request.session.flush() + + #On efface les challenges existants + Challenge.objects.all().delete() + + #On libère toutes les zones + liste_zone = Zone.objects.all() + for zone in liste_zone.iterator(): + zone.etat='L' + zone.save() + + liste_equipe = Equipe.objects.all() + for equipe in liste_equipe.iterator(): + equipe.start_time=None + equipe.end_time=None + equipe.save() + + #On vérifie que le nombre de zones soit au moins égal aun nombre d'équipe +1 + if len(liste_zone) < len(liste_equipe)+1: + messages.error(request, "Pas assez de zone pour créer un nouveau jeu") + else: + messages.info(request, 'Création du jeu OK.') + + return redirect('app:dashboard')