This commit is contained in:
Kilton937342 2022-06-11 23:39:03 +02:00
parent 60a2197970
commit 035af2a3b7
303 changed files with 10913 additions and 846 deletions

2
.gitignore vendored
View File

@ -1,2 +1,2 @@
/backend/env /backend/venv
/frontend/node_modules /frontend/node_modules

View File

@ -18,7 +18,7 @@ def parseCorrection(calc, replacer='...'):
return calc return calc
def Generateur(path, quantity, key): def Generateur(path, quantity, key, forcedCorrection = False):
spec = importlib.util.spec_from_file_location( spec = importlib.util.spec_from_file_location(
"tmp", path) "tmp", path)
tmp = importlib.util.module_from_spec(spec) tmp = importlib.util.module_from_spec(spec)
@ -47,5 +47,5 @@ def Generateur(path, quantity, key):
main_result = main_func() main_result = main_func()
main = {**default_object, **main_result} main = {**default_object, **main_result}
op_list.append({'calcul': parseCorrection(main[ op_list.append({'calcul': parseCorrection(main[
object_key], replacer) if (key != 'web' and main['correction'] == False) else main[object_key], 'correction': main[correction_key]}) object_key], replacer) if (forcedCorrection or (key != 'web' and main['correction'] == False)) else main[object_key], 'correction': main[correction_key]})
return op_list return op_list

View File

@ -39,15 +39,26 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
#3rd party # 3rd party
'rest_framework', 'rest_framework',
'corsheaders', 'corsheaders',
'channels', 'channels',
"rest_framework.authtoken",
'dj_rest_auth', # new
'django.contrib.sites', # new
'allauth', # new
'allauth.account', # new
'allauth.socialaccount', # new
'rest_auth.registration', # new
"django_filters",
#local # local
'exercices', 'exercices',
'room', 'room',
"users"
] ]
@ -70,7 +81,7 @@ MIDDLEWARE = [
SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies" SESSION_ENGINE = "django.contrib.sessions.backends.signed_cookies"
#CORS # 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', 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',
'http://127.0.0.1:8002', 'http://localhost:8001', 'http://192.168.1.18:8000'] 'http://127.0.0.1:8002', 'http://localhost:8001', 'http://192.168.1.18:8000']
CSRF_TRUSTED_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', CSRF_TRUSTED_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',
@ -169,7 +180,7 @@ STATIC_URL = 'static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_ROOT= os.path.join(BASE_DIR) MEDIA_ROOT = os.path.join(BASE_DIR)
# Default primary key field type # Default primary key field type
@ -186,3 +197,27 @@ CHANNEL_LAYERS = {
}, },
}, },
} }
AUTH_USER_MODEL = 'users.CustomUser'
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
AUTHENTICATION_BACKENDS = ("django.contrib.auth.backends.ModelBackend", "allauth.account.auth_backends.AuthenticationBackend",
)
SITE_ID = 1
ACCOUNT_USERNAME_REQUIRED = True
ACCOUNT_SESSION_REMEMBER = True
ACCOUNT_AUTHENTICATION_METHOD = 'username'
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_UNIQUE_USERNAME = True
REST_FRAMEWORK = {
'DATETIME_FORMAT': "%m/%d/%Y %I:%M%P", 'DEFAULT_AUTHENTICATION_CLASSES': ['rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PAGINATION_CLASS': 'exercices.paginations.CustomPagination',
'PAGE_SIZE': 20
}

View File

@ -20,5 +20,6 @@ urlpatterns = [
path('api/admin/', admin.site.urls), path('api/admin/', admin.site.urls),
path('api/exos/', include('exercices.urls')), path('api/exos/', include('exercices.urls')),
path('api/room/', include('room.urls')), path('api/room/', include('room.urls')),
path('api/users/', include("users.urls"))
#path('api/users/', include('users.urls')) #path('api/users/', include('users.urls'))
] ]

Binary file not shown.

View File

@ -0,0 +1,30 @@
import django_filters
from .models import Exercice
class ExosFilter(django_filters.FilterSet):
class Meta:
model = Exercice
fields = ['name']
@property
def qs(self):
parent = super().qs
search = self.request.get('search', '')
tags = self.request.getlist('tags[]', [])
if len(tags) == 0:
withT = []
withAllTags = []
withAllTagsQ = parent
else:
withT = parent.filter(tags__id_code__in=tags).distinct() #les exos possedants au moins un des tags
withAllTags = list(filter(lambda t: all(
i in [t.id_code for t in t.tags.all()] for i in tags ), withT))
withAllTagsQ = parent.filter(id_code__in = [e.id_code for e in withAllTags])
print('WIRHA', withAllTagsQ)
return withAllTagsQ.filter(name__icontains=search)

View File

@ -0,0 +1,25 @@
# Generated by Django 4.0 on 2022-05-20 13:52
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
('exercices', '0004_alter_exercice_exemple_alter_exercice_exo_model'),
]
operations = [
migrations.AddField(
model_name='exercice',
name='author',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='users.customuser'),
),
migrations.AddField(
model_name='exercice',
name='private',
field=models.BooleanField(default=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0 on 2022-05-21 08:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('exercices', '0005_exercice_author_exercice_private'),
]
operations = [
migrations.AlterField(
model_name='exercice',
name='private',
field=models.BooleanField(default=False),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0 on 2022-05-30 15:54
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('exercices', '0006_alter_exercice_private'),
]
operations = [
migrations.AddField(
model_name='exercice',
name='origin',
field=models.CharField(default='', max_length=20, null=True),
),
]

View File

@ -0,0 +1,17 @@
# Generated by Django 4.0 on 2022-05-30 16:15
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('exercices', '0007_exercice_origin'),
]
operations = [
migrations.RemoveField(
model_name='exercice',
name='origin',
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.0 on 2022-05-30 16:15
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('exercices', '0008_remove_exercice_origin'),
]
operations = [
migrations.AddField(
model_name='exercice',
name='origin',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='exercices.exercice'),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.0 on 2022-05-30 16:25
from django.db import migrations, models
import exercices.models
class Migration(migrations.Migration):
dependencies = [
('exercices', '0009_exercice_origin'),
]
operations = [
migrations.AlterField(
model_name='exercice',
name='id_code',
field=models.CharField(default=exercices.models.generate_unique_code_step, max_length=50, null=True, unique=True),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.0 on 2022-05-30 16:30
from django.db import migrations, models
import exercices.models
class Migration(migrations.Migration):
dependencies = [
('exercices', '0010_alter_exercice_id_code'),
]
operations = [
migrations.AlterField(
model_name='exercice',
name='id_code',
field=models.CharField(default=exercices.models.generate_unique_code_step, max_length=50, unique=True),
),
]

View File

@ -0,0 +1,19 @@
# Generated by Django 4.0 on 2022-05-30 16:53
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('exercices', '0011_alter_exercice_id_code'),
]
operations = [
migrations.AlterField(
model_name='exercice',
name='origin',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='exercices.exercice'),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 4.0 on 2022-06-04 06:54
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('users', '0010_alter_customuser_id_code'),
('exercices', '0012_alter_exercice_origin'),
]
operations = [
migrations.AddField(
model_name='tag',
name='user',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='users.customuser'),
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 4.0 on 2022-06-04 07:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('exercices', '0013_tag_user'),
]
operations = [
migrations.RemoveField(
model_name='exercice',
name='tags',
),
migrations.AddField(
model_name='exercice',
name='tags',
field=models.ManyToManyField(to='exercices.Tag'),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0 on 2022-06-06 19:47
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('exercices', '0014_remove_exercice_tags_exercice_tags'),
]
operations = [
migrations.AddField(
model_name='exercice',
name='original',
field=models.BooleanField(default=True),
),
]

View File

@ -5,6 +5,7 @@ import string
from django.db.models.fields import CharField, IntegerField, TextField, BooleanField from django.db.models.fields import CharField, IntegerField, TextField, BooleanField
from django.db.models.fields.json import JSONField from django.db.models.fields.json import JSONField
from users.models import CustomUser
# Create your models here. # Create your models here.
@ -34,6 +35,7 @@ class Tag(models.Model):
color = CharField(max_length=50, default='') color = CharField(max_length=50, default='')
id_code = CharField(max_length=50, unique=True, id_code = CharField(max_length=50, unique=True,
default=generate_unique_code_tag) default=generate_unique_code_tag)
user = models.ForeignKey('users.CustomUser', null=True, on_delete=models.CASCADE)
name = CharField(max_length=25, default='') name = CharField(max_length=25, default='')
@ -55,13 +57,20 @@ class Exercice(models.Model):
unique=True, max_length=50, default=generate_unique_code_step) unique=True, max_length=50, default=generate_unique_code_step)
exo_model = models.FileField(upload_to=exo_code) exo_model = models.FileField(upload_to=exo_code)
consigne = CharField(max_length=100, default='', blank=True) consigne = CharField(max_length=100, default='', blank=True)
tags = JSONField(default=list) tags = models.ManyToManyField(Tag)
exemple = JSONField(default=dict) exemple = JSONField(default=dict)
isPdf = BooleanField(default=True) isPdf = BooleanField(default=True)
isCsv = BooleanField(default=True) isCsv = BooleanField(default=True)
isWeb = BooleanField(default=True) isWeb = BooleanField(default=True)
original = BooleanField(default=True)
origin = models.ForeignKey('self', null=True, on_delete = models.SET_NULL)
private = BooleanField(default=False)
author = models.ForeignKey(CustomUser, null=True, on_delete=models.CASCADE)
objects = ExerciceManager() objects = ExerciceManager()
def delete(self, using=None, keep_parents=False): def delete(self, using=None, keep_parents=False):

View File

@ -0,0 +1,21 @@
from rest_framework import pagination
from rest_framework.response import Response
class CustomPagination(pagination.PageNumberPagination):
page_size_query_param='s'
page_query_param='p'
page_size=20
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.page.paginator.count,
'page_size': self.page.paginator.per_page,
'pages': self.page.paginator.num_pages,
'page_number': self.page.number,
'results': data
})

View File

@ -2,6 +2,9 @@ import os
import tempfile import tempfile
from django.forms import ValidationError from django.forms import ValidationError
from rest_framework import serializers from rest_framework import serializers
from users.models import CustomUser
from users.serializers import UserSerializer
from .models import Exercice, Tag from .models import Exercice, Tag
from api.Generateur import Generateur from api.Generateur import Generateur
import importlib.util import importlib.util
@ -9,19 +12,38 @@ from .utils import checkExoModelObject
class ExerciceSerializer(serializers.ModelSerializer): class ExerciceSerializer(serializers.ModelSerializer):
exo_model = '' tags = serializers.SerializerMethodField()
author = serializers.SerializerMethodField()
origin = serializers.SerializerMethodField()
class Meta: class Meta:
model = Exercice model = Exercice
fields = ('id', 'name', 'id_code', 'consigne', fields = ('name', 'id_code', 'consigne', 'author',
'exemple', 'tags', 'isPdf', 'isCsv', 'isWeb') 'exemple', 'tags', 'isPdf', 'isCsv', 'isWeb', "private", 'tags', 'origin')
def get_author(self, obj):
return UserSerializer(obj.author).data
''' def get_exo_model(self,obj):
pass '''
def get_tags(self, obj):
try:
user = CustomUser.objects.filter(
id_code=self.context['user_id'])[0]
return [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in obj.tags.all() if t.user == user]
except:
return []
def get_origin(self,obj):
return obj.origin if obj.origin == None else {'id_code': obj.origin.id_code}
class ExerciceCreateSerializer(serializers.ModelSerializer): class ExerciceCreateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Exercice model = Exercice
fields = ('name', 'consigne', 'exo_model') fields = ('name', 'consigne', 'exo_model', 'private')
def validate_exo_model(self, value): def validate_exo_model(self, value):
@ -50,38 +72,14 @@ class ExerciceCreateSerializer(serializers.ModelSerializer):
exoCategory = checkExoModelObject(result_object) exoCategory = checkExoModelObject(result_object)
if not exoCategory['isPdf'] and not exoCategory['isCsv'] and not exoCategory['isWeb']: if not exoCategory['isPdf'] and not exoCategory['isCsv'] and not exoCategory['isWeb']:
raise serializers.ValidationError('object invalid', code= 'invalid') raise serializers.ValidationError(
'object invalid', code='invalid')
return { return {
**exoCategory, **exoCategory,
'file': value 'file': value
} }
''' code = value.split(CODE_SEPARATOR)
if(len(code) == 1 or code[1] == ""):
raise serializers.ValidationError('This field may not be blank', code="blank")
if(len(code) == 2 and code[0] == 'python'):
# Generateur(value, 1)
try:
Generateur(value, 1)
except KeyError as e:
if e.args[0] == 'calcul' or e.args[0] == "result":
raise serializers.ValidationError(
f'Verifiez que l\'objet correspond à ce qui ai demandé ({e} manquant)', code="invalid")
if e.args[0] == 'main':
raise serializers.ValidationError(
'Code non conforme (fonction "main" requise)', code="invalid")
else:
raise serializers.ValidationError(
'Code non conforme', code="invalid")
except TypeError:
raise serializers.ValidationError('Il y a eu une erreur (vérifiez que la fontion main renvoie l\'objet demandé)')
return value '''
def create(self, validated_data, **kwargs): def create(self, validated_data, **kwargs):
exo_model = validated_data.pop('exo_model') exo_model = validated_data.pop('exo_model')

View File

@ -1,5 +1,5 @@
from django.urls import path from django.urls import path
from .views import PDF, CSV_Generator, Editor, ExerciceAPI, TagsAPI, Test, ExoModelApi from .views import PDF, CSV_Generator, Editor, ExerciceAPI, TagsAPI, Test, ExoModelApi, fav, getExoModelFile, getPublicList, getUserExosList
urlpatterns = [ urlpatterns = [
@ -9,5 +9,8 @@ urlpatterns = [
path('test/', Test.as_view()), path('test/', Test.as_view()),
path('csv/<str:code>', CSV_Generator.as_view()), path('csv/<str:code>', CSV_Generator.as_view()),
path('pdf/', PDF.as_view()), path('pdf/', PDF.as_view()),
path('model/', ExoModelApi.as_view()), path('fav/', fav),
path('model/', getExoModelFile),
path('exercices/public', getPublicList),
path('exercices/user', getUserExosList),
] ]

View File

@ -1,3 +1,9 @@
from django.db.models import Q
from rest_framework.pagination import PageNumberPagination
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.core.files.base import ContentFile
from rest_framework.decorators import api_view, permission_classes
import base64 import base64
from cmath import inf from cmath import inf
import csv import csv
@ -16,8 +22,14 @@ from rest_framework import status
from django.template.loader import get_template from django.template.loader import get_template
import sympy import sympy
from .filters import ExosFilter
from .paginations import CustomPagination
from .pdfmaker import pdf_settings from .pdfmaker import pdf_settings
from .models import generate_unique_code_step
from .utils import TexError, checkExoModelObject from .utils import TexError, checkExoModelObject
import requests import requests
@ -26,60 +38,97 @@ from api.Generateur import Csv_generator, Generateur
from .models import Exercice, Tag from .models import Exercice, Tag
from .serializers import ExerciceCreateSerializer, ExerciceSerializer, TagSerializer from .serializers import ExerciceCreateSerializer, ExerciceSerializer, TagSerializer
from users.serializers import UserSerializer
from rest_framework import permissions
# Create your views here. # Create your views here.
class ExerciceAPI(APIView): class ExerciceAPI(APIView):
pagination_class = CustomPagination
def get(self, request, format=None): def get(self, request, format=None):
steps = Exercice.objects.all() steps = Exercice.objects.filter(private=False)
code_separ = '<@!code>\r\n' userExos = []
if request.user.is_authenticated:
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('code')
nb_in_page = 24
if code == 'pdf':
stepsListSorted = [s for s in steps if s.isPdf == True]
userExosListSorted = [s for s in userExos if s.isPdf == True]
elif code == 'web':
stepsListSorted = [s for s in steps if s.isWeb == True]
userExosListSorted = [s for s in userExos if s.isWeb == True]
if code == 'all': if code == 'all':
return Response({"data": list(map(lambda ex: {**ExerciceSerializer(ex).data, 'exo_model': {'filename': ex.exo_model.name.split('/')[-1], "data": open(ex.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, ex.tags))}, steps))}, status=status.HTTP_200_OK) stepsListSorted = steps
elif code == "pdf": userExosListSorted = userExos
return Response({"data": list(map(lambda ex: {**ExerciceSerializer(ex).data, 'exo_model': {'filename': ex.exo_model.name.split('/')[-1], "data": open(ex.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, ex.tags))}, list(filter(lambda s:s.isPdf == True, steps))))}, status=status.HTTP_200_OK)
elif code == "web":
return Response({"data": list(map(lambda ex: {**ExerciceSerializer(ex).data, 'exo_model': {'filename': ex.exo_model.name.split('/')[-1], "data": open(ex.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, ex.tags))}, list(filter(lambda s:s.isWeb == True, steps))))}, status=status.HTTP_200_OK)
elif code != 'all' and code != 'pdf' and code != "web":
exo = Exercice.objects.filter(id_code=code)[0]
print(open(exo.exo_model.name, 'r').read())
return Response({"data": {**ExerciceSerializer(exo).data, 'exo_model': {'filename': exo.exo_model.name.split('/')[-1], "data": open(exo.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, exo.tags))}}, status=status.HTTP_200_OK)
else: else:
return Response({"data": list(map(lambda ex: {**ExerciceSerializer(ex).data, 'exo_model': {'filename': ex.exo_model.name.split('/')[-1], "data": open(ex.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, ex.tags))}, steps))}, status=status.HTTP_200_OK) stepsListSorted = steps
userExosListSorted = userExos
if code != 'all' and code != 'pdf' and code != "web":
exo = Exercice.objects.filter(id_code=code)[0]
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)
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(
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)
def post(self, request, format=None): def post(self, request, format=None):
file = request.FILES['file'] file = request.FILES['file']
name = request.data.get('name') name = request.data.get('name')
private = request.data.get('private')
consigne = request.data.get('consigne') consigne = request.data.get('consigne')
create_serializer = ExerciceCreateSerializer( create_serializer = ExerciceCreateSerializer(
data={'exo_model': file, "consigne": consigne, "name": name}, context={'request': request}) data={'exo_model': file, "consigne": consigne, "name": name, 'private': private}, context={'request': request})
if create_serializer.is_valid(): if create_serializer.is_valid():
print(create_serializer.validated_data['exo_model']) author = request.user if request.user.is_authenticated else None
new_exo = Exercice(consigne=consigne, new_exo = Exercice(consigne=consigne,
exo_model=create_serializer.validated_data['exo_model']['file'], name=name) exo_model=create_serializer.validated_data['exo_model']['file'], name=name, author=author, private=create_serializer.validated_data['private'])
new_exo.exemple = [] # Generateur(exo_model, 5) # Generateur(exo_model, 5)
new_exo.isPdf = create_serializer.validated_data['exo_model']['isPdf'] new_exo.isPdf = create_serializer.validated_data['exo_model']['isPdf']
new_exo.isCsv = create_serializer.validated_data['exo_model']['isCsv'] new_exo.isCsv = create_serializer.validated_data['exo_model']['isCsv']
new_exo.isWeb = create_serializer.validated_data['exo_model']['isWeb'] new_exo.isWeb = create_serializer.validated_data['exo_model']['isWeb']
new_exo.save() new_exo.save()
new_exo.exemple = {
# 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) # sleep(2)
return Response({"status": "200", "errors": {}, "data": ExerciceSerializer(new_exo).data}, status=status.HTTP_200_OK) return Response({"status": "200", "errors": {}, "data": {**ExerciceSerializer(new_exo).data, "author": UserSerializer(new_exo.author).data if new_exo.author != None else None, 'exo_model': {'filename': new_exo.exo_model.name.split('/')[-1], "data": open(new_exo.exo_model.name, 'r').read()}, "tags": [{**TagSerializer(t).data, 'value': t.id_code, 'label': t.name} for t in new_exo.tags.all()]}}, status=status.HTTP_200_OK)
print(create_serializer.errors, 'errs') print(create_serializer.errors, 'errs')
return Response({"status": "400", "errors": create_serializer.errors}, status=status.HTTP_400_BAD_REQUEST) return Response({"status": "400", "errors": create_serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
@method_decorator(login_required)
def put(self, request, format=None): def put(self, request, format=None):
file = request.FILES['file'] file = request.FILES['file']
name = request.data.get('name') name = request.data.get('name')
consigne = request.data.get('consigne') consigne = request.data.get('consigne')
exo_model = request.data.get('exo_model')
id_code = request.data.get('id_code') id_code = request.data.get('id_code')
exo = Exercice.objects.filter(id_code=id_code)[0] exo = Exercice.objects.filter(id_code=id_code)
if len(exo) == 0:
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)
serializer = ExerciceCreateSerializer( serializer = ExerciceCreateSerializer(
data={'exo_model': file, "consigne": consigne, "name": name}) data={'exo_model': file, "consigne": consigne, "name": name})
@ -89,61 +138,207 @@ class ExerciceAPI(APIView):
exo.name = name exo.name = name
exo.consigne = consigne exo.consigne = consigne
exo.exo_model = serializer.validated_data['exo_model']['file'] exo.exo_model = serializer.validated_data['exo_model']['file']
exo.exemple =[]
exo.isPdf = serializer.validated_data['exo_model']['isPdf'] exo.isPdf = serializer.validated_data['exo_model']['isPdf']
exo.isCsv = serializer.validated_data['exo_model']['isCsv'] exo.isCsv = serializer.validated_data['exo_model']['isCsv']
exo.isWeb = serializer.validated_data['exo_model']['isWeb'] exo.isWeb = serializer.validated_data['exo_model']['isWeb']
exo.save() exo.save()
exo.exemple = {
# f'{"Csv" if new_exo.isCsv == True else ""}{"Web" if new_exo.isWeb == True else ""}',
'type': 'Csv' if exo.isCsv == True else 'Web' if exo.isWeb == True else None,
'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": "200", "errors": {}, "data": ExerciceSerializer(exo).data}, status=status.HTTP_200_OK)
return Response({"status": "400", "errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST) return Response({"status": "400", "errors": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
@method_decorator(login_required)
def delete(self, request, format=None): def delete(self, request, format=None):
id_code = request.data.get('id_code') id_code = request.data.get('id_code')
exo = Exercice.objects.filter(id_code=id_code)[0] exo = Exercice.objects.filter(id_code=id_code)
if len(exo) == 0:
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)
exo.delete() exo.delete()
# sleep(2)
return Response({'status': "200", "data": id_code}, status=status.HTTP_200_OK) return Response({'status': "200", "data": id_code}, status=status.HTTP_200_OK)
@api_view(['GET'])
def getPublicList(request):
''' paginator = PageNumberPagination()
paginator.page_size = 10
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)
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]
elif code == 'web':
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 = ExosFilter(request=request.GET, queryset=exos).qs
result_page = paginator.paginate_queryset(exos, 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)
code = request.query_params.get('code')
if code == 'pdf':
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]
elif code == 'csv':
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)
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]
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'])
@permission_classes([permissions.IsAuthenticated])
def fav(request):
code = request.data.get('code')
exo = Exercice.objects.filter(id_code=code)
if len(exo) == 0:
return Response({'data': {'msg': 'Not found'}}, status=status.HTTP_404_NOT_FOUND)
originExo = exo[0]
exo = exo[0]
with open(exo.exo_model.path, 'r') as f:
print(f.name.split('/')[-1])
exo.pk = None
exo.id = None
exo.id_code = generate_unique_code_step()
exo.author = request.user
exo.original = False
exo.origin = Exercice.objects.filter(id_code=code)[0]
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)
class TagsAPI(APIView): class TagsAPI(APIView):
@method_decorator(login_required)
def get(self, request, format=None): def get(self, request, format=None):
tags = Tag.objects.all() tags = request.user.tag_set.all()
return Response({"data": list(map(lambda tag: {**TagSerializer(tag).data, 'label': tag.name, "value": tag.id_code}, tags))}, status=status.HTTP_200_OK) return Response({"data": list(map(lambda tag: {**TagSerializer(tag).data, 'label': tag.name, "value": tag.id_code}, tags))}, status=status.HTTP_200_OK)
@method_decorator(login_required)
def post(self, request, format=None): def post(self, request, format=None):
options = request.data.get('tags') options = request.data.get('tags')
step = request.data.get('step') id_code = request.data.get('step')
step = Exercice.objects.filter(id_code=step)[0] exo = Exercice.objects.filter(id_code=id_code)
if len(exo) == 0:
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 = [] tagsList = []
for o in options: for o in options:
# print(o) # print(o)
if o['value'].startswith('new_opt'): if o['value'].startswith('new_opt'):
newTag = Tag(name=o['label'], color=o['color']) newTag = Tag(name=o['label'], color=o['color'], user = request.user)
newTag.save() newTag.save()
oldTags = step.tags exo.tags.add(newTag)
step.tags = [*oldTags, newTag.id_code] exo.save()
step.save()
tagsList.append( tagsList.append(
{'name': o['label'], 'color': o['color'], 'id_code': newTag.id_code}) {'name': o['label'], 'color': o['color'], 'id_code': newTag.id_code})
else: else:
tagId = o['value'] tagId = o['value']
tag = Tag.objects.filter(id_code=tagId)[0] tag = request.user.tag_set.filter(id_code=tagId)
oldTags = step.tags if len(tag) == 0:
step.tags = [*oldTags, tag.id_code] return Response({'errors': ''}, status=status.HTTP_400_BAD_REQUEST)
step.save() tag= tag[0]
exo.tags.add(tag)
exo.save()
tagsList.append( tagsList.append(
{'name': o['label'], 'color': o['color'], 'id_code': tag.id_code}) {'name': o['label'], 'color': o['color'], 'id_code': tag.id_code})
return Response({'tags': tagsList}, status=status.HTTP_200_OK) return Response({'id_code': exo.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)
@method_decorator(login_required)
def delete(self, request, format=None): def delete(self, request, format=None):
tag = request.data.get('tag') tagId = request.data.get('tag')
step = Exercice.objects.filter(id_code=request.data.get('step'))[0] id_code = request.data.get('step')
step.tags = list(filter(lambda t: t != tag, step.tags)) exo = Exercice.objects.filter(id_code=id_code)
step.save() if len(exo) == 0:
tagObj = Tag.objects.filter(id_code=tag)[0] return Response({'status': "404", "data": {}},
return Response({"data": {"name": tagObj.name}}, status=status.HTTP_200_OK) status=status.HTTP_404_NOT_FOUND)
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]
exo = exo[0]
if request.user != exo.author:
if tag.user != request.user:
return Response({'status': "401", "data": {}},
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)
class Editor(APIView): class Editor(APIView):
@ -171,7 +366,6 @@ class CSV_Generator(APIView):
if ex.isCsv == False: if ex.isCsv == False:
return Response({'error': "Bah non en fait"}, status=status.HTTP_401_UNAUTHORIZED) return Response({'error': "Bah non en fait"}, status=status.HTTP_401_UNAUTHORIZED)
model = ex.exo_model.name model = ex.exo_model.name
consigne = ex.consigne consigne = ex.consigne
@ -296,7 +490,7 @@ class Test(APIView):
class ExoModelApi(APIView): class ExoModelApi(APIView):
def get(self, request, format=None): def get(self, request, format=None):
code = request.GET.get('code') code = request.GET.get('id_code')
exo = Exercice.objects.filter(id_code=code)[0] exo = Exercice.objects.filter(id_code=code)[0]
print(exo.exo_model.name) print(exo.exo_model.name)
model = open(exo.exo_model.name, 'rb') model = open(exo.exo_model.name, 'rb')

View File

@ -3,9 +3,9 @@ import json
from uuid import uuid4 from uuid import uuid4
from channels.generic.websocket import AsyncWebsocketConsumer from channels.generic.websocket import AsyncWebsocketConsumer
from channels.db import database_sync_to_async from channels.db import database_sync_to_async
from .models import Room from .models import Room
class RoomConsumer(AsyncWebsocketConsumer): class RoomConsumer(AsyncWebsocketConsumer):
async def connect(self): async def connect(self):
@ -25,39 +25,44 @@ class RoomConsumer(AsyncWebsocketConsumer):
print('closed') print('closed')
await self.close() await self.close()
async def receive(self, text_data): async def receive(self, text_data):
text_data_json = json.loads(text_data) text_data_json = json.loads(text_data)
type = text_data_json['data']['type'] type = text_data_json['data']['type']
print(text_data_json) print(text_data_json)
if type == "login": if type == "login":
print('LOF', self.scope['user'])
participants = await self.get_participants() participants = await self.get_participants()
nick = text_data_json['data']['nick'] if self.scope['user'].is_anonymous:
nick = text_data_json['data']['nick']
else:
nick = self.scope['user'].username
if nick in list(map(lambda p: p['nick'], participants)): if nick in list(map(lambda p: p['nick'], participants)) and self.scope['user'].is_anonymous:
print('Nooope', nick, nick in list(
map(lambda p: p['nick'], participants)))
await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo déjà utilisé"})) await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo déjà utilisé"}))
else: else:
if self.room.private == True: if self.room.private == True:
waiter = await self.add_waiter_db(nick) 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)
if waiter != None: if waiter != None:
self.waiter = True self.waiter = True
self.waiter_code = waiter['code'] self.waiter_code = waiter['code']
await self.send(json.dumps({'type': "waitingRoom", "nick": nick, 'id_code': self.room_id})) await self.send(json.dumps({'type': "waitingRoom", "nick": nick, 'id_code': self.room_id}))
await self.channel_layer.group_add(f'waiter__{waiter["code"]}', self.channel_name) await self.channel_layer.group_add(f'waiter__{waiter["code"]}', self.channel_name)
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "add_waiter", "code": waiter['code'], "nick": nick,}) await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "add_waiter", "code": waiter['code'], "nick": waiter['nick'], "status": waiter['status']})
else: else:
await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo déjà utilisé"})) await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo déjà utilisé"}))
else: else:
await self.channel_layer.group_add(self.room_id, self.channel_name) await self.channel_layer.group_add(self.room_id, self.channel_name)
new_participant = await self.add_participant(nick, self.clientId) if self.scope['user'].is_anonymous:
self.user = new_participant new_participant = await self.add_participant(nick, self.clientId)
print('new_participant') self.user = new_participant
else:
new_participant = await self.add_user(nick, self.scope['user'])
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(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']}) await self.channel_layer.group_send(f'owner__{self.room_id}', {'type': 'join.event', "nick": nick, "owner": False, "online": True, "code": new_participant['code']})
@ -65,26 +70,43 @@ class RoomConsumer(AsyncWebsocketConsumer):
elif type == "acceptParticipant": elif type == "acceptParticipant":
code = text_data_json['data']['code'] code = text_data_json['data']['code']
nick = text_data_json['data']['nick'] nick = text_data_json['data']['nick']
status = text_data_json['data']['status']
self.waiter = False self.waiter = False
new_participant = await self.add_participant(nick, str(uuid4())) if status == 'anonymous':
new_participant = await self.add_participant(nick, str(uuid4()))
else:
new_participant = await self.add_user(code)
print(new_participant)
await self.del_waiter_db(code) await self.del_waiter_db(code)
await self.channel_layer.group_send(f'waiter__{code}', {"type": "accept_room", 'id_code': self.room_id, 'code': new_participant['code']}) await self.channel_layer.group_send(f'waiter__{code}', {"type": "accept_room", 'id_code': self.room_id, 'code': new_participant['code']})
elif type == "refusedParticipant": elif type == "refusedParticipant":
code = text_data_json['data']['code'] code = text_data_json['data']['code']
await self.del_waiter_db(code) await self.del_waiter_db(code)
await self.channel_layer.group_send(f'waiter__{code}', {"type": "refused_participant"}) await self.channel_layer.group_send(f'waiter__{code}', {"type": "refused_participant"})
elif type == "logAcceptedWaiter": elif type == "logAcceptedWaiter":
code = text_data_json['data']['code'] code = text_data_json['data']['code']
participants = await self.get_participants() participants = await self.get_participants()
if not self.scope['user'].is_anonymous:
await self.channel_layer.group_discard(f'waiter__{code}', self.channel_name)
await self.channel_layer.group_add(self.room_id, self.channel_name)
self.clientId = self.scope['user'].clientId
if code in list(map(lambda p: p['code'], participants)): self.user = {
'nick': self.scope['user'].username, 'code': self.scope['user'].id_code, 'clientId':self.scope['user'].clientId, "owner": False} #à continuer dsl
self.waiter = False
self.waiter_code = None
await self.send(json.dumps({'type': "roomJoined", "clientId": self.clientId, 'id_code': self.room_id, 'identity': self.user}))
await self.channel_layer.group_send(self.room_id, {"type": "join.event", "nick": self.user['nick'], "owner": False, "online": True, "code": ''})
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "join.event", "nick": self.user['nick'], "owner": False, "online": True, "code": self.user['code']})
elif code in list(map(lambda p: p['code'], participants)):
participant = list( participant = list(
filter(lambda p: p['code'] == code, participants))[0] filter(lambda p: p['code'] == code, participants))[0]
await self.channel_layer.group_discard(f'waiter__{code}', self.channel_name) await self.channel_layer.group_discard(f'waiter__{code}', self.channel_name)
@ -100,13 +122,33 @@ class RoomConsumer(AsyncWebsocketConsumer):
await self.channel_layer.group_send(self.room_id, {"type": "join.event", "nick": participant['nick'], "owner": False, "online": True, "code": ''}) await self.channel_layer.group_send(self.room_id, {"type": "join.event", "nick": participant['nick'], "owner": False, "online": True, "code": ''})
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "join.event", "nick": participant['nick'], "owner": False, "online": True, "code": participant['code']}) await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "join.event", "nick": participant['nick'], "owner": False, "online": True, "code": participant['code']})
elif type == 'relogin': elif type == 'relogin':
if not self.scope['user'].is_anonymous:
userInRoom = await self.userInRoom()
if not userInRoom:
await self.send(json.dumps({"type": "reloginError"}))
else:
isOwner = self.scope['user'].clientId == self.room.owner[
'clientId'] and self.scope['user'].id_code == self.room.owner['code']
self.clientId = self.scope['user'].clientId
if isOwner:
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)
self.user = {
'nick': self.scope['user'].username, 'code': self.scope['user'].id_code, 'clientId': self.scope['user'].clientId, "owner": False}
await self.connect_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']})
code = text_data_json['data']['code'] code = text_data_json['data']['code']
participants = await self.get_participants() participants = await self.get_participants()
print('participants', code, participants)
if code in list(map(lambda p: p['code'], participants)): if code in list(map(lambda p: p['code'], participants)):
participant = list(filter(lambda p: p['code'] == code, participants))[0] participant = list(
filter(lambda p: p['code'] == code, participants))[0]
self.clientId = participant['clientId'] self.clientId = participant['clientId']
if participant['clientId'] == self.room.owner['clientId'] and participant['code'] == self.room.owner['code']: if participant['clientId'] == self.room.owner['clientId'] and participant['code'] == self.room.owner['code']:
@ -126,52 +168,78 @@ class RoomConsumer(AsyncWebsocketConsumer):
else: else:
await self.send(json.dumps({"type": "reloginError"})) await self.send(json.dumps({"type": "reloginError"}))
elif type == "reconnect": elif type == "reconnect":
client = text_data_json['data']['clientId'] client = text_data_json['data']['clientId']
participants = await self.get_participants() print(self.scope['user'].is_anonymous)
if not self.scope['user'].is_anonymous:
if client in list(map(lambda p: p['clientId'], participants)): userInRoom = await self.userInRoom()
self.clientId = client if not userInRoom:
await self.send(json.dumps({"type": "reconnectError", 'id_code': self.room_id}))
participant = list(filter(lambda p: p['clientId'] == client, participants))[0]
if participant['clientId'] == self.room.owner['clientId'] and participant['code'] == self.room.owner['code']:
print('add in admin')
await self.channel_layer.group_add(f'owner__{self.room_id}', self.channel_name)
else: else:
print('add in users') isOwner = self.scope['user'].clientId == self.room.owner[
await self.channel_layer.group_add(self.room_id, self.channel_name) 'clientId'] and self.scope['user'].id_code == self.room.owner['code']
participant['online'] = True if isOwner:
self.user = participant await self.channel_layer.group_add(f'owner__{self.room_id}', self.channel_name)
await self.connect_participant() else:
await self.send(json.dumps({'type': "reconnected", "clientId": client, 'id_code': self.room_id, 'identity': participant})) await self.channel_layer.group_add(self.room_id, self.channel_name)
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']}) self.user = {
'code': self.scope['user'].id_code, 'nick': self.scope['user'].username, "clientId": self.scope['user'].clientId, 'online': True, 'owner': self.scope['user'].clientId == self.room.owner['clientId'] and self.scope['user'].id_code == self.room.owner['code']}
await self.connect_participant()
self.clientId = self.scope['user'].clientId
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']})
else: else:
await self.send(json.dumps({"type": "reconnectError", 'id_code': self.room_id})) participants = await self.get_participants()
if client in list(map(lambda p: p['clientId'], participants)):
self.clientId = client
participant = list(
filter(lambda p: p['clientId'] == client, participants))[0]
if participant['clientId'] == self.room.owner['clientId'] and participant['code'] == self.room.owner['code']:
print('add in admin')
await self.channel_layer.group_add(f'owner__{self.room_id}', self.channel_name)
else:
print('add in users')
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': "reconnected", "clientId": client, '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": "reconnectError", 'id_code': self.room_id}))
elif type == 'ban': elif type == 'ban':
code = text_data_json['data']["code"] code = text_data_json['data']["code"]
nick = text_data_json['data']["nick"] nick = text_data_json['data']["nick"]
status = text_data_json['data']["status"]
await self.del_participant(code) if status == 'anonymous':
await self.del_participant(code)
else:
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(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}) await self.channel_layer.group_send(f'owner__{self.room_id}', {'type': "ban_participant", "code": code, "nick": nick})
async def join_event(self, event): 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"]})) await self.send(json.dumps({'type': 'joined', 'nick': event['nick'], "owner": event['owner'], "online": event['online'], "code": event["code"]}))
async def accept_room(self, event): async def accept_room(self, event):
await self.send(json.dumps({'type': 'accept_room', 'id_code': self.room_id, 'code':event["code"]})) await self.send(json.dumps({'type': 'accept_room', 'id_code': self.room_id, 'code': event["code"]}))
async def accept_waiter(self, event): async def accept_waiter(self, event):
await self.send(json.dumps({'type': 'joined', 'nick': event['nick'], "owner": event['owner'], "online": event['online'], "code": event["code"]})) await self.send(json.dumps({'type': 'joined', 'nick': event['nick'], "owner": event['owner'], "online": event['online'], "code": event["code"]}))
async def add_waiter(self, event): async def add_waiter(self, event):
await self.send(json.dumps({'type': 'add_waiter', 'nick': event['nick'], "code": event["code"], })) await self.send(json.dumps({'type': 'add_waiter', 'nick': event['nick'], "code": event["code"], "status": event['status']}))
async def new_parcours(self, event): async def new_parcours(self, event):
await self.send(json.dumps({'type': "add_parcours", "parcours": event['parcours']})) await self.send(json.dumps({'type': "add_parcours", "parcours": event['parcours']}))
@ -184,23 +252,30 @@ class RoomConsumer(AsyncWebsocketConsumer):
@database_sync_to_async @database_sync_to_async
def get_participants(self): def get_participants(self):
return Room.objects.filter(id_code = self.room_id)[0].participants return Room.objects.filter(id_code=self.room_id)[0].anonymousMembers
@database_sync_to_async @database_sync_to_async
def get_room(self): def get_room(self):
return Room.objects.filter(id_code = self.room_id)[0] return Room.objects.filter(id_code=self.room_id)[0]
@database_sync_to_async @database_sync_to_async
def add_participant(self, new, id): def add_participant(self, new, id):
return Room.objects.add_participant(self.room_id, new, id, False, True) return Room.objects.add_participant(self.room_id, new, id, False, True)
@database_sync_to_async @database_sync_to_async
def del_participant(self, code): def add_user(self, code):
return Room.objects.del_participant(self.room_id, code) return Room.objects.add_user(self.room_id, code, False, True)
@database_sync_to_async @database_sync_to_async
def add_waiter_db(self, new): def del_participant(self, code):
return Room.objects.add_waiter(self.room_id, new) return Room.objects.del_participant(self.room_id, code)
@database_sync_to_async
def del_user(self, code):
return Room.objects.del_user(self.room_id, code)
@database_sync_to_async
def add_waiter_db(self, new, isUser, code):
return Room.objects.add_waiter(self.room_id, new, isUser, code)
@database_sync_to_async @database_sync_to_async
def del_waiter_db(self, code): def del_waiter_db(self, code):
@ -208,11 +283,23 @@ class RoomConsumer(AsyncWebsocketConsumer):
@database_sync_to_async @database_sync_to_async
def disconnect_participant(self): def disconnect_participant(self):
return Room.objects.disconnect(self.room_id, self.user['code']) if self.scope['user'].is_anonymous:
return Room.objects.disconnect(self.room_id, self.user['code'])
else:
return Room.objects.disconnect(self.room_id, self.scope['user'].id_code)
@database_sync_to_async @database_sync_to_async
def connect_participant(self): def connect_participant(self):
return Room.objects.connect(self.room_id, self.user['code']) return Room.objects.connect(self.room_id, self.user['code'])
@database_sync_to_async
def userInRoom(self):
if self.scope['user'].is_anonymous:
return None
return len(self.scope['user'].room_set.filter(
id_code=self.room.id_code)) != 0
async def disconnect(self, close_code): async def disconnect(self, close_code):
if self.waiter == False and self.user != None: if self.waiter == False and self.user != None:
await self.disconnect_participant() await self.disconnect_participant()
@ -234,8 +321,6 @@ class RoomConsumer(AsyncWebsocketConsumer):
async def del_waiter(self, event): async def del_waiter(self, event):
await self.send(json.dumps({"type": 'del_waiter', "code": event['code']})) await self.send(json.dumps({"type": 'del_waiter', "code": event['code']}))
async def challenge_parcours(self, event): async def challenge_parcours(self, event):
await self.send(json.dumps({**event})) await self.send(json.dumps({**event}))
@ -244,7 +329,3 @@ class RoomConsumer(AsyncWebsocketConsumer):
async def edit_parcours(self, event): async def edit_parcours(self, event):
await self.send(json.dumps({**event})) await self.send(json.dumps({**event}))

View File

@ -0,0 +1,25 @@
# Generated by Django 4.0 on 2022-05-21 15:35
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('room', '0004_alter_tempcorrection_id_code'),
]
operations = [
migrations.RenameField(
model_name='room',
old_name='participants',
new_name='anonymousMembers',
),
migrations.AddField(
model_name='room',
name='userMembers',
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 4.0 on 2022-05-21 15:44
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('room', '0005_rename_participants_room_anonymousmembers_and_more'),
]
operations = [
migrations.AlterField(
model_name='room',
name='userMembers',
field=models.ManyToManyField(null=True, to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,20 @@
# Generated by Django 4.0 on 2022-05-21 15:44
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('room', '0006_alter_room_usermembers'),
]
operations = [
migrations.AlterField(
model_name='room',
name='userMembers',
field=models.ManyToManyField(to=settings.AUTH_USER_MODEL),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0 on 2022-05-21 15:45
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('room', '0007_alter_room_usermembers'),
]
operations = [
migrations.AlterField(
model_name='room',
name='anonymousMembers',
field=models.JSONField(default=list, null=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 4.0 on 2022-05-21 17:03
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('room', '0008_alter_room_anonymousmembers'),
]
operations = [
migrations.AddField(
model_name='room',
name='online',
field=models.JSONField(default=list),
),
]

View File

@ -6,6 +6,8 @@ import string
from django.db import models from django.db import models
import pytz import pytz
from .utils import getNow from .utils import getNow
from users.models import CustomUser
# Create your models here. # Create your models here.
@ -29,6 +31,7 @@ def generate_unique_code_parcours():
break break
return code return code
def generate_unique_code_corr(): def generate_unique_code_corr():
length = 6 length = 6
@ -42,25 +45,55 @@ def generate_unique_code_corr():
class RoomManager(models.Manager): class RoomManager(models.Manager):
def add_participant(self, room, new_name, clientId, owner, online): def add_participant(self, room, new_name, clientId, owner, online):
room = self.get_queryset().filter(id_code=room)[0] room = self.get_queryset().filter(id_code=room)[0]
participants = room.participants participants = room.anonymousMembers
if new_name in list(map(lambda p: p['nick'], participants)): if new_name in list(map(lambda p: p['nick'], participants)):
return None return None
code = None code = None
while True: while True:
code = ''.join(random.choices(string.ascii_uppercase, k=6)) code = ''.join(random.choices(string.ascii_uppercase, k=6))
if code not in list(map(lambda p: p['code'], participants)): if code not in list(map(lambda p: p['code'], participants)):
break break
new_participant = {'nick': new_name, 'code': code, new_participant = {'nick': new_name, 'code': code,
'clientId': clientId, "owner": owner, "online": online} 'clientId': clientId, "owner": owner, "online": online}
room.participants = [*participants, new_participant] room.anonymousMembers = [*participants, new_participant]
room.save() room.save()
return new_participant return new_participant
def add_user(self, room, code, owner, online):
room = self.get_queryset().filter(id_code=room)[0]
try:
user = CustomUser.objects.filter(id_code = code)[0]
except IndexError:
return None
room.userMembers.add(user)
new_participant = {'nick': user.username, 'code': user.id_code,
'clientId': user.clientId, "owner": owner, "online": online}
room.online = [*room.online, user.id_code]
room.save()
return new_participant
def del_user(self, room, code):
room = self.get_queryset().filter(id_code=room)[0]
try:
user = CustomUser.objects.filter(id_code=code)[0]
except IndexError:
return None
room.userMembers.remove(user)
parcours = room.parcours_set.all()
for parc in parcours:
challenger = parc.challenger
parc.challenger = list(
filter(lambda c: c['code'] != code, challenger))
parc.save()
room.save()
return code
def del_participant(self, room, code): def del_participant(self, room, code):
room = self.get_queryset().filter(id_code=room)[0] room = self.get_queryset().filter(id_code=room)[0]
participants = room.participants participants = room.anonymousMembers
room.participants = list( room.anonymousMembers = list(
filter(lambda c: c['code'] != code, participants)) filter(lambda c: c['code'] != code, participants))
print('parcours', room.parcours_set) print('parcours', room.parcours_set)
parcours = room.parcours_set.all() parcours = room.parcours_set.all()
@ -72,21 +105,20 @@ class RoomManager(models.Manager):
room.save() room.save()
return code return code
def add_waiter(self, room, new_name): def add_waiter(self, room, new_name, isUser, code = None):
room = self.get_queryset().filter(id_code=room)[0] room = self.get_queryset().filter(id_code=room)[0]
participants = room.participants participants = room.anonymousMembers
if new_name in list(map(lambda p: p['nick'], participants)): if new_name in list(map(lambda p: p['nick'], participants)) and isUser:
return None return None
waiters = room.waiters waiters = room.waiters
if new_name in list(map(lambda p: p['nick'], waiters)): if new_name in list(map(lambda p: p['nick'], waiters)):
return None return None
if code == None:
code = None while True:
while True: code = ''.join(random.choices(string.ascii_uppercase, k=6))
code = ''.join(random.choices(string.ascii_uppercase, k=6)) if code not in list(map(lambda p: p['code'], waiters)):
if code not in list(map(lambda p: p['code'], waiters)): break
break new_waiter = {'nick': new_name, 'code': code, "status": 'user' if isUser == True else 'anonymous'}
new_waiter = {'nick': new_name, 'code': code, }
room.waiters = [*waiters, new_waiter] room.waiters = [*waiters, new_waiter]
room.save() room.save()
return new_waiter return new_waiter
@ -100,95 +132,108 @@ class RoomManager(models.Manager):
def disconnect(self, room_code, code): def disconnect(self, room_code, code):
room = self.get_queryset().filter(id_code=room_code)[0] room = self.get_queryset().filter(id_code=room_code)[0]
participants = room.participants online = room.online
participant = list(
filter(lambda p: p['code'] == code, participants))[0] room.online = [
participant['online'] = False o for o in online if o != code]
room.participants = [
*list(filter(lambda p: p['code'] != code, participants)), participant]
room.save() room.save()
return True return True
def connect(self, room_code, code): def connect(self, room_code, code):
room = self.get_queryset().filter(id_code=room_code)[0] room = self.get_queryset().filter(id_code=room_code)[0]
participants = room.participants online = room.online
participant = list(
filter(lambda p: p['code'] == code, participants))[0] room.online = [*online, code]
participant['online'] = True room.save()
room.participants = [ return True
*list(filter(lambda p: p['code'] != code, participants)), participant]
def connectUser(self, room_code, code):
room = self.get_queryset().filter(id_code=room_code)[0]
online = room.online
room.online = [*online, code]
room.save() room.save()
return True return True
class Room(models.Model): class Room(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
id_code = models.CharField(max_length=50, default=generate_unique_code_room) id_code = models.CharField(
participants = models.JSONField(default=list) max_length=50, default=generate_unique_code_room)
waiters = models.JSONField(default=list) anonymousMembers = models.JSONField(default=list, null=True)
created_at = models.DateTimeField(auto_now_add=True) userMembers = models.ManyToManyField("users.CustomUser")
owner = models.JSONField(default=dict) waiters = models.JSONField(default=list)
public_result = models.BooleanField(default=False) created_at = models.DateTimeField(auto_now_add=True)
owner = models.JSONField(default=dict)
public_result = models.BooleanField(default=False)
private = models.BooleanField(default=True) online = models.JSONField(default=list)
private = models.BooleanField(default=True)
objects = RoomManager() objects = RoomManager()
class ParcoursManager(models.Manager): class ParcoursManager(models.Manager):
def challenge(self, parcours_code, user_code, result): def challenge(self, parcours_code, user_code, result, isUser):
parcours = self.get_queryset().filter(id_code=parcours_code)[0] parcours = self.get_queryset().filter(id_code=parcours_code)[0]
challengers = list( challengers = list(
filter(lambda c: c['code'] == user_code, parcours.challenger)) 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]
else:
user = CustomUser.objects.filter(id_code = user_code)[0]
challenger = {'nick': user.username, "code": user.id_code, 'clientId': user.clientId}
validate = None
challenger = list( date = getNow()
filter(lambda p: p['code'] == user_code, parcours.room.participants))[0] if len(challengers) == 0:
validate = None condition = parcours.success_condition
validate = date if result['note']['value'] * 20 / \
result['note']['total'] >= condition else False
code = ''.join(random.choices(string.ascii_uppercase, k=6))
parcours.challenger = [*parcours.challenger,
{**challenger, 'exos': [{**result, 'endAt': date, 'code': code}], "validate": validate}]
date = getNow() else:
if len(challengers) == 0: validate = False
condition = parcours.success_condition if challengers[0]['validate'] != False:
validate = date if result['note']['value'] * 20 / \ validate = challenger[0]['validate']
result['note']['total'] >= condition else False else:
code = ''.join(random.choices(string.ascii_uppercase, k=6)) condition = parcours.success_condition
parcours.challenger = [*parcours.challenger, validate = date if result['note']['value'] * 20 / \
{**challenger, 'exos': [{**result, 'endAt': date, 'code':code}], "validate": validate}] 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}]
else: parcours.save()
validate = False return {'validate': validate, 'code': code}
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}]
parcours.save()
return {'validate': validate}
class Parcours(models.Model): class Parcours(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
id_code = models.CharField( id_code = models.CharField(
max_length=50, default=generate_unique_code_parcours) max_length=50, default=generate_unique_code_parcours)
challenger = models.JSONField(default=list) challenger = models.JSONField(default=list)
room = models.ForeignKey(Room, on_delete=models.CASCADE) room = models.ForeignKey(Room, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True) created_at = models.DateTimeField(auto_now_add=True)
timer = models.IntegerField(blank=True) timer = models.IntegerField(blank=True)
exercices = models.JSONField(default=list) exercices = models.JSONField(default=list)
# https://docs.djangoproject.com/fr/4.0/ref/validators/ # https://docs.djangoproject.com/fr/4.0/ref/validators/
success_condition = models.IntegerField(default=10) success_condition = models.IntegerField(default=10)
objects = ParcoursManager()
objects = ParcoursManager()
class TempCorrection(models.Model): class TempCorrection(models.Model):
correction = models.JSONField(default=list) correction = models.JSONField(default=list)
id_code = models.CharField(max_length=50, default = generate_unique_code_corr) id_code = models.CharField(
max_length=50, default=generate_unique_code_corr)

View File

@ -6,7 +6,7 @@ class RoomSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Room model = Room
fields = ('id', 'name', 'id_code', 'participants') fields = ('id', 'name', 'id_code', 'anonymousMembers')
class ParcoursSerializer(serializers.ModelSerializer): class ParcoursSerializer(serializers.ModelSerializer):

View File

@ -25,37 +25,56 @@ from .utils import getNow
class RoomAPI(APIView): class RoomAPI(APIView):
def post(self, request, format=None): def post(self, request, format=None):
name = request.data.get('name') name = request.data.get('name')
nick = request.data.get('nick')
code = ''.join( if request.user.is_authenticated:
random.choices(string.ascii_uppercase, k=6)) room = Room(name=name, owner={
clientId = str(uuid4()) "name": request.user.username, 'code': request.user.id_code, 'clientId': request.user.clientId})
room = Room(name=name, owner={'name': nick, 'code': code, "clientId": clientId}, participants=[{'nick': nick, 'owner': True, 'code': code, "clientId": clientId}] room.save()
) clientId = request.user.clientId
room.save() code = request.user.id_code
room.userMembers.add(request.user)
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()
return Response({"data": {'id_code': room.id_code, "clientId": clientId, "code": code}}, status=status.HTTP_200_OK) return Response({"data": {'id_code': room.id_code, "clientId": clientId, "code": code}}, status=status.HTTP_200_OK)
def get(self, request, format=None): def get(self, request, format=None):
code = request.GET.get('code') code = request.GET.get('code')
room = None room = None
try: try:
room = Room.objects.filter(id_code=code)[0] room = Room.objects.filter(id_code=code)[0]
except IndexError: except IndexError:
return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND) return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND)
clientId = request.GET.get('clientId') clientId = request.GET.get('clientId')
participants = room.participants participants = room.anonymousMembers
users = room.userMembers.all()
print(room.userMembers.all())
if clientId not in list(map(lambda p: p['clientId'], participants)): userInRoom = False
if request.user.is_authenticated:
userInRoom = len(request.user.room_set.filter(
id_code=room.id_code)) != 0
if clientId not in [p['clientId'] for p in participants] and not userInRoom:
return Response({'error': 'Non autorisé', 'code': '401'}, status=status.HTTP_401_UNAUTHORIZED) return Response({'error': 'Non autorisé', 'code': '401'}, status=status.HTTP_401_UNAUTHORIZED)
admin = False admin = False
if clientId == room.owner['clientId']: if clientId == room.owner['clientId']:
admin = True 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)) # "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) 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)
def delete(self, request, format=None): def delete(self, request, format=None):
code = request.data.get('code') code = request.data.get('code')
@ -105,7 +124,13 @@ class RoomAPI(APIView):
@api_view(['GET']) @api_view(['GET'])
def RoomExist(request, id_code): def RoomExist(request, id_code):
if Room.objects.filter(id_code=id_code).count() > 0: if Room.objects.filter(id_code=id_code).count() > 0:
return Response({'data': {"id_code": id_code}}, status=status.HTTP_200_OK) userInRoom = False
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
return Response({'data': {"id_code": id_code, 'is_auth': userInRoom}}, status=status.HTTP_200_OK)
else: else:
return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND) return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND)
@ -153,9 +178,13 @@ class ChallengeAPI(APIView):
room = parcours.room room = parcours.room
participants = list( participants = list(
filter(lambda p: p['code'] == user_code, room.participants)) 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
if(len(participants) == 0): if len(participants) == 0 and not userInRoom:
return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED) return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED)
exos = parcours.exercices exos = parcours.exercices
@ -200,6 +229,8 @@ class ChallengeAPI(APIView):
exos = request.data.get('exos') exos = request.data.get('exos')
parcours_id = request.data.get('id_code') parcours_id = request.data.get('id_code')
user_code = request.data.get('user_code') user_code = request.data.get('user_code')
if request.user.is_authenticated:
user_code = request.user.id_code
correct_code = request.data.get('correct_code') correct_code = request.data.get('correct_code')
parcours = Parcours.objects.filter(id_code=parcours_id) parcours = Parcours.objects.filter(id_code=parcours_id)
@ -214,14 +245,18 @@ class ChallengeAPI(APIView):
correctionDB = corrections[0] correctionDB = corrections[0]
participants = list( participants = list(
filter(lambda p: p['code'] == user_code, room.participants)) filter(lambda p: p['code'] == user_code, room.anonymousMembers))
if(len(participants) == 0): userInRoom = True
if request.user.is_authenticated:
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) return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED)
# Corriger selon la correction les exos envoyé dans exos.exos # Corriger selon la correction les exos envoyé dans exos.exos
student_answer = exos['result'] student_answer = exos['result']
correction = correctionDB.correction correction = correctionDB.correction
inpppp = 0
def corrige(ans): def corrige(ans):
correctionExos = list( correctionExos = list(
@ -234,7 +269,8 @@ class ChallengeAPI(APIView):
correctInputs = exoCorrect['inputs'] correctInputs = exoCorrect['inputs']
print('correcti', correctInputs) print('correcti', correctInputs)
studentsInput = sorted(a['inputs'], key=lambda i: i.get('order')) studentsInput = sorted(
a['inputs'], key=lambda i: i.get('order'))
print('correctiinnnn\n\n', studentsInput) print('correctiinnnn\n\n', studentsInput)
corrigedInputs = [{**inp, "value": studentsInput[inp['order']]['value'], "isCorrect": (str(studentsInput[inp['order']]['value']) == str( 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] inp['correction'])) if inp['correction'] != "" else None} for inp in correctInputs]
@ -244,25 +280,24 @@ class ChallengeAPI(APIView):
corriged = list((map(corrige, student_answer))) corriged = list((map(corrige, student_answer)))
#l6 = uniquement les isCorrect # l6 = uniquement les isCorrect
l2 = [exs['exos'] for exs in corriged] l2 = [exs['exos'] for exs in corriged]
l4 = [ex['inputs'] for exs in l2 for ex in exs] l4 = [ex['inputs'] for exs in l2 for ex in exs]
l5 = [ex for exs in l4 for ex in exs] l5 = [ex for exs in l4 for ex in exs]
l6 = [e['isCorrect'] for e in l5] l6 = [e['isCorrect'] for e in l5]
note = { note = {
"total": len(l6), "total": len(l6),
"value": l6.count(True), "value": l6.count(True),
"isTrust": l6.count(None) == 0 "isTrust": l6.count(None) == 0
} }
adding_challenger = Parcours.objects.challenge( adding_challenger = Parcours.objects.challenge(
parcours_id, user_code, {"result": corriged, "timer": exos['timer'], "note": note}) parcours_id, user_code, {"result": corriged, "timer": exos['timer'], "note": note}, request.user.is_authenticated)
correctionDB.delete() correctionDB.delete()
channel_layer = get_channel_layer() channel_layer = get_channel_layer()
async_to_sync(channel_layer.group_send)(f"owner__{room.id_code}", { 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']}}) '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']}})
return Response({"data": {"exos": corriged, "note": note}}, status=status.HTTP_200_OK) return Response({"data": {"exos": corriged, "note": note}}, status=status.HTTP_200_OK)
def put(self, request, format=None): def put(self, request, format=None):
@ -300,10 +335,11 @@ class ChallengeAPI(APIView):
date = getNow() date = getNow()
condition = parcours.success_condition condition = parcours.success_condition
parcours.challenger = [ 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}]}] *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() parcours.save()
return Response({"data": {}}, status=status.HTTP_200_OK) return Response({"data": {}}, status=status.HTTP_200_OK)
class ParcoursAPI(APIView): class ParcoursAPI(APIView):
def delete(self, request, format=None): def delete(self, request, format=None):
@ -394,9 +430,12 @@ class ParcoursAPI(APIView):
room = parcours.room room = parcours.room
participants = list( participants = list(
filter(lambda p: p['code'] == user_code, room.participants)) 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
if(len(participants) == 0): if len(participants) == 0 and not userInRoom:
return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED) return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED)
exos = parcours.exercices exos = parcours.exercices

View File

@ -0,0 +1,6 @@
import random
def main():
return {'calcul': f'1 + [3] = 4'}
print('test')

View File

@ -0,0 +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():
return {"calcul": "", "result": None}

View File

@ -0,0 +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():
return {"calcul": "", "result": None}

View File

@ -0,0 +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():
return {"calcul": "", "result": None}

View File

@ -0,0 +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():
return {"calcul": "", "result": None}

View File

@ -0,0 +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():
return {"calcul": "", "result": None}

View File

@ -0,0 +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():
return {"calcul": "", "result": None}

View File

@ -0,0 +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():
return {"calcul": "", "result": None}

Some files were not shown because too many files have changed in this diff Show More