ajout des room, plus qu'à test
This commit is contained in:
parent
035af2a3b7
commit
0e147e1a98
Binary file not shown.
|
@ -33,7 +33,6 @@ def Generateur(path, quantity, key, forcedCorrection = False):
|
|||
'web': False, 'correction': False} # les valeurs par défaut
|
||||
# Si l'utilisateur n'a pas entré une valeur, elle est définie à False
|
||||
result_object = {**default_object, **main_result}
|
||||
print(result_object)
|
||||
object_key = getObjectKey(result_object, key)
|
||||
correction_key = getCorrectionKey(result_object, key)
|
||||
|
||||
|
|
Binary file not shown.
|
@ -79,7 +79,7 @@ MIDDLEWARE = [
|
|||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||
]
|
||||
|
||||
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
|
||||
#SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
|
||||
|
||||
# CORS
|
||||
CORS_ALLOWED_ORIGINS = ['http://localhost:8000', 'http://141.136.42.178:8001', 'http://141.136.42.178:8002', 'http://141.136.42.178:80', 'http://lilandco42.com',
|
||||
|
@ -160,6 +160,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||
]
|
||||
|
||||
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/4.0/topics/i18n/
|
||||
|
||||
|
@ -212,6 +213,9 @@ ACCOUNT_AUTHENTICATION_METHOD = 'username'
|
|||
ACCOUNT_UNIQUE_EMAIL = True
|
||||
ACCOUNT_UNIQUE_USERNAME = True
|
||||
|
||||
OLD_PASSWORD_FIELD_ENABLED = False
|
||||
LOGOUT_ON_PASSWORD_CHANGE = False
|
||||
|
||||
|
||||
REST_FRAMEWORK = {
|
||||
'DATETIME_FORMAT': "%m/%d/%Y %I:%M%P", 'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication',
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -7,7 +7,6 @@ class ExosFilter(django_filters.FilterSet):
|
|||
model = Exercice
|
||||
fields = ['name']
|
||||
|
||||
|
||||
|
||||
@property
|
||||
def qs(self):
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# Generated by Django 4.0 on 2022-06-24 08:44
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.utils.timezone
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('exercices', '0015_exercice_original'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='exercice',
|
||||
name='last_update',
|
||||
field=models.DateField(auto_now_add=True, default=django.utils.timezone.now),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.0 on 2022-06-24 08:58
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('exercices', '0016_exercice_last_update'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='exercice',
|
||||
name='last_update',
|
||||
field=models.DateTimeField(auto_now_add=True),
|
||||
),
|
||||
]
|
Binary file not shown.
Binary file not shown.
|
@ -3,7 +3,7 @@ from django.db import models
|
|||
import random
|
||||
import string
|
||||
|
||||
from django.db.models.fields import CharField, IntegerField, TextField, BooleanField
|
||||
from django.db.models.fields import CharField, IntegerField, TextField, BooleanField, DateTimeField
|
||||
from django.db.models.fields.json import JSONField
|
||||
from users.models import CustomUser
|
||||
# Create your models here.
|
||||
|
@ -64,6 +64,8 @@ class Exercice(models.Model):
|
|||
isCsv = BooleanField(default=True)
|
||||
isWeb = BooleanField(default=True)
|
||||
|
||||
last_update = DateTimeField(auto_now_add=True)
|
||||
|
||||
original = BooleanField(default=True)
|
||||
origin = models.ForeignKey('self', null=True, on_delete = models.SET_NULL)
|
||||
|
||||
|
|
|
@ -11,7 +11,8 @@ class CustomPagination(pagination.PageNumberPagination):
|
|||
return Response({
|
||||
'links': {
|
||||
'next': self.get_next_link(),
|
||||
'previous': self.get_previous_link()
|
||||
'previous': self.get_previous_link(),
|
||||
|
||||
},
|
||||
'count': self.page.paginator.count,
|
||||
'page_size': self.page.paginator.per_page,
|
||||
|
|
|
@ -3,14 +3,8 @@ from fontTools.ttLib import TTFont
|
|||
from fontTools.ttLib.tables._c_m_a_p import CmapSubtable
|
||||
|
||||
|
||||
def pdf_settings(path, police, number_in_serie, number_exo, start_index, consigne):
|
||||
size = {
|
||||
'10': 94,
|
||||
'12': 78,
|
||||
'14': 67,
|
||||
'16': 59,
|
||||
'18': 52
|
||||
}
|
||||
def pdf_settings(path, number_in_serie, consigne):
|
||||
|
||||
font = TTFont(
|
||||
'/usr/share/fonts/truetype/liberation/LiberationSerif-Regular.ttf')
|
||||
|
||||
|
@ -28,6 +22,7 @@ def pdf_settings(path, police, number_in_serie, number_exo, start_index, consign
|
|||
total += s['.notdef'].width
|
||||
total = total*float(pointSize)/units_per_em
|
||||
return total
|
||||
|
||||
exemple_exo = sorted(Generateur(path, 5, 'pdf'),
|
||||
key=len, reverse=True)
|
||||
|
||||
|
|
|
@ -15,18 +15,28 @@ class ExerciceSerializer(serializers.ModelSerializer):
|
|||
tags = serializers.SerializerMethodField()
|
||||
author = serializers.SerializerMethodField()
|
||||
origin = serializers.SerializerMethodField()
|
||||
isUser = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Exercice
|
||||
fields = ('name', 'id_code', 'consigne', 'author',
|
||||
'exemple', 'tags', 'isPdf', 'isCsv', 'isWeb', "private", 'tags', 'origin')
|
||||
'exemple', 'tags', 'isPdf', 'isCsv', 'isWeb', "private", 'tags', 'origin', 'isUser', 'last_update')
|
||||
|
||||
def get_author(self, obj):
|
||||
|
||||
return UserSerializer(obj.author).data
|
||||
''' def get_exo_model(self,obj):
|
||||
pass '''
|
||||
def get_isUser(self, obj):
|
||||
try:
|
||||
user = CustomUser.objects.filter(
|
||||
id_code=self.context['user_id'])[0]
|
||||
|
||||
return obj.author == user
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def get_tags(self, obj):
|
||||
try:
|
||||
user = CustomUser.objects.filter(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
from django.urls import path
|
||||
from .views import PDF, CSV_Generator, Editor, ExerciceAPI, TagsAPI, Test, ExoModelApi, fav, getExoModelFile, getPublicList, getUserExosList
|
||||
from .views import PDF, CSV_Generator, Editor, ExerciceAPI, TagsAPI, Test, ExoModelApi, fav, getExoModelFile, getPublicList, getUserExosList, pdfGen
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
|
@ -8,7 +8,7 @@ urlpatterns = [
|
|||
path('editor/', Editor.as_view()),
|
||||
path('test/', Test.as_view()),
|
||||
path('csv/<str:code>', CSV_Generator.as_view()),
|
||||
path('pdf/', PDF.as_view()),
|
||||
path('pdf/', pdfGen),
|
||||
path('fav/', fav),
|
||||
path('model/', getExoModelFile),
|
||||
path('exercices/public', getPublicList),
|
||||
|
|
|
@ -44,10 +44,9 @@ from rest_framework import permissions
|
|||
# Create your views here.
|
||||
|
||||
|
||||
|
||||
|
||||
class ExerciceAPI(APIView):
|
||||
pagination_class = CustomPagination
|
||||
|
||||
def get(self, request, format=None):
|
||||
steps = Exercice.objects.filter(private=False)
|
||||
userExos = []
|
||||
|
@ -55,8 +54,8 @@ class ExerciceAPI(APIView):
|
|||
steps = [s for s in steps if s.author.id != request.user.id]
|
||||
userExos = request.user.exercice_set.all()
|
||||
|
||||
code = request.GET.get('code')
|
||||
|
||||
code = request.GET.get('id')
|
||||
|
||||
if code == 'pdf':
|
||||
stepsListSorted = [s for s in steps if s.isPdf == True]
|
||||
userExosListSorted = [s for s in userExos if s.isPdf == True]
|
||||
|
@ -71,16 +70,17 @@ class ExerciceAPI(APIView):
|
|||
userExosListSorted = userExos
|
||||
|
||||
if code != 'all' and code != 'pdf' and code != "web":
|
||||
exo = Exercice.objects.filter(id_code=code)[0]
|
||||
exo = Exercice.objects.get(id_code=code)
|
||||
isUser = False
|
||||
if request.user == exo.author:
|
||||
isUser = True
|
||||
return Response({"data": {**ExerciceSerializer(exo).data, "isUser": isUser, "original": exo.origin.id_code if exo.origin != None else None, "author": UserSerializer(exo.author).data if exo.author != None else None, 'exo_model': { 'filename': exo.exo_model.name.split('/')[-1], "data": open(exo.exo_model.name, 'r').read()}, "tags": [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in [tt for tt in exo.tags.all() if tt.user == request.user]]}}, status=status.HTTP_200_OK)
|
||||
return Response({"data": {**ExerciceSerializer(exo).data, "isUser": isUser, "original": exo.origin.id_code if exo.origin != None else None, "author": UserSerializer(exo.author).data if exo.author != None else None, 'exo_model': {'filename': exo.exo_model.name.split('/')[-1], "data": open(exo.exo_model.name, 'r').read()}, "tags": [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in [tt for tt in exo.tags.all() if tt.user == request.user]]}}, status=status.HTTP_200_OK)
|
||||
|
||||
else:
|
||||
return Response({"data": {
|
||||
"userExos": [{**ExerciceSerializer(ex).data,'isUser': True ,"original": ex.origin.id_code if ex.origin != None else None, "author": UserSerializer(ex.author).data if ex.author != None else None, "exo_model": {"filename": ex.exo_model.name.split('/')[-1], "data": open(
|
||||
ex.exo_model.name, 'r').read()}, "tags": [{**TagSerializer(t).data, 'value': t.id_code, 'label':t.name} for t in ex.tags.all()]} for ex in userExosListSorted],
|
||||
"publicList": [{**ExerciceSerializer(ex).data,'isUser': False, 'isRegistered': len(request.user.registeredExos.filter(id_code=ex.id_code)) != 0 if request.user.is_authenticated else None, "author": UserSerializer(ex.author).data if ex.author != None else None, "exo_model": {"filename": ex.exo_model.name.split('/')[-1], "data": open(
|
||||
"userExos": [{**ExerciceSerializer(ex).data, 'isUser': True, "original": ex.origin.id_code if ex.origin != None else None, "author": UserSerializer(ex.author).data if ex.author != None else None, "exo_model": {"filename": ex.exo_model.name.split('/')[-1], "data": open(
|
||||
ex.exo_model.name, 'r').read()}, "tags": [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in ex.tags.all()]} for ex in userExosListSorted],
|
||||
"publicList": [{**ExerciceSerializer(ex).data, 'isUser': False, 'isRegistered': len(request.user.registeredExos.filter(id_code=ex.id_code)) != 0 if request.user.is_authenticated else None, "author": UserSerializer(ex.author).data if ex.author != None else None, "exo_model": {"filename": ex.exo_model.name.split('/')[-1], "data": open(
|
||||
ex.exo_model.name, 'r').read()}, "original": ex.origin.id_code if ex.origin != None else None,
|
||||
"tags": [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in [tt for tt in ex.tags.all() if tt.user == request.user]]} for ex in stepsListSorted],
|
||||
}}, status=status.HTTP_200_OK)
|
||||
|
@ -97,7 +97,7 @@ class ExerciceAPI(APIView):
|
|||
new_exo = Exercice(consigne=consigne,
|
||||
exo_model=create_serializer.validated_data['exo_model']['file'], name=name, author=author, private=create_serializer.validated_data['private'])
|
||||
# Generateur(exo_model, 5)
|
||||
|
||||
|
||||
new_exo.isPdf = create_serializer.validated_data['exo_model']['isPdf']
|
||||
new_exo.isCsv = create_serializer.validated_data['exo_model']['isCsv']
|
||||
new_exo.isWeb = create_serializer.validated_data['exo_model']['isWeb']
|
||||
|
@ -106,7 +106,7 @@ class ExerciceAPI(APIView):
|
|||
# f'{"Csv" if new_exo.isCsv == True else ""}{"Web" if new_exo.isWeb == True else ""}',
|
||||
'type': 'Csv' if new_exo.isCsv == True else 'Web' if new_exo.isWeb == True else None,
|
||||
'data': Generateur(new_exo.exo_model.name, 5, 'csv' if new_exo.isCsv == True else 'web' if new_exo.isWeb == True else None, True) if new_exo.isCsv == True or new_exo.isWeb == True else None
|
||||
}
|
||||
}
|
||||
new_exo.save()
|
||||
# sleep(2)
|
||||
|
||||
|
@ -120,6 +120,7 @@ class ExerciceAPI(APIView):
|
|||
name = request.data.get('name')
|
||||
consigne = request.data.get('consigne')
|
||||
id_code = request.data.get('id_code')
|
||||
private = request.data.get('private')
|
||||
|
||||
exo = Exercice.objects.filter(id_code=id_code)
|
||||
if len(exo) == 0:
|
||||
|
@ -131,14 +132,15 @@ class ExerciceAPI(APIView):
|
|||
status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
serializer = ExerciceCreateSerializer(
|
||||
data={'exo_model': file, "consigne": consigne, "name": name})
|
||||
data={'exo_model': file, "consigne": consigne, "name": name, "private": private})
|
||||
errors = []
|
||||
|
||||
if serializer.is_valid():
|
||||
exo.name = name
|
||||
exo.consigne = consigne
|
||||
exo.exo_model = serializer.validated_data['exo_model']['file']
|
||||
|
||||
exo.private = serializer.validated_data['private']
|
||||
|
||||
exo.isPdf = serializer.validated_data['exo_model']['isPdf']
|
||||
exo.isCsv = serializer.validated_data['exo_model']['isCsv']
|
||||
exo.isWeb = serializer.validated_data['exo_model']['isWeb']
|
||||
|
@ -149,29 +151,28 @@ class ExerciceAPI(APIView):
|
|||
'data': Generateur(exo.exo_model.name, 5, 'csv' if exo.isCsv == True else 'web' if exo.isWeb == True else None, True) if exo.isCsv == True or exo.isWeb == True else None
|
||||
}
|
||||
exo.save()
|
||||
|
||||
|
||||
return Response({"status": "200", "errors": {}, "data": ExerciceSerializer(exo).data}, status=status.HTTP_200_OK)
|
||||
return Response({"status": "400", "errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
|
||||
@method_decorator(login_required)
|
||||
def delete(self, request, format=None):
|
||||
|
||||
|
||||
id_code = request.data.get('id_code')
|
||||
exo = Exercice.objects.filter(id_code=id_code)
|
||||
if len(exo) == 0:
|
||||
return Response({'status': "404", "data": {}},
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
exo = exo[0]
|
||||
if request.user != exo.author:
|
||||
return Response({'status': "401", "data": {}},
|
||||
status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
exo.delete()
|
||||
|
||||
return Response({'status': "200", "data": id_code}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def getPublicList(request):
|
||||
''' paginator = PageNumberPagination()
|
||||
|
@ -179,76 +180,73 @@ def getPublicList(request):
|
|||
person_objects = Exercice.objects.all()
|
||||
result_page = paginator.paginate_queryset(person_objects, request) '''
|
||||
#exos = Exercice.objects.all()
|
||||
#return Response({'data': ExerciceSerializer(exos[8], context={'user_id': request.user.id_code if not request.user.is_anonymous else ''}).data}, status=status.HTTP_200_OK)
|
||||
# return Response({'data': ExerciceSerializer(exos[8], context={'user_id': request.user.id_code if not request.user.is_anonymous else ''}).data}, status=status.HTTP_200_OK)
|
||||
|
||||
paginator = CustomPagination()
|
||||
paginator.page_size = 22
|
||||
|
||||
|
||||
exos = Exercice.objects.filter(private=False).filter(original=True)
|
||||
|
||||
|
||||
if not request.user.is_anonymous:
|
||||
# [ex for ex in exos if ex.author.id != request.user.id]
|
||||
exos = exos.filter(~Q(author__id=request.user.id))
|
||||
|
||||
|
||||
code = request.query_params.get('code')
|
||||
|
||||
if code == 'pdf':
|
||||
exos = exos.filter(isPdf = True)#[s for s in exos if s.isPdf == True]
|
||||
exos = exos.filter(isPdf=True) # [s for s in exos if s.isPdf == True]
|
||||
elif code == 'web':
|
||||
exos = exos.filter(isWeb = True)#[s for s in exos if s.isWeb == True]
|
||||
exos = exos.filter(isWeb=True) # [s for s in exos if s.isWeb == True]
|
||||
elif code == 'csv':
|
||||
exos = exos.filter(isCsv = True)#[s for s in exos if s.isCsv == True]
|
||||
exos = exos.filter(isCsv=True) # [s for s in exos if s.isCsv == True]
|
||||
exos = ExosFilter(request=request.GET, queryset=exos).qs
|
||||
|
||||
|
||||
result_page = paginator.paginate_queryset(exos, request)
|
||||
result_page = paginator.paginate_queryset(
|
||||
exos.order_by('-last_update'), request)
|
||||
serializer = ExerciceSerializer(result_page, many=True, context={
|
||||
'user_id': request.user.id_code if not request.user.is_anonymous else ''})
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([permissions.IsAuthenticated])
|
||||
def getUserExosList(request):
|
||||
paginator = CustomPagination()
|
||||
paginator.page_size = 22
|
||||
|
||||
|
||||
exos = request.user.exercice_set.all()# Exercice.objects.filter(private=False).filter(original=True)
|
||||
|
||||
# Exercice.objects.filter(private=False).filter(original=True)
|
||||
exos = request.user.exercice_set.all()
|
||||
code = request.query_params.get('code')
|
||||
|
||||
if code == 'pdf':
|
||||
exos = exos.filter(isPdf = True)#[s for s in exos if s.isPdf == True]
|
||||
exos = exos.filter(isPdf=True) # [s for s in exos if s.isPdf == True]
|
||||
elif code == 'web':
|
||||
exos = exos.filter(isWeb = True)#[s for s in exos if s.isWeb == True]
|
||||
exos = exos.filter(isWeb=True) # [s for s in exos if s.isWeb == True]
|
||||
elif code == 'csv':
|
||||
exos = exos.filter(isCsv = True)#[s for s in exos if s.isCsv == True]
|
||||
exos = exos.filter(isCsv=True) # [s for s in exos if s.isCsv == True]
|
||||
exos = ExosFilter(request=request.GET, queryset=exos).qs
|
||||
|
||||
result_page = paginator.paginate_queryset(exos, request)
|
||||
result_page = paginator.paginate_queryset(
|
||||
exos.order_by('-last_update'), request)
|
||||
serializer = ExerciceSerializer(result_page, many=True, context={
|
||||
'user_id': request.user.id_code if not request.user.is_anonymous else ''})
|
||||
return paginator.get_paginated_response(serializer.data)
|
||||
|
||||
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def getExoModelFile(request):
|
||||
|
||||
|
||||
|
||||
id_code = request.query_params['id_code']
|
||||
exo = Exercice.objects.filter(id_code=id_code)
|
||||
if len(exo) == 0:
|
||||
return Response({'errors': 'Not found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
exo = exo[0]
|
||||
exo = exo[0]
|
||||
model = exo.exo_model
|
||||
print(model.name)
|
||||
with open(model.name, 'r') as f:
|
||||
|
||||
|
||||
response = HttpResponse(f.read(), content_type='text/x-python')
|
||||
response['Content-Disposition'] = f'attachment;filename={model.name.split("/")[-1]}'
|
||||
return response
|
||||
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
|
@ -271,7 +269,6 @@ def fav(request):
|
|||
exo.exo_model.save(f.name.split('/')[-1], ContentFile(f.read()))
|
||||
exo._state.adding = True
|
||||
exo.save()
|
||||
|
||||
|
||||
return Response({'data': {'isRegistered': False}}, status=status.HTTP_200_OK)
|
||||
|
||||
|
@ -291,15 +288,13 @@ class TagsAPI(APIView):
|
|||
return Response({'status': "404", "data": {}},
|
||||
status=status.HTTP_404_NOT_FOUND)
|
||||
exo = exo[0]
|
||||
''' if request.user != exo.author:
|
||||
return Response({'status': "401", "data": {}},
|
||||
status=status.HTTP_401_UNAUTHORIZED) '''
|
||||
tagsList = []
|
||||
|
||||
|
||||
for o in options:
|
||||
# print(o)
|
||||
if o['value'].startswith('new_opt'):
|
||||
newTag = Tag(name=o['label'], color=o['color'], user = request.user)
|
||||
newTag = Tag(name=o['label'],
|
||||
color=o['color'], user=request.user)
|
||||
newTag.save()
|
||||
exo.tags.add(newTag)
|
||||
exo.save()
|
||||
|
@ -310,7 +305,7 @@ class TagsAPI(APIView):
|
|||
tag = request.user.tag_set.filter(id_code=tagId)
|
||||
if len(tag) == 0:
|
||||
return Response({'errors': ''}, status=status.HTTP_400_BAD_REQUEST)
|
||||
tag= tag[0]
|
||||
tag = tag[0]
|
||||
exo.tags.add(tag)
|
||||
exo.save()
|
||||
tagsList.append(
|
||||
|
@ -333,12 +328,11 @@ class TagsAPI(APIView):
|
|||
if request.user != exo.author:
|
||||
if tag.user != request.user:
|
||||
return Response({'status': "401", "data": {}},
|
||||
status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
|
||||
status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
exo.tags.remove(tag)
|
||||
exo.save()
|
||||
return Response({'id_code': exo.id_code,'name': tag.name, 'tagId': tag.id_code,'tags': [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in exo.tags.all() if t.user == request.user]}, status=status.HTTP_200_OK)
|
||||
return Response({'id_code': exo.id_code, 'name': tag.name, 'tagId': tag.id_code, 'tags': [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in exo.tags.all() if t.user == request.user]}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class Editor(APIView):
|
||||
|
@ -380,9 +374,92 @@ class CSV_Generator(APIView):
|
|||
return response
|
||||
|
||||
|
||||
@api_view(['POST'])
|
||||
def pdfGen(request):
|
||||
|
||||
exos = [pdf_settings(Exercice.objects.get(id_code=ex['id_code']).exo_model.name, int(ex['numberInExo']), Exercice.objects.get(id_code=ex['id_code']).consigne)
|
||||
for ex in request.data.get('exos')]
|
||||
|
||||
for e in range(len(exos)):
|
||||
for exo in range(len(exos[e]['exos'])):
|
||||
# print(exos[e]['exos'][exo])
|
||||
|
||||
exos[e]['exos'][exo]['calcul'] = sympy.latex(
|
||||
exos[e]['exos'][exo]['calcul'])
|
||||
|
||||
exos[e]['exos'][exo]['calcul'] = exos[e]['exos'][exo]['calcul'].replace(
|
||||
'≃', '\\ensuremath{\\simeq}')
|
||||
exos[e]['exos'][exo]['calcul'] = exos[e]['exos'][exo]['calcul'].replace(
|
||||
'≈', '\\ensurmath{\approx}')
|
||||
exos[e]['exos'][exo]['calcul'] = exos[e]['exos'][exo]['calcul'].replace(
|
||||
'≠', '\\ensuremath{\neq}')
|
||||
|
||||
exos[e]['exos'][exo]['correction'] = sympy.latex(
|
||||
exos[e]['exos'][exo]['correction'])
|
||||
|
||||
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
|
||||
'≃', '\\ensuremath{\\simeq}')
|
||||
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
|
||||
'≈', '\\ensurmath{\approx}')
|
||||
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
|
||||
'≠', '\\ensuremath{\neq}')
|
||||
|
||||
exp_list = re.findall(
|
||||
r'\[([A-Za-z0-9_]+)\]', exos[e]['exos'][exo]['correction'])
|
||||
red = '{red}'
|
||||
for exp in exp_list:
|
||||
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
|
||||
f'[{exp}]', f'\\textcolor{red}{{{exp}}}')
|
||||
context = {'exos': exos, 'title': request.data.get(
|
||||
'title'), 'police': request.data.get('police')}
|
||||
|
||||
template = get_template('test.tex')
|
||||
latex = template.render(context)
|
||||
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
direct = tempdir
|
||||
with open(os.path.join(direct, 'tmp.tex'), 'x', encoding='utf-8') as f:
|
||||
f.write(latex)
|
||||
command = f'xelatex -interaction=batchmode tmp.tex'
|
||||
try:
|
||||
subprocess.run(command, shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
check=True,
|
||||
cwd=direct)
|
||||
except TexError:
|
||||
raise TexError(log=log, source=latex,
|
||||
template_name='test.tex')
|
||||
try:
|
||||
subprocess.run(command, shell=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
check=True,
|
||||
cwd=direct)
|
||||
except TexError:
|
||||
raise TexError(log=log, source=latex,
|
||||
template_name='test.tex')
|
||||
|
||||
with open(os.path.join(direct, 'tmp.pdf'), 'rb') as out:
|
||||
|
||||
pdf = out.read()
|
||||
buffer = io.BytesIO(out.read())
|
||||
fich_name = request.data.get('file')
|
||||
if fich_name.count('.') >= 1:
|
||||
ext = fich_name.split('.')[-1]
|
||||
# print(ext)
|
||||
if ext == 'pdf':
|
||||
fich_name = fich_name
|
||||
elif ext != 'pdf':
|
||||
# print('nipe')
|
||||
fich_name = fich_name.replace(f'.{ext}', '.pdf')
|
||||
else:
|
||||
fich_name = fich_name + '.pdf'
|
||||
return Response({'pdf': base64.b64encode(pdf), 'filename': fich_name}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class PDF(APIView):
|
||||
def post(self, request, format=None):
|
||||
print('exos', request.data.get('exos'))
|
||||
exos = list(map(lambda ex: pdf_settings(
|
||||
Exercice.objects.filter(id_code=ex['id_code'])[0].exo_model.name, 14, int(ex['numberInExo']), int(ex['numberOfExo']), 1, ex['consigne']), request.data.get('exos')))
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3,6 +3,8 @@ import json
|
|||
from uuid import uuid4
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
from channels.db import database_sync_to_async
|
||||
|
||||
from users.serializers import UserSerializer
|
||||
from .models import Room
|
||||
|
||||
|
||||
|
@ -28,8 +30,8 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
async def receive(self, text_data):
|
||||
text_data_json = json.loads(text_data)
|
||||
type = text_data_json['data']['type']
|
||||
print(text_data_json)
|
||||
|
||||
print("EVENT", type)
|
||||
print('USER', self.scope['user'])
|
||||
if type == "login":
|
||||
print('LOF', self.scope['user'])
|
||||
participants = await self.get_participants()
|
||||
|
@ -37,10 +39,16 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
nick = text_data_json['data']['nick']
|
||||
else:
|
||||
nick = self.scope['user'].username
|
||||
|
||||
if len(nick) == 0:
|
||||
await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo non valide"}))
|
||||
return
|
||||
if nick in list(map(lambda p: p['nick'], participants)) and self.scope['user'].is_anonymous:
|
||||
await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo déjà utilisé"}))
|
||||
|
||||
return
|
||||
|
||||
elif len(nick) > 30:
|
||||
await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo trop long"}))
|
||||
return
|
||||
else:
|
||||
if self.room.private == True:
|
||||
waiter = await self.add_waiter_db(nick, self.scope['user'].is_anonymous == False, None if self.scope['user'].is_anonymous else self.scope['user'].id_code)
|
||||
|
@ -60,10 +68,10 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
new_participant = await self.add_participant(nick, self.clientId)
|
||||
self.user = new_participant
|
||||
else:
|
||||
new_participant = await self.add_user(nick, self.scope['user'])
|
||||
new_participant = await self.add_user(self.scope['user'].id_code)
|
||||
self.user = new_participant
|
||||
|
||||
await self.send(json.dumps({'type': "roomJoined", "clientId": new_participant.clientId, 'id_code': self.room_id, 'identity': new_participant}))
|
||||
await self.send(json.dumps({'type': "roomJoined", "clientId": new_participant['clientId'], 'id_code': self.room_id, 'identity': new_participant}))
|
||||
await self.channel_layer.group_send(self.room_id, {'type': 'join.event', "nick": nick, "owner": False, "online": True, "code": ""})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {'type': 'join.event', "nick": nick, "owner": False, "online": True, "code": new_participant['code']})
|
||||
|
||||
|
@ -143,34 +151,35 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
|
||||
await self.channel_layer.group_send(self.room_id, {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
else:
|
||||
code = text_data_json['data']['code']
|
||||
participants = await self.get_participants()
|
||||
|
||||
code = text_data_json['data']['code']
|
||||
participants = await self.get_participants()
|
||||
if code in list(map(lambda p: p['code'], participants)):
|
||||
participant = list(
|
||||
filter(lambda p: p['code'] == code, participants))[0]
|
||||
self.clientId = participant['clientId']
|
||||
if code in list(map(lambda p: p['code'], participants)):
|
||||
participant = list(
|
||||
filter(lambda p: p['code'] == code, participants))[0]
|
||||
self.clientId = participant['clientId']
|
||||
|
||||
if participant['clientId'] == self.room.owner['clientId'] and participant['code'] == self.room.owner['code']:
|
||||
await self.channel_layer.group_add(f'owner__{self.room_id}', self.channel_name)
|
||||
else:
|
||||
await self.channel_layer.group_add(self.room_id, self.channel_name)
|
||||
|
||||
participant['online'] = True
|
||||
self.user = participant
|
||||
await self.connect_participant()
|
||||
|
||||
await self.send(json.dumps({'type': "reloged", "clientId": self.clientId, 'id_code': self.room_id, 'identity': participant}))
|
||||
|
||||
await self.channel_layer.group_send(self.room_id, {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
|
||||
if participant['clientId'] == self.room.owner['clientId'] and participant['code'] == self.room.owner['code']:
|
||||
await self.channel_layer.group_add(f'owner__{self.room_id}', self.channel_name)
|
||||
else:
|
||||
await self.channel_layer.group_add(self.room_id, self.channel_name)
|
||||
|
||||
participant['online'] = True
|
||||
self.user = participant
|
||||
await self.connect_participant()
|
||||
|
||||
await self.send(json.dumps({'type': "reloged", "clientId": self.clientId, 'id_code': self.room_id, 'identity': participant}))
|
||||
|
||||
await self.channel_layer.group_send(self.room_id, {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
|
||||
else:
|
||||
await self.send(json.dumps({"type": "reloginError"}))
|
||||
await self.send(json.dumps({"type": "reloginError"}))
|
||||
|
||||
elif type == "reconnect":
|
||||
client = text_data_json['data']['clientId']
|
||||
print(self.scope['user'].is_anonymous)
|
||||
print("reconeect", self.scope['user'].is_anonymous)
|
||||
if not self.scope['user'].is_anonymous:
|
||||
userInRoom = await self.userInRoom()
|
||||
if not userInRoom:
|
||||
|
@ -178,6 +187,7 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
else:
|
||||
isOwner = self.scope['user'].clientId == self.room.owner[
|
||||
'clientId'] and self.scope['user'].id_code == self.room.owner['code']
|
||||
|
||||
if isOwner:
|
||||
await self.channel_layer.group_add(f'owner__{self.room_id}', self.channel_name)
|
||||
else:
|
||||
|
@ -189,6 +199,7 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
await self.connect_participant()
|
||||
|
||||
self.clientId = self.scope['user'].clientId
|
||||
print('SENDING')
|
||||
await self.send(json.dumps({'type': "reconnected", "clientId": self.scope['user'].clientId, 'id_code': self.room_id, 'identity': self.user}))
|
||||
await self.channel_layer.group_send(self.room_id, {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "reconnect.event", 'nick': self.user['nick']})
|
||||
|
@ -228,6 +239,32 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
|
||||
await self.channel_layer.group_send(self.room_id, {'type': "ban_participant", "code": code, "nick": nick})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {'type': "ban_participant", "code": code, "nick": nick})
|
||||
elif type == 'leave':
|
||||
code = text_data_json['data']["code"]
|
||||
nick = text_data_json['data']["nick"]
|
||||
clientId = text_data_json['data']["clientId"]
|
||||
status = 'anonymous' if len(code) == 6 else 'user'
|
||||
|
||||
print('EST')
|
||||
if status == 'anonymous':
|
||||
participants = await self.get_participants()
|
||||
participant = [p for p in participants if p['code'] == code]
|
||||
print('PARTICIPANR', participant)
|
||||
if len(participant) == 0:
|
||||
pass
|
||||
else:
|
||||
if clientId == participant[0]['clientId']:
|
||||
await self.del_participant(code)
|
||||
await self.channel_layer.group_send(self.room_id, {'type': "ban_participant", "code": code, "nick": nick})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {'type': "ban_participant", "code": code, "nick": nick})
|
||||
else:
|
||||
user = await self.get_user(code)
|
||||
print('USER', user, code)
|
||||
if self.scope['user'] == user:
|
||||
await self.del_user(code)
|
||||
await self.channel_layer.group_send(self.room_id, {'type': "ban_participant", "code": code, "nick": nick})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {'type': "ban_participant", "code": code, "nick": nick})
|
||||
|
||||
|
||||
async def join_event(self, event):
|
||||
await self.send(json.dumps({'type': 'joined', 'nick': event['nick'], "owner": event['owner'], "online": event['online'], "code": event["code"]}))
|
||||
|
@ -253,6 +290,14 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
@database_sync_to_async
|
||||
def get_participants(self):
|
||||
return Room.objects.filter(id_code=self.room_id)[0].anonymousMembers
|
||||
|
||||
@database_sync_to_async
|
||||
def get_users(self):
|
||||
return [UserSerializer(u).data for u in Room.objects.filter(id_code=self.room_id)[0].userMembers.all()]
|
||||
|
||||
@database_sync_to_async
|
||||
def get_user(self, code):
|
||||
return Room.objects.filter(id_code=self.room_id)[0].userMembers.get(id_code = code)
|
||||
|
||||
@database_sync_to_async
|
||||
def get_room(self):
|
||||
|
@ -301,6 +346,7 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
id_code=self.room.id_code)) != 0
|
||||
|
||||
async def disconnect(self, close_code):
|
||||
print('Disconnect')
|
||||
if self.waiter == False and self.user != None:
|
||||
await self.disconnect_participant()
|
||||
await self.channel_layer.group_discard(self.room_id, self.channel_name)
|
||||
|
@ -314,6 +360,9 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||
|
||||
async def disconnect_event(self, event):
|
||||
await self.send(json.dumps({'type': 'disconnect_participant', "nick": event['nick']}))
|
||||
|
||||
async def room_deleted(self, event):
|
||||
await self.send(json.dumps({'type': 'room_deleted'}))
|
||||
|
||||
async def reconnect_event(self, event):
|
||||
await self.send(json.dumps({'type': 'reconnect_participant', "nick": event['nick']}))
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,34 @@
|
|||
from django.core.management.base import BaseCommand, CommandError
|
||||
from room.models import Room
|
||||
import string
|
||||
import random
|
||||
import faker
|
||||
import uuid
|
||||
class Command(BaseCommand):
|
||||
help = 'Closes the specified poll for voting'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('roomId', nargs='+', type=str)
|
||||
parser.add_argument('number', nargs='+', type=int)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
room = Room.objects.get(id_code = options['roomId'][0])
|
||||
except:
|
||||
raise CommandError(f'Room "{options["roomId"][0]}" does not exist')
|
||||
newMembers = []
|
||||
for i in range(options['number'][0]):
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
if code not in [p['code'] for p in room.anonymousMembers]:
|
||||
break
|
||||
while True:
|
||||
uid = uuid.uuid4()
|
||||
if uid not in [p['clientId'] for p in room.anonymousMembers]:
|
||||
break
|
||||
fake = faker.Faker()
|
||||
newMembers.append({'nick': fake.name(), 'clientId': str(uid), 'code': code, 'owner': False, 'online': True})
|
||||
room.anonymousMembers = [*newMembers, *room.anonymousMembers]
|
||||
room.save()
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
f'Successfully added {options["number"][0]} participants to room {options["roomId"][0]}'))
|
|
@ -0,0 +1,59 @@
|
|||
from datetime import datetime
|
||||
import functools
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
import faker
|
||||
import pytz
|
||||
from room.models import Room, Parcours
|
||||
import string
|
||||
import random
|
||||
import uuid
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Closes the specified poll for voting'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('parcoursId', nargs='+', type=str)
|
||||
parser.add_argument('number', nargs='+', type=int)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
try:
|
||||
parcours = Parcours.objects.get(id_code=options['parcoursId'][0])
|
||||
except:
|
||||
raise CommandError(f'Parcours "{options["parcoursId"][0]}" does not exist')
|
||||
participants = [*parcours.room.anonymousMembers, *
|
||||
[{'code': u.id_code, 'nick': u.username, 'clientId': u.clientId} for u in parcours.room.userMembers.all()]]
|
||||
new_challengers = parcours.challenger
|
||||
if len(parcours.exercices) != 1:
|
||||
maxNote = functools.reduce(lambda a, b:{'number': a['number'] + b['number']}, parcours.exercices )['number']
|
||||
else:
|
||||
maxNote = parcours.exercices[0]['number']
|
||||
|
||||
for i in range(options['number'][0]):
|
||||
challenger = random.choice(participants)
|
||||
if challenger['code'] in [n['code'] for n in new_challengers]:
|
||||
index = [i for i, n in enumerate(
|
||||
new_challengers) if n['code'] == challenger['code']][0]
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
if code not in [p['code'] for p in new_challengers[index]['exos']]:
|
||||
break
|
||||
now = datetime.now()
|
||||
date = str(now.astimezone(pytz.timezone('Europe/Berlin')))
|
||||
fake = faker.Faker()
|
||||
date = str(fake.date_time_this_month())
|
||||
new_challengers[index] = {
|
||||
**new_challengers[index], 'exos': [*new_challengers[index]['exos'], {'result': [], 'endAt': date, 'timer': random.randint(1, parcours.timer * 60), 'note': {'value': random.randint(0, maxNote), 'total': maxNote, 'isTrust': True}, 'code': code}]}
|
||||
else:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
now = datetime.now()
|
||||
date = str(now.astimezone(pytz.timezone('Europe/Berlin')))
|
||||
fake = faker.Faker()
|
||||
date = str(fake.date_time_this_month())
|
||||
new_challengers.append({**challenger, 'validate': False, 'exos': [{'result': [], 'endAt': date, 'timer': random.randint(
|
||||
1, parcours.timer * 60), 'note': {'value': random.randint(0, maxNote), 'total': maxNote, 'isTrust': True, }, 'code': code}]})
|
||||
|
||||
parcours.challenger = new_challengers
|
||||
parcours.save()
|
||||
self.stdout.write(self.style.SUCCESS(
|
||||
f'Successfully added {options["number"][0]} challenges to parcours {options["parcoursId"][0]}'))
|
|
@ -0,0 +1,23 @@
|
|||
# Generated by Django 4.0 on 2022-06-14 20:53
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('exercices', '0015_exercice_original'),
|
||||
('room', '0009_room_online'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='parcours',
|
||||
name='exercices',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='parcours',
|
||||
name='exercices',
|
||||
field=models.ManyToManyField(to='exercices.Exercice'),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,22 @@
|
|||
# Generated by Django 4.0 on 2022-06-14 20:56
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('room', '0010_remove_parcours_exercices_parcours_exercices'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='parcours',
|
||||
name='exercices',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='parcours',
|
||||
name='exercices',
|
||||
field=models.JSONField(default=list),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.0 on 2022-06-19 14:40
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('room', '0011_remove_parcours_exercices_parcours_exercices'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='room',
|
||||
name='name',
|
||||
field=models.CharField(max_length=30),
|
||||
),
|
||||
]
|
|
@ -0,0 +1,18 @@
|
|||
# Generated by Django 4.0 on 2022-06-20 09:00
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('room', '0012_alter_room_name'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='parcours',
|
||||
name='name',
|
||||
field=models.CharField(max_length=30),
|
||||
),
|
||||
]
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,6 @@
|
|||
from datetime import datetime
|
||||
from email.policy import default
|
||||
import functools
|
||||
from pyexpat import model
|
||||
import random
|
||||
import string
|
||||
|
@ -54,7 +55,8 @@ class RoomManager(models.Manager):
|
|||
if code not in list(map(lambda p: p['code'], participants)):
|
||||
break
|
||||
new_participant = {'nick': new_name, 'code': code,
|
||||
'clientId': clientId, "owner": owner, "online": online}
|
||||
'clientId': clientId, "owner": owner}
|
||||
room.online = [*room.online, code]
|
||||
room.anonymousMembers = [*participants, new_participant]
|
||||
room.save()
|
||||
return new_participant
|
||||
|
@ -107,12 +109,18 @@ class RoomManager(models.Manager):
|
|||
|
||||
def add_waiter(self, room, new_name, isUser, code = None):
|
||||
room = self.get_queryset().filter(id_code=room)[0]
|
||||
|
||||
participants = room.anonymousMembers
|
||||
if new_name in list(map(lambda p: p['nick'], participants)) and isUser:
|
||||
return None
|
||||
|
||||
waiters = room.waiters
|
||||
print('NEWNAME', new_name, new_name in list(
|
||||
map(lambda p: p['nick'], waiters)), list(map(lambda p: p['nick'], waiters)), waiters)
|
||||
|
||||
if new_name in list(map(lambda p: p['nick'], waiters)):
|
||||
return None
|
||||
print('PASSED')
|
||||
if code == None:
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
|
@ -159,7 +167,7 @@ class RoomManager(models.Manager):
|
|||
|
||||
|
||||
class Room(models.Model):
|
||||
name = models.CharField(max_length=50)
|
||||
name = models.CharField(max_length=30)
|
||||
id_code = models.CharField(
|
||||
max_length=50, default=generate_unique_code_room)
|
||||
anonymousMembers = models.JSONField(default=list, null=True)
|
||||
|
@ -181,6 +189,7 @@ class ParcoursManager(models.Manager):
|
|||
|
||||
challengers = list(
|
||||
filter(lambda c: c['code'] == user_code, parcours.challenger))
|
||||
|
||||
if not isUser:
|
||||
challenger = list(
|
||||
filter(lambda p: p['code'] == user_code, parcours.room.anonymousMembers))[0]
|
||||
|
@ -189,37 +198,48 @@ class ParcoursManager(models.Manager):
|
|||
challenger = {'nick': user.username, "code": user.id_code, 'clientId': user.clientId}
|
||||
validate = None
|
||||
|
||||
date = getNow()
|
||||
now = datetime.now()
|
||||
date = str(now.astimezone(pytz.timezone('Europe/Berlin')))
|
||||
if len(challengers) == 0:
|
||||
condition = parcours.success_condition
|
||||
validate = date if result['note']['value'] * 20 / \
|
||||
result['note']['total'] >= condition else False
|
||||
validate = result['note']['value'] * 20 / \
|
||||
result['note']['total'] >= condition
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
parcours.challenger = [*parcours.challenger,
|
||||
{**challenger, 'exos': [{**result, 'endAt': date, 'code': code}], "validate": validate}]
|
||||
|
||||
else:
|
||||
validate = False
|
||||
if challengers[0]['validate'] != False:
|
||||
validate = challenger[0]['validate']
|
||||
else:
|
||||
condition = parcours.success_condition
|
||||
validate = date if result['note']['value'] * 20 / \
|
||||
result['note']['total'] >= condition else False
|
||||
oldChallenger = challengers[0]['exos']
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
if len(list(filter(lambda c: c['code'] == code, oldChallenger))) == 0:
|
||||
break
|
||||
parcours.challenger = [*list(filter(lambda c: c['code'] != challenger['code'], parcours.challenger)),
|
||||
{**challenger, 'exos': [*challengers[0]['exos'], {**result, 'endAt': date, "code": code}], "validate": validate}]
|
||||
|
||||
condition = parcours.success_condition
|
||||
moyenne = self.getAverage(parcours.id_code, challenger['code'])
|
||||
validate = moyenne['value'] * 20 / \
|
||||
moyenne['total'] >= condition
|
||||
oldChallenger = challengers[0]['exos']
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
if len(list(filter(lambda c: c['code'] == code, oldChallenger))) == 0:
|
||||
break
|
||||
exos = challengers[0]['exos']
|
||||
if len(exos) > 6:
|
||||
exos = [{**e, 'result':[] if i < (len(exos) - 6) and e['note']['isTrust'] == True else e['result']} for i, e in enumerate(exos)]
|
||||
parcours.challenger = [*list(filter(lambda c: c['code'] != challenger['code'], parcours.challenger)),
|
||||
{**challenger, 'exos': [*exos, {**result, 'endAt': date, "code": code}], "validate": validate}]
|
||||
|
||||
parcours.save()
|
||||
return {'validate': validate, 'code': code}
|
||||
|
||||
def getAverage(self, parcours_code, user_code):
|
||||
parcours = self.get_queryset().filter(id_code=parcours_code)[0]
|
||||
challengers = parcours.challenger
|
||||
challengers = [c for c in challengers if c['code'] == user_code]
|
||||
if len(challengers) == 0:
|
||||
print('NOPE', user_code)
|
||||
return None
|
||||
c = challengers[0]
|
||||
return {'value': round(functools.reduce(lambda a, b: a+b, [e['note']['value'] for e in c['exos']])/len(c['exos']), 2), 'total': c['exos'][0]['note']['total']}
|
||||
|
||||
|
||||
class Parcours(models.Model):
|
||||
name = models.CharField(max_length=50)
|
||||
name = models.CharField(max_length=30)
|
||||
id_code = models.CharField(
|
||||
max_length=50, default=generate_unique_code_parcours)
|
||||
challenger = models.JSONField(default=list)
|
||||
|
|
|
@ -1,18 +1,111 @@
|
|||
import functools
|
||||
from rest_framework import serializers
|
||||
|
||||
from users.models import CustomUser
|
||||
from .models import Room, Parcours
|
||||
|
||||
|
||||
class RoomSerializer(serializers.ModelSerializer):
|
||||
exo_model = ''
|
||||
exo_model = ''
|
||||
|
||||
class Meta:
|
||||
model = Room
|
||||
fields = ('id', 'name', 'id_code', 'anonymousMembers')
|
||||
|
||||
class Meta:
|
||||
model = Room
|
||||
fields = ('id', 'name', 'id_code', 'anonymousMembers', 'private', 'public_result')
|
||||
|
||||
class CreateRoomSerializer(serializers.ModelSerializer):
|
||||
exo_model = ''
|
||||
nick = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Room
|
||||
fields = ( 'name', 'anonymousMembers', 'private', "public_result", 'nick')
|
||||
|
||||
def validate_nick(self, value):
|
||||
if value != '':
|
||||
if len(value) > 30:
|
||||
raise serializers.ValidationError('Trop long')
|
||||
return value
|
||||
|
||||
raise serializers.ValidationError(code='blank')
|
||||
def get_nick(self, obj):
|
||||
return ''
|
||||
|
||||
|
||||
class RoomUserSerializer(serializers.ModelSerializer):
|
||||
status = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Room
|
||||
fields = ('id', 'name', 'id_code', 'status')
|
||||
|
||||
def get_status(self, obj):
|
||||
try:
|
||||
user = CustomUser.objects.get(
|
||||
id_code=self.context['userId'])
|
||||
return 'administrateur' if user.id_code == obj.owner['code'] else 'membre'
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
class ParcoursFullSerializer(serializers.ModelSerializer):
|
||||
is_validate = serializers.SerializerMethodField()
|
||||
challenger = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Parcours
|
||||
fields = ('id', 'name', 'id_code',
|
||||
'timer', 'exercices', 'success_condition', 'is_validate', 'challenger') # + challenger ?
|
||||
|
||||
def get_is_validate(self, obj):
|
||||
clientId = self.context.get('clientId', None)
|
||||
if clientId != None:
|
||||
challenger = [
|
||||
p for p in obj.challenger if p['clientId'] == clientId]
|
||||
if len(challenger) == 0:
|
||||
return False
|
||||
else:
|
||||
return challenger[0]['validate']
|
||||
return None
|
||||
|
||||
def get_challenger(self, obj):
|
||||
user_code = self.context.get('user_code', None)
|
||||
challengers = obj.challenger
|
||||
if user_code != None:
|
||||
challengers = [c for c in challengers if c['code'] == user_code]
|
||||
if len(challengers) == 0:
|
||||
return []
|
||||
|
||||
return [{**c, 'moyenne': Parcours.objects.getAverage(obj.id_code, c['code']), 'exos': [{'endAt': e['endAt'], 'note': e['note'], "code": e['code'], "timer": e['timer'], 'canCorrige': len(e['result']) != 0} for e in c['exos']]} for c in challengers]
|
||||
|
||||
|
||||
class ParcoursSerializer(serializers.ModelSerializer):
|
||||
exo_model = ''
|
||||
is_validate = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Parcours
|
||||
fields = ('id', 'name', 'id_code',
|
||||
'timer', 'exercices', 'success_condition') # + challenger ?
|
||||
class Meta:
|
||||
model = Parcours
|
||||
fields = ('id', 'name', 'id_code',
|
||||
'timer', 'exercices', 'success_condition', 'is_validate') # + challenger ?
|
||||
|
||||
def get_is_validate(self, obj):
|
||||
clientId = self.context.get('clientId', None)
|
||||
if clientId != None:
|
||||
challenger = [
|
||||
p for p in obj.challenger if p['clientId'] == clientId]
|
||||
if len(challenger) == 0:
|
||||
return False
|
||||
else:
|
||||
return challenger[0]['validate']
|
||||
return None
|
||||
|
||||
|
||||
class ParcoursCreateSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Parcours
|
||||
fields = ('name', 'room',
|
||||
'timer', 'exercices', 'success_condition') # + challenger ?
|
||||
|
||||
def validate_exercices(self, value):
|
||||
print('EXOS', value)
|
||||
if len(value) == 0:
|
||||
raise serializers.ValidationError('Aucun exercice séléctioné')
|
||||
return value
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
from django.test import TestCase
|
||||
|
||||
# Create your tests here.
|
||||
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
from django.conf.urls import include
|
||||
from django.urls import path
|
||||
from .views import RoomAPI, ParcoursAPI, RoomExist, ChallengeAPI, getCorrectionInfo
|
||||
from .views import RoomAPI, ParcoursAPI, RoomExist, ChallengeAPI, changeRoomName, getCorrectionInfo, getEditParcours, lockRoom, publicResultToggler
|
||||
urlpatterns = [
|
||||
path('room/', RoomAPI.as_view()),
|
||||
path('parcours/', ParcoursAPI.as_view()),
|
||||
path('room/<str:id_code>', RoomExist),
|
||||
path('correct/', getCorrectionInfo),
|
||||
path('challenge/', ChallengeAPI.as_view())
|
||||
path('edit/', getEditParcours),
|
||||
path('lock/', lockRoom),
|
||||
path('public/', publicResultToggler),
|
||||
path('change_name/', changeRoomName),
|
||||
path('challenge/', ChallengeAPI.as_view()),
|
||||
]
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import functools
|
||||
from sys import api_version
|
||||
from rest_framework.decorators import api_view
|
||||
from datetime import datetime
|
||||
|
@ -12,7 +13,7 @@ from rest_framework.views import APIView
|
|||
from rest_framework import status
|
||||
|
||||
from .models import Room, Parcours, TempCorrection
|
||||
from .serializers import RoomSerializer, ParcoursSerializer
|
||||
from .serializers import CreateRoomSerializer, ParcoursCreateSerializer, RoomSerializer, ParcoursFullSerializer, ParcoursSerializer
|
||||
from django.contrib.sessions.models import Session
|
||||
from api.Generateur import Generateur
|
||||
from exercices.models import Exercice
|
||||
|
@ -28,22 +29,36 @@ class RoomAPI(APIView):
|
|||
|
||||
def post(self, request, format=None):
|
||||
name = request.data.get('name')
|
||||
private = request.data.get('private')
|
||||
results = request.data.get('results')
|
||||
|
||||
|
||||
|
||||
if request.user.is_authenticated:
|
||||
room = Room(name=name, owner={
|
||||
"name": request.user.username, 'code': request.user.id_code, 'clientId': request.user.clientId})
|
||||
room.save()
|
||||
clientId = request.user.clientId
|
||||
code = request.user.id_code
|
||||
room.userMembers.add(request.user)
|
||||
serial = CreateRoomSerializer(data={'name': name, 'private': private, 'nick':request.user.username, 'public_results': results })
|
||||
if serial.is_valid():
|
||||
room = Room(name=name,private= private, public_result=results,owner={
|
||||
"name": request.user.username, 'code': request.user.id_code, 'clientId': request.user.clientId})
|
||||
room.save()
|
||||
clientId = request.user.clientId
|
||||
code = request.user.id_code
|
||||
room.userMembers.add(request.user)
|
||||
else:
|
||||
return Response({'error': serial.errors}, status=status.HTTP_400_BAD_REQUEST)
|
||||
else:
|
||||
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}, anonymousMembers=[{'nick': nick, 'owner': True, 'code': code, "clientId": clientId}]
|
||||
)
|
||||
room.save()
|
||||
serial = CreateRoomSerializer(
|
||||
data={'name': name, 'private': private, 'nick': nick, 'public_results': results})
|
||||
if serial.is_valid():
|
||||
code = ''.join(
|
||||
random.choices(string.ascii_uppercase, k=6))
|
||||
clientId = str(uuid4())
|
||||
room = Room(name=name, private=private, public_result=results, owner={'name': nick, 'code': code, "clientId": clientId}, anonymousMembers=[{'nick': nick, 'owner': True, 'code': code, "clientId": clientId}]
|
||||
)
|
||||
room.online=[code]
|
||||
room.save()
|
||||
else:
|
||||
return Response({'error': serial.errors}, status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response({"data": {'id_code': room.id_code, "clientId": clientId, "code": code}}, status=status.HTTP_200_OK)
|
||||
|
||||
def get(self, request, format=None):
|
||||
|
@ -59,7 +74,6 @@ class RoomAPI(APIView):
|
|||
clientId = request.GET.get('clientId')
|
||||
participants = room.anonymousMembers
|
||||
users = room.userMembers.all()
|
||||
print(room.userMembers.all())
|
||||
|
||||
userInRoom = False
|
||||
if request.user.is_authenticated:
|
||||
|
@ -73,13 +87,31 @@ class RoomAPI(APIView):
|
|||
if clientId == room.owner['clientId']:
|
||||
admin = True
|
||||
online = room.online
|
||||
# "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": [{'nick': p['nick'], 'owner': p['clientId'] == room.owner['clientId'], 'online': p['code'] in online, "code": p['code'] if admin == True else "", 'status': "anonymous"} for p in participants] + [{"status": "user", 'nick': u.username, 'owner': u.clientId == room.owner['clientId'], 'online': u.id_code in online, 'code': u.id_code if admin == True else ""} for u in users], 'parcours': [ParcoursSerializer(p).data for p in room.parcours_set.all()]}}}, status=status.HTTP_200_OK)
|
||||
|
||||
return Response({"data": {"room": {**RoomSerializer(room).data, "waiters": room.waiters if admin == True else [], "participants": [{'nick': p['nick'], 'owner': p['clientId'] == room.owner['clientId'], 'online': p['code'] in online, "code": p['code'] if admin == True else "", 'status': "anonymous"} for p in participants] + [{"status": "user", 'nick': u.username, 'owner': u.clientId == room.owner['clientId'], 'online': u.id_code in online, 'code': u.id_code if admin == True else ""} for u in users], 'parcours': [ParcoursSerializer(p, context={'clientId': clientId}).data for p in 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()
|
||||
code = request.data.get('id_code')
|
||||
clientId = request.data.get('clientId')
|
||||
try:
|
||||
room = Room.objects.filter(id_code=code)[0]
|
||||
except:
|
||||
return Response({'error': 'Not found'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
if request.user.is_authenticated:
|
||||
if request.user.id_code == room.owner['code'] and request.user.clientId == room.owner['clientId']:
|
||||
room.delete()
|
||||
else:
|
||||
return Response({'error': 'Unauthorized'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
else:
|
||||
print('CLIENTID', clientId, room.owner)
|
||||
if clientId == room.owner['clientId']:
|
||||
room.delete()
|
||||
else:
|
||||
return Response({'error': 'Unauthorized'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
channel_layer = get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)(room.id_code, {
|
||||
'type': "room_deleted"})
|
||||
return Response({"data": ''}, status=status.HTTP_200_OK)
|
||||
|
||||
def patch(self, request, format=None):
|
||||
|
@ -125,11 +157,16 @@ class RoomAPI(APIView):
|
|||
def RoomExist(request, id_code):
|
||||
if Room.objects.filter(id_code=id_code).count() > 0:
|
||||
userInRoom = False
|
||||
clientId = request.query_params.get('clientId', None)
|
||||
|
||||
if request.user.is_authenticated:
|
||||
room = Room.objects.filter(id_code=id_code)[0]
|
||||
userInRoom = len(request.user.room_set.filter(
|
||||
id_code=room.id_code)) != 0
|
||||
|
||||
else:
|
||||
room = Room.objects.filter(id_code=id_code)[0]
|
||||
userInRoom = len([p for p in room.anonymousMembers if p['clientId'] == clientId]) != 0
|
||||
|
||||
return Response({'data': {"id_code": id_code, 'is_auth': userInRoom}}, status=status.HTTP_200_OK)
|
||||
else:
|
||||
return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
@ -162,7 +199,97 @@ def getCorrectionInfo(request):
|
|||
|
||||
challenge = challenge[0]
|
||||
|
||||
return Response({'data': {**challenge, "parcours_id": parcours.id_code, 'user_code': user_code}}, status=status.HTTP_200_OK)
|
||||
return Response({'data': {**challenge, "parcours_id": parcours.id_code, "success_condition": parcours.success_condition, 'user_code': user_code, 'parcours_name': parcours.name, 'challenger_name': challenger[0]['nick']}}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
@api_view(['GET'])
|
||||
def getEditParcours(request):
|
||||
parcours_id = request.query_params['id_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]
|
||||
|
||||
exos = parcours.exercices
|
||||
exosList = []
|
||||
for e in exos:
|
||||
exo = Exercice.objects.filter(id_code=e['id_code'])
|
||||
if len(exo) != 0:
|
||||
exosList.append(
|
||||
{**ExerciceSerializer(exo[0]).data, 'number': e['number']})
|
||||
|
||||
return Response({'data': {**ParcoursSerializer(parcours).data, 'exercices': exosList}}, status=status.HTTP_200_OK)
|
||||
|
||||
@api_view(['POST'])
|
||||
def lockRoom(request):
|
||||
print('DATA', request.data)
|
||||
room_id = request.data['id_code']
|
||||
|
||||
if request.user.is_authenticated:
|
||||
clientId = request.user.clientId
|
||||
else:
|
||||
clientId = request.data['clientId']
|
||||
room = Room.objects.filter(id_code=room_id)
|
||||
|
||||
if len(room) == 0:
|
||||
return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND)
|
||||
room = room[0]
|
||||
if room.owner['clientId'] != clientId:
|
||||
return Response({'error': 'Pas autorisé en fait'}, status = status.HTTP_401_UNAUTHORIZED)
|
||||
room.private = room.private == False
|
||||
room.save()
|
||||
|
||||
return Response({'data': {'private': room.private}}, status=status.HTTP_200_OK)
|
||||
|
||||
@api_view(['POST'])
|
||||
def publicResultToggler(request):
|
||||
print('DATA', request.data)
|
||||
room_id = request.data['id_code']
|
||||
|
||||
if request.user.is_authenticated:
|
||||
clientId = request.user.clientId
|
||||
else:
|
||||
clientId = request.data['clientId']
|
||||
room = Room.objects.filter(id_code=room_id)
|
||||
|
||||
if len(room) == 0:
|
||||
return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
room = room[0]
|
||||
if room.owner['clientId'] != clientId:
|
||||
return Response({'error': 'Pas autorisé en fait'}, status = status.HTTP_401_UNAUTHORIZED)
|
||||
room.public_result = room.public_result == False
|
||||
room.save()
|
||||
|
||||
return Response({'data': {'private': room.public_result}}, status=status.HTTP_200_OK)
|
||||
|
||||
@api_view(['POST'])
|
||||
def changeRoomName(request):
|
||||
print('DATA', request.data)
|
||||
room_id = request.data['id_code']
|
||||
|
||||
if request.user.is_authenticated:
|
||||
clientId = request.user.clientId
|
||||
else:
|
||||
clientId = request.data['clientId']
|
||||
room = Room.objects.filter(id_code=room_id)
|
||||
|
||||
if len(room) == 0:
|
||||
return Response({'error': 'Pas de parcours lol'}, status=status.HTTP_404_NOT_FOUND)
|
||||
room = room[0]
|
||||
if room.owner['clientId'] != clientId:
|
||||
return Response({'error': 'Pas autorisé en fait'}, status = status.HTTP_401_UNAUTHORIZED)
|
||||
name = request.data['name']
|
||||
if name == '':
|
||||
return Response({'error': 'Not null pls'}, status = status.HTTP_400_BAD_REQUEST)
|
||||
if len(name) > 30:
|
||||
return Response({'error': 'TRop long frr'}, status = status.HTTP_400_BAD_REQUEST)
|
||||
room.name = name
|
||||
room.save()
|
||||
|
||||
return Response({'data': {'name':name}}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ChallengeAPI(APIView):
|
||||
|
@ -193,6 +320,7 @@ class ChallengeAPI(APIView):
|
|||
|
||||
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:
|
||||
|
@ -294,10 +422,12 @@ class ChallengeAPI(APIView):
|
|||
adding_challenger = Parcours.objects.challenge(
|
||||
parcours_id, user_code, {"result": corriged, "timer": exos['timer'], "note": note}, request.user.is_authenticated)
|
||||
correctionDB.delete()
|
||||
now = datetime.now()
|
||||
now = str(now.astimezone(pytz.timezone('Europe/Berlin')))
|
||||
|
||||
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] if not request.user.is_authenticated else {'nick': request.user.username,'code': request.user.id_code,'clientId': request.user.clientId}, "validate": adding_challenger['validate'], 'exos': {'note': note,"code": adding_challenger['code'], 'endAt': getNow(), "timer": exos['timer']}})
|
||||
'type': "challenge_parcours", 'id_code': parcours_id, 'moyenne': Parcours.objects.getAverage(parcours.id_code, participants[0]['code'] if not request.user.is_authenticated else request.user.id_code), "participant": participants[0] if not request.user.is_authenticated else {'nick': request.user.username, 'code': request.user.id_code, 'clientId': request.user.clientId}, "validate": adding_challenger['validate'], 'exos': {'note': note, "code": adding_challenger['code'], 'canCorrige': True, 'endAt': now, "timer": exos['timer']}})
|
||||
return Response({"data": {"exos": corriged, "note": note}}, status=status.HTTP_200_OK)
|
||||
|
||||
def put(self, request, format=None):
|
||||
|
@ -308,36 +438,46 @@ class ChallengeAPI(APIView):
|
|||
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))
|
||||
challenger = [p for p in parcours.challenger if p['code'] == user_code]
|
||||
|
||||
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))
|
||||
challenge = [c for c in trys if c['code'] == challenge_code]
|
||||
|
||||
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.challenger = [p if p['code'] != user_code else {
|
||||
**p, "exos": [e if e['code'] != challenge_code else {**e, "result": result, "note": note} for e in p['exos']]} for p in parcours.challenger]
|
||||
|
||||
parcours.save()
|
||||
return Response({"data": {}}, status=status.HTTP_200_OK)
|
||||
|
||||
moyenne = Parcours.objects.getAverage(
|
||||
parcours.id_code, challenger[0]['code'])
|
||||
parcours.challenger = [p if p['code'] != user_code else {
|
||||
**p, 'validate': moyenne['value'] * 20 / moyenne['total'] >= condition} for p in parcours.challenger]
|
||||
|
||||
parcours.save()
|
||||
|
||||
challenger = [p for p in parcours.challenger if p['code'] == user_code]
|
||||
trys = challenger[0]['exos']
|
||||
challenge = [c for c in trys if c['code'] == challenge_code]
|
||||
challenge = challenge[0]
|
||||
return Response({'data': {**challenge, "parcours_id": parcours.id_code, 'user_code': user_code, 'parcours_name': parcours.name, 'challenger_name': challenger[0]['nick']}}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ParcoursAPI(APIView):
|
||||
|
@ -366,25 +506,31 @@ class ParcoursAPI(APIView):
|
|||
|
||||
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)
|
||||
success = request.data.get('success_condition')
|
||||
|
||||
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()
|
||||
|
||||
serial = ParcoursCreateSerializer(
|
||||
data={'name': name, 'room': room.id, 'timer': timer, 'exercices': exos, 'success_condition': success})
|
||||
if not serial.is_valid():
|
||||
return Response(serial.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
parcours = serial.create(serial.validated_data)
|
||||
print('PARCOURS', parcours)
|
||||
layer = get_channel_layer()
|
||||
async_to_sync(layer.group_send)(room_code, {
|
||||
'type': 'new_parcours', 'parcours': ParcoursSerializer(parcours).data})
|
||||
'type': 'new_parcours', 'parcours': ParcoursFullSerializer(parcours).data})
|
||||
layer = get_channel_layer()
|
||||
|
||||
return Response({"data": {'id_code': parcours.id_code}}, status=status.HTTP_200_OK)
|
||||
|
@ -396,7 +542,8 @@ class ParcoursAPI(APIView):
|
|||
id_code = request.data.get('id_code')
|
||||
exos = request.data.get('exos')
|
||||
timer = request.data.get('timer')
|
||||
# print(exos, name, room_code)
|
||||
success_condition = request.data.get('success_condition')
|
||||
|
||||
try:
|
||||
parcours = Parcours.objects.filter(id_code=id_code)[0]
|
||||
except:
|
||||
|
@ -410,11 +557,12 @@ class ParcoursAPI(APIView):
|
|||
parcours.name = name
|
||||
parcours.timer = timer
|
||||
parcours.exercices = exos
|
||||
parcours.success_condition = success_condition
|
||||
parcours.save()
|
||||
|
||||
layer = get_channel_layer()
|
||||
async_to_sync(layer.group_send)(room.id_code, {
|
||||
'type': 'edit_parcours', 'parcours': ParcoursSerializer(parcours).data})
|
||||
'type': 'edit_parcours', 'parcours': ParcoursFullSerializer(parcours).data})
|
||||
layer = get_channel_layer()
|
||||
|
||||
return Response({"data": {'id_code': parcours.id_code}}, status=status.HTTP_200_OK)
|
||||
|
@ -433,23 +581,19 @@ class ParcoursAPI(APIView):
|
|||
filter(lambda p: p['code'] == user_code, room.anonymousMembers))
|
||||
userInRoom = True
|
||||
if request.user.is_authenticated:
|
||||
userInRoom = len(request.user.room_set.filter(id_code = room.id_code)) != 0
|
||||
userInRoom = len(request.user.room_set.filter(
|
||||
id_code=room.id_code)) != 0
|
||||
|
||||
if len(participants) == 0 and not userInRoom:
|
||||
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)
|
||||
return Response({"data": ParcoursFullSerializer(parcours).data}, 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)
|
||||
return Response({"data": ParcoursFullSerializer(parcours, context={'user_code': user_code}).data, }, 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)
|
||||
return Response({"data": ParcoursFullSerializer(parcours).data, }, status=status.HTTP_200_OK)
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
import random
|
||||
|
||||
def main():
|
||||
return {'calcul': f'1 + [3] = 4'}
|
||||
|
||||
print('test')
|
Binary file not shown.
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Binary file not shown.
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Binary file not shown.
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
import random
|
||||
|
||||
def main():
|
||||
return {'calcul': f'1 + [3] = 4', 'csv': None}
|
||||
|
||||
print('test')
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
import random
|
||||
|
||||
def main():
|
||||
return {'calcul': f'1 + [3] = 4', 'csv': None}
|
||||
|
||||
print('test')
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Binary file not shown.
|
@ -1,6 +0,0 @@
|
|||
import random
|
||||
|
||||
def main():
|
||||
return {'calcul': f'1 + [3] = 4', 'csv': None}
|
||||
|
||||
print('test')
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Binary file not shown.
|
@ -1,10 +1,10 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Binary file not shown.
|
@ -1,10 +1,10 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
|
@ -1,10 +0,0 @@
|
|||
import random
|
||||
|
||||
"""
|
||||
Fonction main() qui doit renvoyer un objet avec:
|
||||
calcul: le calcul a afficher
|
||||
result: la correction du calcul (pas de correction -> mettre None)
|
||||
"""
|
||||
|
||||
def main():
|
||||
return {"calcul": "", "result": None}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue