from sys import api_version from rest_framework.decorators import api_view from datetime import datetime import random from shutil import register_unpack_format import string from uuid import uuid4 from django.shortcuts import render import pytz from rest_framework.response import Response from rest_framework.views import APIView from rest_framework import status from .models import Room, Parcours, TempCorrection from .serializers import RoomSerializer, ParcoursSerializer from django.contrib.sessions.models import Session from api.Generateur import Generateur from exercices.models import Exercice from exercices.serializers import ExerciceSerializer from channels.layers import get_channel_layer from asgiref.sync import async_to_sync from .utils import getNow # Create your views here. class RoomAPI(APIView): def post(self, request, format=None): name = request.data.get('name') nick = request.data.get('nick') code = ''.join( random.choices(string.ascii_uppercase, k=6)) clientId = str(uuid4()) room = Room(name=name, owner={'name': nick, 'code': code, "clientId": clientId}, participants=[{'nick': nick, 'owner': True, 'code': code, "clientId": clientId}] ) room.save() return Response({"data": {'id_code': room.id_code, "clientId": clientId, "code": code}}, status=status.HTTP_200_OK) def get(self, request, format=None): code = request.GET.get('code') room = None try: room = Room.objects.filter(id_code=code)[0] except IndexError: return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND) clientId = request.GET.get('clientId') participants = room.participants if clientId not in list(map(lambda p: p['clientId'], participants)): return Response({'error': 'Non autorisé', 'code': '401'}, status=status.HTTP_401_UNAUTHORIZED) admin = False if clientId == room.owner['clientId']: admin = True # "challenger": list(map(lambda c: {'nick': p['nick'], "validate": c['validate'], 'exos': list(map(lambda e: {'endAt': e['endAt'], 'note': e['note']}, p['exos']))}, p.challenger)) return Response({"data": {"room": {**RoomSerializer(room).data, "waiters": room.waiters if admin == True else [], "participants": list(map(lambda p: {'nick': p['nick'], 'owner': p['owner'], 'online': p['online'], "code": p['code'] if admin == True else ""}, participants)), 'parcours': list(map(lambda p: {**ParcoursSerializer(p).data}, room.parcours_set.all()))}}}, status=status.HTTP_200_OK) def delete(self, request, format=None): code = request.data.get('code') room = Room.objects.filter(id_code=code)[0] room.delete() return Response({"data": ''}, status=status.HTTP_200_OK) def patch(self, request, format=None): code = request.data.get('pin') nick = request.data.get('nick') room = None try: room = Room.objects.filter(id_code=code)[0] except IndexError: return Response({'error': 'No room'}, status=status.HTTP_502_BAD_GATEWAY) # print(room) if 'roomsJoined' not in request.session: request.session['roomsJoined'] = [] elif 'roomsJoined' in request.session: request.session['roomsJoined'] = list( filter(lambda s: len(Room.objects.filter(id_code=s['id_code'])) != 0, request.session['roomsJoined'])) if room.id_code not in list(map(lambda r: r['id_code'], request.session['roomsJoined'])): code = ''.join( random.choices(string.ascii_uppercase, k=6)) while code in list(map(lambda p: p['code'], room.participants)): code = ''.join( random.choices(string.ascii_uppercase, k=6)) room.participants = [*room.participants, { 'nick': nick, 'owner': False, 'code': code }] try: request.session['roomsJoined'] = [*request.session['roomsJoined'], {'id_code': room.id_code, 'nick': nick, 'owner': False, 'code': code}] except: request.session['roomsJoined'] = [{'id_code': room.id_code, 'nick': nick, 'owner': False, 'code': code}] room.save() return Response({"data": {'id_code': room.id_code}}, status=status.HTTP_200_OK) @api_view(['GET']) def RoomExist(request, id_code): if Room.objects.filter(id_code=id_code).count() > 0: return Response({'data': {"id_code": id_code}}, status=status.HTTP_200_OK) else: return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND) @api_view(['GET']) def getCorrectionInfo(request): parcours_id = request.query_params['parcours_id'] user_code = request.query_params['user_code'] correct_code = request.query_params['correct_code'] parcours = Parcours.objects.filter(id_code=parcours_id) if len(parcours) == 0: return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND) parcours = parcours[0] challenger = list( filter(lambda p: p['code'] == user_code, parcours.challenger)) if(len(challenger) == 0): return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED) trys = challenger[0]['exos'] challenge = list(filter(lambda c: c['code'] == correct_code, trys)) if(len(challenge) == 0): return Response({'error': 'Not found'}, status=status.HTTP_404_NOT_FOUND) challenge = challenge[0] return Response({'data': {**challenge, "parcours_id": parcours.id_code, 'user_code': user_code}}, status=status.HTTP_200_OK) class ChallengeAPI(APIView): def get(self, request, format=None): id_code = request.GET.get('code') user_code = request.GET.get('user_code') parcours = Parcours.objects.filter(id_code=id_code) if len(parcours) == 0: return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND) parcours = parcours[0] room = parcours.room participants = list( filter(lambda p: p['code'] == user_code, room.participants)) if(len(participants) == 0): return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED) exos = parcours.exercices exos = list(map(lambda e: Generateur(Exercice.objects.filter( id_code=e['id_code'])[0].exo_model.name, e['number'], 'web'), exos)) def parseCorrection(calcul): """Fait en sorte de séparer la correction présente dans le calcul""" calculEx = calcul['calcul'].replace('[', ' [').replace(']', '] ') splitted = calculEx.split() if len(list(filter(lambda e: e.startswith("[") and e.endswith(']'), splitted))) == 0: splitted.append('[]') inputs = [] for i in range(len(splitted)): c = splitted[i] if c.startswith('[') and c.endswith(']'): corr = c.replace('[', '').replace(']', '') splitted[i] = f'[{len(inputs)}]' inputs.append( {'order': len(inputs), 'correction': corr, 'value': ""}) calculEx = ' '.join(splitted) return {'calcul': calculEx, 'inputs': inputs} exosWcorrection = [] for i in range(len(exos)): ex = exos[i] tempsExs = list(map(parseCorrection, ex)) tmp = {'order': i, 'exos': [{'order': ind, **e} for ind, e in enumerate(tempsExs)]} exosWcorrection.append(tmp) #exos[i] = {'order': i, 'exos': list(map(lambda e, id: {'order': id,'calcul': e['calcul'], 'inputs': list(map(lambda i :{'order': i['order'],'value':i['value']}, e['inputs']))}, tempsExs))} #exos[i] = list(map(lambda e: {'calcul': e['calcul'], 'inputs': list(map(lambda i :{'order': i['order'],'value':i['value']}, e['inputs']))}, tempsExs)) exos[i] = {'order': i, 'exos': [{'order': ind, 'calcul': e['calcul'], 'inputs': [ {'value': inp['value'], 'order': inp['order'], 'correction': ""} for inp in e['inputs']]} for ind, e in enumerate(tempsExs)]} tempCorr = TempCorrection(correction=exosWcorrection) tempCorr.save() return Response({"data": {**ParcoursSerializer(parcours).data, "exos": exos, 'correctId': tempCorr.id_code}}, status=status.HTTP_200_OK) def post(self, request, format=None): exos = request.data.get('exos') parcours_id = request.data.get('id_code') user_code = request.data.get('user_code') correct_code = request.data.get('correct_code') parcours = Parcours.objects.filter(id_code=parcours_id) if len(parcours) == 0: return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND) parcours = parcours[0] room = parcours.room corrections = TempCorrection.objects.filter(id_code=correct_code) if len(corrections) == 0: return Response({'error': 'Correction indisponible !'}, status=status.HTTP_404_NOT_FOUND) correctionDB = corrections[0] participants = list( filter(lambda p: p['code'] == user_code, room.participants)) if(len(participants) == 0): return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED) # Corriger selon la correction les exos envoyé dans exos.exos student_answer = exos['result'] correction = correctionDB.correction inpppp = 0 def corrige(ans): correctionExos = list( filter(lambda c: c['order'] == ans['order'], correction))[0] corrigedList = [] for a in ans['exos']: #a = ans['exos'][i] exoCorrect = list( filter(lambda c: c['order'] == a['order'], correctionExos['exos']))[0] correctInputs = exoCorrect['inputs'] print('correcti', correctInputs) studentsInput = sorted(a['inputs'], key=lambda i: i.get('order')) print('correctiinnnn\n\n', studentsInput) corrigedInputs = [{**inp, "value": studentsInput[inp['order']]['value'], "isCorrect": (str(studentsInput[inp['order']]['value']) == str( inp['correction'])) if inp['correction'] != "" else None} for inp in correctInputs] corrigedList.append({**a, 'inputs': corrigedInputs}) return {**ans, "exos": corrigedList} corriged = list((map(corrige, student_answer))) #l6 = uniquement les isCorrect l2 = [exs['exos'] for exs in corriged] l4 = [ex['inputs'] for exs in l2 for ex in exs] l5 = [ex for exs in l4 for ex in exs] l6 = [e['isCorrect'] for e in l5] note = { "total": len(l6), "value": l6.count(True), "isTrust": l6.count(None) == 0 } adding_challenger = Parcours.objects.challenge( parcours_id, user_code, {"result": corriged, "timer": exos['timer'], "note": note}) correctionDB.delete() channel_layer = get_channel_layer() async_to_sync(channel_layer.group_send)(f"owner__{room.id_code}", { 'type': "challenge_parcours", 'id_code': parcours_id, "participant": participants[0], "validate": adding_challenger['validate'], 'exos': {'note': note, 'endAt': getNow(), "timer": exos['timer']}}) return Response({"data": {"exos": corriged, "note": note}}, status=status.HTTP_200_OK) def put(self, request, format=None): parcours_id = request.data.get('parcours_id') result = request.data.get('result') challenge_code = request.data.get('challenge_code') clientId = request.data.get('clientId') user_code = request.data.get('user_code') note = request.data.get('note') print(f'PARCOURS: {parcours_id}') parcours = Parcours.objects.filter(id_code=parcours_id) if len(parcours) == 0: return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND) parcours = parcours[0] room = parcours.room print(f'CLIENTID COMPARE: {room.owner["clientId"]}\n{clientId}') if room.owner['clientId'] != clientId: return Response({'error': 'Pas les droits'}, status=status.HTTP_401_UNAUTHORIZED) challenger = list( filter(lambda p: p['code'] == user_code, parcours.challenger)) if(len(challenger) == 0): return Response({'error': 'Not found'}, status=status.HTTP_401_UNAUTHORIZED) trys = challenger[0]['exos'] challenge = list(filter(lambda c: c['code'] == challenge_code, trys)) if(len(challenge) == 0): return Response({'error': 'Not found'}, status=status.HTTP_404_NOT_FOUND) challenge = challenge[0] date = getNow() condition = parcours.success_condition parcours.challenger = [ *list(filter(lambda p: p['code'] != user_code, parcours.challenger)), {**challenger[0], "validate": date if note['value'] * 20 / note['total'] >= condition else False ,"exos": [*list(filter(lambda c: c['code'] != challenge_code, trys)), {**challenge, "result": result, "note": note}]}] parcours.save() return Response({"data": {}}, status=status.HTTP_200_OK) class ParcoursAPI(APIView): def delete(self, request, format=None): id_code = request.data.get('id_code') code = request.data.get('code') print(f'id_code={id_code};code={code}') parcours = Parcours.objects.filter(id_code=id_code) if len(parcours) == 0: return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND) parcours = parcours[0] room = parcours.room if room.owner['code'] != code: return Response({'error': 'Pas owner'}, status=status.HTTP_401_UNAUTHORIZED) channel_layer = get_channel_layer() async_to_sync(channel_layer.group_send)(parcours.room.id_code, {'type': 'delete_parcours', "id_code": id_code}) parcours.delete() return Response({'data': {'id_code': id_code}}, status=status.HTTP_200_OK) def post(self, request, format=None): name = request.data.get('name') # ...futur: pour admin quand j'aurais fait la création de room "clean" code = request.data.get('code') room_code = request.data.get('room_code') exos = request.data.get('exos') timer = request.data.get('timer') # print(exos, name, room_code) try: room = Room.objects.filter(id_code=room_code)[0] except: return Response({'error': ""}, status=status.HTTP_404_NOT_FOUND) if room.owner['code'] != code: return Response({'error': ''}, status=status.HTTP_401_UNAUTHORIZED) parcours = Parcours(name=name, room=room, timer=timer, exercices=exos) parcours.save() layer = get_channel_layer() async_to_sync(layer.group_send)(room_code, { 'type': 'new_parcours', 'parcours': ParcoursSerializer(parcours).data}) layer = get_channel_layer() return Response({"data": {'id_code': parcours.id_code}}, status=status.HTTP_200_OK) def put(self, request, format=None): name = request.data.get('name') # ...futur: pour admin quand j'aurais fait la création de room "clean" code = request.data.get('code') id_code = request.data.get('id_code') exos = request.data.get('exos') timer = request.data.get('timer') # print(exos, name, room_code) try: parcours = Parcours.objects.filter(id_code=id_code)[0] except: return Response({'error': ""}, status=status.HTTP_404_NOT_FOUND) room = parcours.room if code != room.owner['code']: return Response({'error': ''}, status=status.HTTP_401_UNAUTHORIZED) parcours.challenger = [] parcours.name = name parcours.timer = timer parcours.exercices = exos parcours.save() layer = get_channel_layer() async_to_sync(layer.group_send)(room.id_code, { 'type': 'edit_parcours', 'parcours': ParcoursSerializer(parcours).data}) layer = get_channel_layer() return Response({"data": {'id_code': parcours.id_code}}, status=status.HTTP_200_OK) def get(self, request, format=None): id_code = request.GET.get('code') user_code = request.GET.get('user_code') parcours = Parcours.objects.filter(id_code=id_code) if len(parcours) == 0: return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND) parcours = parcours[0] room = parcours.room participants = list( filter(lambda p: p['code'] == user_code, room.participants)) if(len(participants) == 0): return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED) exos = parcours.exercices exos = list(map(lambda e: ExerciceSerializer(Exercice.objects.filter( id_code=e['id_code'])[0]).data, exos)) challenger_data = parcours.challenger if user_code == parcours.room.owner['code']: return Response({"data": {**ParcoursSerializer(parcours).data, "challenger": list(map(lambda r: {**r, 'exos': list(map(lambda e: {'endAt': e['endAt'], 'note': e['note'], "timer": e['timer'], "code": e['code']}, r['exos']))}, parcours.challenger)), "exercices": exos}}, status=status.HTTP_200_OK) else: challenger_filtered = list( filter(lambda c: c['code'] == user_code, challenger_data)) if parcours.room.public_result == False: return Response({"data": {**ParcoursSerializer(parcours).data, "challenger": list(map(lambda r: {**r, 'exos': list(map(lambda e: {'endAt': e['endAt'], 'note': e['note'], "code": e['code'], "timer": e['timer']}, r['exos']))}, challenger_filtered)), "exercices": exos}}, status=status.HTTP_200_OK) else: return Response({"data": {**ParcoursSerializer(parcours).data, "challenger": list(map(lambda r: {**r, "code": "", 'exos': list(map(lambda e: {'endAt': e['endAt'], "code": e['code'], 'note': e['note'], "timer": e['timer']}, r['exos']))}, parcours.challenger)), "exercices": exos}}, status=status.HTTP_200_OK)