modifs
This commit is contained in:
parent
60a2197970
commit
035af2a3b7
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,2 +1,2 @@
|
||||
/backend/env
|
||||
/backend/venv
|
||||
/frontend/node_modules
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -18,7 +18,7 @@ def parseCorrection(calc, replacer='...'):
|
||||
return calc
|
||||
|
||||
|
||||
def Generateur(path, quantity, key):
|
||||
def Generateur(path, quantity, key, forcedCorrection = False):
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"tmp", path)
|
||||
tmp = importlib.util.module_from_spec(spec)
|
||||
@ -47,5 +47,5 @@ def Generateur(path, quantity, key):
|
||||
main_result = main_func()
|
||||
main = {**default_object, **main_result}
|
||||
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
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -38,17 +38,28 @@ INSTALLED_APPS = [
|
||||
'django.contrib.sessions',
|
||||
'django.contrib.messages',
|
||||
'django.contrib.staticfiles',
|
||||
|
||||
#3rd party
|
||||
|
||||
# 3rd party
|
||||
'rest_framework',
|
||||
'corsheaders',
|
||||
'channels',
|
||||
"rest_framework.authtoken",
|
||||
|
||||
'dj_rest_auth', # new
|
||||
'django.contrib.sites', # new
|
||||
'allauth', # new
|
||||
'allauth.account', # new
|
||||
'allauth.socialaccount', # new
|
||||
'rest_auth.registration', # new
|
||||
|
||||
|
||||
#local
|
||||
"django_filters",
|
||||
|
||||
|
||||
# local
|
||||
'exercices',
|
||||
'room',
|
||||
|
||||
"users"
|
||||
|
||||
]
|
||||
|
||||
''' REST_FRAMEWORK = {
|
||||
@ -70,7 +81,7 @@ MIDDLEWARE = [
|
||||
|
||||
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',
|
||||
'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',
|
||||
@ -169,7 +180,7 @@ STATIC_URL = 'static/'
|
||||
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
|
||||
@ -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
|
||||
|
||||
}
|
||||
|
@ -20,5 +20,6 @@ urlpatterns = [
|
||||
path('api/admin/', admin.site.urls),
|
||||
path('api/exos/', include('exercices.urls')),
|
||||
path('api/room/', include('room.urls')),
|
||||
path('api/users/', include("users.urls"))
|
||||
#path('api/users/', include('users.urls'))
|
||||
]
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
backend/api/exercices/__pycache__/filters.cpython-310.pyc
Normal file
BIN
backend/api/exercices/__pycache__/filters.cpython-310.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
backend/api/exercices/__pycache__/paginations.cpython-310.pyc
Normal file
BIN
backend/api/exercices/__pycache__/paginations.cpython-310.pyc
Normal file
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.
30
backend/api/exercices/filters.py
Normal file
30
backend/api/exercices/filters.py
Normal 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)
|
||||
|
@ -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),
|
||||
),
|
||||
]
|
@ -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),
|
||||
),
|
||||
]
|
18
backend/api/exercices/migrations/0007_exercice_origin.py
Normal file
18
backend/api/exercices/migrations/0007_exercice_origin.py
Normal 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),
|
||||
),
|
||||
]
|
@ -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',
|
||||
),
|
||||
]
|
19
backend/api/exercices/migrations/0009_exercice_origin.py
Normal file
19
backend/api/exercices/migrations/0009_exercice_origin.py
Normal 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'),
|
||||
),
|
||||
]
|
@ -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),
|
||||
),
|
||||
]
|
@ -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),
|
||||
),
|
||||
]
|
@ -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'),
|
||||
),
|
||||
]
|
20
backend/api/exercices/migrations/0013_tag_user.py
Normal file
20
backend/api/exercices/migrations/0013_tag_user.py
Normal 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'),
|
||||
),
|
||||
]
|
@ -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'),
|
||||
),
|
||||
]
|
18
backend/api/exercices/migrations/0015_exercice_original.py
Normal file
18
backend/api/exercices/migrations/0015_exercice_original.py
Normal 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),
|
||||
),
|
||||
]
|
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.
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -5,6 +5,7 @@ import string
|
||||
|
||||
from django.db.models.fields import CharField, IntegerField, TextField, BooleanField
|
||||
from django.db.models.fields.json import JSONField
|
||||
from users.models import CustomUser
|
||||
# Create your models here.
|
||||
|
||||
|
||||
@ -34,6 +35,7 @@ class Tag(models.Model):
|
||||
color = CharField(max_length=50, default='')
|
||||
id_code = CharField(max_length=50, unique=True,
|
||||
default=generate_unique_code_tag)
|
||||
user = models.ForeignKey('users.CustomUser', null=True, on_delete=models.CASCADE)
|
||||
name = CharField(max_length=25, default='')
|
||||
|
||||
|
||||
@ -55,13 +57,20 @@ class Exercice(models.Model):
|
||||
unique=True, max_length=50, default=generate_unique_code_step)
|
||||
exo_model = models.FileField(upload_to=exo_code)
|
||||
consigne = CharField(max_length=100, default='', blank=True)
|
||||
tags = JSONField(default=list)
|
||||
tags = models.ManyToManyField(Tag)
|
||||
exemple = JSONField(default=dict)
|
||||
|
||||
isPdf = BooleanField(default=True)
|
||||
isCsv = 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()
|
||||
|
||||
def delete(self, using=None, keep_parents=False):
|
||||
|
21
backend/api/exercices/paginations.py
Normal file
21
backend/api/exercices/paginations.py
Normal 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
|
||||
})
|
@ -2,6 +2,9 @@ import os
|
||||
import tempfile
|
||||
from django.forms import ValidationError
|
||||
from rest_framework import serializers
|
||||
from users.models import CustomUser
|
||||
|
||||
from users.serializers import UserSerializer
|
||||
from .models import Exercice, Tag
|
||||
from api.Generateur import Generateur
|
||||
import importlib.util
|
||||
@ -9,19 +12,38 @@ from .utils import checkExoModelObject
|
||||
|
||||
|
||||
class ExerciceSerializer(serializers.ModelSerializer):
|
||||
exo_model = ''
|
||||
tags = serializers.SerializerMethodField()
|
||||
author = serializers.SerializerMethodField()
|
||||
origin = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = Exercice
|
||||
fields = ('id', 'name', 'id_code', 'consigne',
|
||||
'exemple', 'tags', 'isPdf', 'isCsv', 'isWeb')
|
||||
fields = ('name', 'id_code', 'consigne', 'author',
|
||||
'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 Meta:
|
||||
model = Exercice
|
||||
fields = ('name', 'consigne', 'exo_model')
|
||||
fields = ('name', 'consigne', 'exo_model', 'private')
|
||||
|
||||
def validate_exo_model(self, value):
|
||||
|
||||
@ -50,37 +72,13 @@ class ExerciceCreateSerializer(serializers.ModelSerializer):
|
||||
|
||||
exoCategory = checkExoModelObject(result_object)
|
||||
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 {
|
||||
**exoCategory,
|
||||
'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):
|
||||
exo_model = validated_data.pop('exo_model')
|
||||
|
@ -1,5 +1,5 @@
|
||||
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 = [
|
||||
@ -9,5 +9,8 @@ urlpatterns = [
|
||||
path('test/', Test.as_view()),
|
||||
path('csv/<str:code>', CSV_Generator.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),
|
||||
]
|
||||
|
@ -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
|
||||
from cmath import inf
|
||||
import csv
|
||||
@ -16,8 +22,14 @@ from rest_framework import status
|
||||
from django.template.loader import get_template
|
||||
import sympy
|
||||
|
||||
from .filters import ExosFilter
|
||||
|
||||
from .paginations import CustomPagination
|
||||
|
||||
from .pdfmaker import pdf_settings
|
||||
|
||||
from .models import generate_unique_code_step
|
||||
|
||||
from .utils import TexError, checkExoModelObject
|
||||
|
||||
import requests
|
||||
@ -26,60 +38,97 @@ from api.Generateur import Csv_generator, Generateur
|
||||
|
||||
from .models import Exercice, Tag
|
||||
from .serializers import ExerciceCreateSerializer, ExerciceSerializer, TagSerializer
|
||||
from users.serializers import UserSerializer
|
||||
|
||||
from rest_framework import permissions
|
||||
# Create your views here.
|
||||
|
||||
|
||||
|
||||
|
||||
class ExerciceAPI(APIView):
|
||||
pagination_class = CustomPagination
|
||||
def get(self, request, format=None):
|
||||
steps = Exercice.objects.all()
|
||||
code_separ = '<@!code>\r\n'
|
||||
steps = Exercice.objects.filter(private=False)
|
||||
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')
|
||||
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':
|
||||
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)
|
||||
elif code == "pdf":
|
||||
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)
|
||||
stepsListSorted = steps
|
||||
userExosListSorted = userExos
|
||||
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):
|
||||
file = request.FILES['file']
|
||||
name = request.data.get('name')
|
||||
private = request.data.get('private')
|
||||
consigne = request.data.get('consigne')
|
||||
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():
|
||||
print(create_serializer.validated_data['exo_model'])
|
||||
author = request.user if request.user.is_authenticated else None
|
||||
new_exo = Exercice(consigne=consigne,
|
||||
exo_model=create_serializer.validated_data['exo_model']['file'], name=name)
|
||||
new_exo.exemple = [] # Generateur(exo_model, 5)
|
||||
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']
|
||||
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)
|
||||
|
||||
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')
|
||||
return Response({"status": "400", "errors": create_serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def put(self, request, format=None):
|
||||
file = request.FILES['file']
|
||||
name = request.data.get('name')
|
||||
consigne = request.data.get('consigne')
|
||||
exo_model = request.data.get('exo_model')
|
||||
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(
|
||||
data={'exo_model': file, "consigne": consigne, "name": name})
|
||||
@ -89,61 +138,207 @@ class ExerciceAPI(APIView):
|
||||
exo.name = name
|
||||
exo.consigne = consigne
|
||||
exo.exo_model = serializer.validated_data['exo_model']['file']
|
||||
exo.exemple =[]
|
||||
|
||||
exo.isPdf = serializer.validated_data['exo_model']['isPdf']
|
||||
exo.isCsv = serializer.validated_data['exo_model']['isCsv']
|
||||
exo.isWeb = serializer.validated_data['exo_model']['isWeb']
|
||||
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": "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)[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()
|
||||
# sleep(2)
|
||||
|
||||
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):
|
||||
@method_decorator(login_required)
|
||||
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)
|
||||
|
||||
@method_decorator(login_required)
|
||||
def post(self, request, format=None):
|
||||
options = request.data.get('tags')
|
||||
step = request.data.get('step')
|
||||
step = Exercice.objects.filter(id_code=step)[0]
|
||||
id_code = request.data.get('step')
|
||||
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 = []
|
||||
|
||||
for o in options:
|
||||
# print(o)
|
||||
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()
|
||||
oldTags = step.tags
|
||||
step.tags = [*oldTags, newTag.id_code]
|
||||
step.save()
|
||||
exo.tags.add(newTag)
|
||||
exo.save()
|
||||
tagsList.append(
|
||||
{'name': o['label'], 'color': o['color'], 'id_code': newTag.id_code})
|
||||
else:
|
||||
tagId = o['value']
|
||||
tag = Tag.objects.filter(id_code=tagId)[0]
|
||||
oldTags = step.tags
|
||||
step.tags = [*oldTags, tag.id_code]
|
||||
step.save()
|
||||
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.tags.add(tag)
|
||||
exo.save()
|
||||
tagsList.append(
|
||||
{'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):
|
||||
tag = request.data.get('tag')
|
||||
step = Exercice.objects.filter(id_code=request.data.get('step'))[0]
|
||||
step.tags = list(filter(lambda t: t != tag, step.tags))
|
||||
step.save()
|
||||
tagObj = Tag.objects.filter(id_code=tag)[0]
|
||||
return Response({"data": {"name": tagObj.name}}, status=status.HTTP_200_OK)
|
||||
tagId = request.data.get('tag')
|
||||
id_code = request.data.get('step')
|
||||
exo = Exercice.objects.filter(id_code=id_code)
|
||||
if len(exo) == 0:
|
||||
return Response({'status': "404", "data": {}},
|
||||
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):
|
||||
@ -170,8 +365,7 @@ class CSV_Generator(APIView):
|
||||
ex = Exercice.objects.filter(id_code=code)[0]
|
||||
if ex.isCsv == False:
|
||||
return Response({'error': "Bah non en fait"}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
|
||||
|
||||
model = ex.exo_model.name
|
||||
consigne = ex.consigne
|
||||
|
||||
@ -296,7 +490,7 @@ class Test(APIView):
|
||||
|
||||
class ExoModelApi(APIView):
|
||||
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]
|
||||
print(exo.exo_model.name)
|
||||
model = open(exo.exo_model.name, 'rb')
|
||||
|
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.
Binary file not shown.
Binary file not shown.
@ -3,12 +3,12 @@ import json
|
||||
from uuid import uuid4
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
from channels.db import database_sync_to_async
|
||||
|
||||
from .models import Room
|
||||
|
||||
|
||||
class RoomConsumer(AsyncWebsocketConsumer):
|
||||
async def connect(self):
|
||||
|
||||
|
||||
self.room_id = self.scope['url_route']['kwargs']['room_id']
|
||||
self.waiter = None
|
||||
self.clientId = str(uuid4())
|
||||
@ -20,71 +20,93 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
||||
print('Connected')
|
||||
await self.accept()
|
||||
await self.send(json.dumps({'type': 'connect', "clientId": self.clientId}))
|
||||
|
||||
|
||||
except:
|
||||
print('closed')
|
||||
await self.close()
|
||||
|
||||
|
||||
async def receive(self, text_data):
|
||||
text_data_json = json.loads(text_data)
|
||||
type = text_data_json['data']['type']
|
||||
print(text_data_json)
|
||||
|
||||
|
||||
if type == "login":
|
||||
print('LOF', self.scope['user'])
|
||||
participants = await self.get_participants()
|
||||
nick = text_data_json['data']['nick']
|
||||
|
||||
if nick in list(map(lambda p: p['nick'], participants)):
|
||||
print('Nooope', nick, nick in list(
|
||||
map(lambda p: p['nick'], participants)))
|
||||
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)) and self.scope['user'].is_anonymous:
|
||||
await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo déjà utilisé"}))
|
||||
|
||||
|
||||
else:
|
||||
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:
|
||||
self.waiter = True
|
||||
self.waiter_code = waiter['code']
|
||||
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_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:
|
||||
await self.send(json.dumps({'type': 'loginResponse', "error": "USER_INPUT", "description": "Pseudo déjà utilisé"}))
|
||||
|
||||
|
||||
else:
|
||||
await self.channel_layer.group_add(self.room_id, self.channel_name)
|
||||
new_participant = await self.add_participant(nick, self.clientId)
|
||||
self.user = new_participant
|
||||
print('new_participant')
|
||||
if self.scope['user'].is_anonymous:
|
||||
new_participant = await self.add_participant(nick, self.clientId)
|
||||
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.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']})
|
||||
|
||||
|
||||
elif type == "acceptParticipant":
|
||||
code = text_data_json['data']['code']
|
||||
nick = text_data_json['data']['nick']
|
||||
status = text_data_json['data']['status']
|
||||
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.channel_layer.group_send(f'waiter__{code}', {"type": "accept_room", 'id_code': self.room_id, 'code': new_participant['code']})
|
||||
|
||||
|
||||
|
||||
elif type == "refusedParticipant":
|
||||
code = text_data_json['data']['code']
|
||||
|
||||
|
||||
await self.del_waiter_db(code)
|
||||
await self.channel_layer.group_send(f'waiter__{code}', {"type": "refused_participant"})
|
||||
|
||||
|
||||
elif type == "logAcceptedWaiter":
|
||||
code = text_data_json['data']['code']
|
||||
participants = await self.get_participants()
|
||||
|
||||
if code in list(map(lambda p: p['code'], 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
|
||||
|
||||
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(
|
||||
filter(lambda p: p['code'] == code, participants))[0]
|
||||
await self.channel_layer.group_discard(f'waiter__{code}', self.channel_name)
|
||||
@ -100,151 +122,210 @@ 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(f'owner__{self.room_id}', {"type": "join.event", "nick": participant['nick'], "owner": False, "online": True, "code": participant['code']})
|
||||
|
||||
|
||||
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']
|
||||
participants = await self.get_participants()
|
||||
print('participants', 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']
|
||||
|
||||
|
||||
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"}))
|
||||
|
||||
|
||||
|
||||
elif type == "reconnect":
|
||||
client = text_data_json['data']['clientId']
|
||||
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)
|
||||
print(self.scope['user'].is_anonymous)
|
||||
if not self.scope['user'].is_anonymous:
|
||||
userInRoom = await self.userInRoom()
|
||||
if not userInRoom:
|
||||
await self.send(json.dumps({"type": "reconnectError", 'id_code': self.room_id}))
|
||||
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']})
|
||||
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:
|
||||
await self.channel_layer.group_add(self.room_id, self.channel_name)
|
||||
|
||||
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:
|
||||
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':
|
||||
code = text_data_json['data']["code"]
|
||||
nick = text_data_json['data']["nick"]
|
||||
|
||||
await self.del_participant(code)
|
||||
|
||||
status = text_data_json['data']["status"]
|
||||
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(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"]}))
|
||||
|
||||
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
await self.send(json.dumps({'type': "add_parcours", "parcours": event['parcours']}))
|
||||
|
||||
|
||||
async def refused_participant(self, event):
|
||||
await self.send(json.dumps({"type": "refused"}))
|
||||
|
||||
|
||||
async def ban_participant(self, event):
|
||||
await self.send(json.dumps({"type": "banned", 'nick': event['nick'], "code": event["code"]}))
|
||||
|
||||
|
||||
@database_sync_to_async
|
||||
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
|
||||
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
|
||||
def add_participant(self, new, id):
|
||||
return Room.objects.add_participant(self.room_id, new, id, False, True)
|
||||
|
||||
@database_sync_to_async
|
||||
def add_user(self, code):
|
||||
return Room.objects.add_user(self.room_id, code, False, True)
|
||||
|
||||
@database_sync_to_async
|
||||
def del_participant(self, code):
|
||||
return Room.objects.del_participant(self.room_id, code)
|
||||
|
||||
@database_sync_to_async
|
||||
def add_waiter_db(self, new):
|
||||
return Room.objects.add_waiter(self.room_id, new)
|
||||
|
||||
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
|
||||
def del_waiter_db(self, code):
|
||||
return Room.objects.del_waiter(self.room_id, code)
|
||||
|
||||
|
||||
@database_sync_to_async
|
||||
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
|
||||
def connect_participant(self):
|
||||
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):
|
||||
if self.waiter == False and self.user != None:
|
||||
await self.disconnect_participant()
|
||||
await self.channel_layer.group_discard(self.room_id, self.channel_name)
|
||||
await self.channel_layer.group_send(self.room_id, {"type": "disconnect.event", "nick": self.user['nick']})
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {"type": "disconnect.event", "nick": self.user['nick']})
|
||||
|
||||
|
||||
elif self.waiter == True and self.waiter_code != None:
|
||||
await self.del_waiter_db(self.waiter_code)
|
||||
await self.channel_layer.group_send(f'owner__{self.room_id}', {'type': "del_waiter", "code": self.waiter_code})
|
||||
await self.channel_layer.group_discard(f'waiter__{self.waiter_code}', self.channel_name)
|
||||
|
||||
|
||||
async def disconnect_event(self, event):
|
||||
await self.send(json.dumps({'type': 'disconnect_participant', "nick": event['nick']}))
|
||||
|
||||
|
||||
async def reconnect_event(self, event):
|
||||
await self.send(json.dumps({'type': 'reconnect_participant', "nick": event['nick']}))
|
||||
|
||||
|
||||
async def del_waiter(self, event):
|
||||
await self.send(json.dumps({"type": 'del_waiter', "code": event['code']}))
|
||||
|
||||
|
||||
|
||||
|
||||
async def challenge_parcours(self, event):
|
||||
await self.send(json.dumps({**event}))
|
||||
|
||||
|
||||
async def delete_parcours(self, event):
|
||||
await self.send(json.dumps({**event}))
|
||||
|
||||
|
||||
async def edit_parcours(self, event):
|
||||
await self.send(json.dumps({**event}))
|
||||
|
||||
|
||||
|
||||
|
@ -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),
|
||||
),
|
||||
]
|
20
backend/api/room/migrations/0006_alter_room_usermembers.py
Normal file
20
backend/api/room/migrations/0006_alter_room_usermembers.py
Normal 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),
|
||||
),
|
||||
]
|
20
backend/api/room/migrations/0007_alter_room_usermembers.py
Normal file
20
backend/api/room/migrations/0007_alter_room_usermembers.py
Normal 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),
|
||||
),
|
||||
]
|
@ -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),
|
||||
),
|
||||
]
|
18
backend/api/room/migrations/0009_room_online.py
Normal file
18
backend/api/room/migrations/0009_room_online.py
Normal 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),
|
||||
),
|
||||
]
|
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.
Binary file not shown.
Binary file not shown.
@ -6,6 +6,8 @@ import string
|
||||
from django.db import models
|
||||
import pytz
|
||||
from .utils import getNow
|
||||
|
||||
from users.models import CustomUser
|
||||
# Create your models here.
|
||||
|
||||
|
||||
@ -29,6 +31,7 @@ def generate_unique_code_parcours():
|
||||
break
|
||||
return code
|
||||
|
||||
|
||||
def generate_unique_code_corr():
|
||||
length = 6
|
||||
|
||||
@ -42,25 +45,55 @@ def generate_unique_code_corr():
|
||||
class RoomManager(models.Manager):
|
||||
def add_participant(self, room, new_name, clientId, owner, online):
|
||||
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)):
|
||||
return None
|
||||
code = None
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
if code not in list(map(lambda p: p['code'], participants)):
|
||||
break
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
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}
|
||||
room.participants = [*participants, new_participant]
|
||||
room.anonymousMembers = [*participants, new_participant]
|
||||
room.save()
|
||||
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):
|
||||
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))
|
||||
print('parcours', room.parcours_set)
|
||||
parcours = room.parcours_set.all()
|
||||
@ -72,21 +105,20 @@ class RoomManager(models.Manager):
|
||||
room.save()
|
||||
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]
|
||||
participants = room.participants
|
||||
if new_name in list(map(lambda p: p['nick'], participants)):
|
||||
return None
|
||||
participants = room.anonymousMembers
|
||||
if new_name in list(map(lambda p: p['nick'], participants)) and isUser:
|
||||
return None
|
||||
waiters = room.waiters
|
||||
if new_name in list(map(lambda p: p['nick'], waiters)):
|
||||
return None
|
||||
|
||||
code = None
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
if code not in list(map(lambda p: p['code'], waiters)):
|
||||
break
|
||||
new_waiter = {'nick': new_name, 'code': code, }
|
||||
if code == None:
|
||||
while True:
|
||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||
if code not in list(map(lambda p: p['code'], waiters)):
|
||||
break
|
||||
new_waiter = {'nick': new_name, 'code': code, "status": 'user' if isUser == True else 'anonymous'}
|
||||
room.waiters = [*waiters, new_waiter]
|
||||
room.save()
|
||||
return new_waiter
|
||||
@ -100,95 +132,108 @@ class RoomManager(models.Manager):
|
||||
|
||||
def disconnect(self, room_code, code):
|
||||
room = self.get_queryset().filter(id_code=room_code)[0]
|
||||
participants = room.participants
|
||||
participant = list(
|
||||
filter(lambda p: p['code'] == code, participants))[0]
|
||||
participant['online'] = False
|
||||
room.participants = [
|
||||
*list(filter(lambda p: p['code'] != code, participants)), participant]
|
||||
online = room.online
|
||||
|
||||
room.online = [
|
||||
o for o in online if o != code]
|
||||
room.save()
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def connect(self, room_code, code):
|
||||
room = self.get_queryset().filter(id_code=room_code)[0]
|
||||
participants = room.participants
|
||||
participant = list(
|
||||
filter(lambda p: p['code'] == code, participants))[0]
|
||||
participant['online'] = True
|
||||
room.participants = [
|
||||
*list(filter(lambda p: p['code'] != code, participants)), participant]
|
||||
online = room.online
|
||||
|
||||
room.online = [*online, code]
|
||||
room.save()
|
||||
return True
|
||||
|
||||
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()
|
||||
return True
|
||||
|
||||
|
||||
class Room(models.Model):
|
||||
name = models.CharField(max_length=50)
|
||||
id_code = models.CharField(max_length=50, default=generate_unique_code_room)
|
||||
participants = models.JSONField(default=list)
|
||||
waiters = models.JSONField(default=list)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
owner = models.JSONField(default=dict)
|
||||
public_result = models.BooleanField(default=False)
|
||||
name = models.CharField(max_length=50)
|
||||
id_code = models.CharField(
|
||||
max_length=50, default=generate_unique_code_room)
|
||||
anonymousMembers = models.JSONField(default=list, null=True)
|
||||
userMembers = models.ManyToManyField("users.CustomUser")
|
||||
waiters = models.JSONField(default=list)
|
||||
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):
|
||||
def challenge(self, parcours_code, user_code, result):
|
||||
parcours = self.get_queryset().filter(id_code=parcours_code)[0]
|
||||
def challenge(self, parcours_code, user_code, result, isUser):
|
||||
parcours = self.get_queryset().filter(id_code=parcours_code)[0]
|
||||
|
||||
challengers = list(
|
||||
filter(lambda c: c['code'] == user_code, parcours.challenger))
|
||||
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]
|
||||
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(
|
||||
filter(lambda p: p['code'] == user_code, parcours.room.participants))[0]
|
||||
validate = None
|
||||
date = getNow()
|
||||
if len(challengers) == 0:
|
||||
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()
|
||||
if len(challengers) == 0:
|
||||
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}]
|
||||
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}]
|
||||
|
||||
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}]
|
||||
|
||||
parcours.save()
|
||||
return {'validate': validate}
|
||||
parcours.save()
|
||||
return {'validate': validate, 'code': code}
|
||||
|
||||
|
||||
class Parcours(models.Model):
|
||||
name = models.CharField(max_length=50)
|
||||
id_code = models.CharField(
|
||||
max_length=50, default=generate_unique_code_parcours)
|
||||
challenger = models.JSONField(default=list)
|
||||
room = models.ForeignKey(Room, on_delete=models.CASCADE)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
timer = models.IntegerField(blank=True)
|
||||
exercices = models.JSONField(default=list)
|
||||
# https://docs.djangoproject.com/fr/4.0/ref/validators/
|
||||
success_condition = models.IntegerField(default=10)
|
||||
name = models.CharField(max_length=50)
|
||||
id_code = models.CharField(
|
||||
max_length=50, default=generate_unique_code_parcours)
|
||||
challenger = models.JSONField(default=list)
|
||||
room = models.ForeignKey(Room, on_delete=models.CASCADE)
|
||||
created_at = models.DateTimeField(auto_now_add=True)
|
||||
timer = models.IntegerField(blank=True)
|
||||
exercices = models.JSONField(default=list)
|
||||
# https://docs.djangoproject.com/fr/4.0/ref/validators/
|
||||
success_condition = models.IntegerField(default=10)
|
||||
|
||||
objects = ParcoursManager()
|
||||
|
||||
|
||||
objects = ParcoursManager()
|
||||
|
||||
class TempCorrection(models.Model):
|
||||
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)
|
||||
|
@ -6,7 +6,7 @@ class RoomSerializer(serializers.ModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Room
|
||||
fields = ('id', 'name', 'id_code', 'participants')
|
||||
fields = ('id', 'name', 'id_code', 'anonymousMembers')
|
||||
|
||||
|
||||
class ParcoursSerializer(serializers.ModelSerializer):
|
||||
|
@ -25,37 +25,56 @@ from .utils import getNow
|
||||
|
||||
|
||||
class RoomAPI(APIView):
|
||||
|
||||
def post(self, request, format=None):
|
||||
name = request.data.get('name')
|
||||
nick = request.data.get('nick')
|
||||
code = ''.join(
|
||||
random.choices(string.ascii_uppercase, k=6))
|
||||
clientId = str(uuid4())
|
||||
room = Room(name=name, owner={'name': nick, 'code': code, "clientId": clientId}, participants=[{'nick': nick, 'owner': True, 'code': code, "clientId": clientId}]
|
||||
)
|
||||
room.save()
|
||||
|
||||
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)
|
||||
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)
|
||||
|
||||
def get(self, request, format=None):
|
||||
code = request.GET.get('code')
|
||||
|
||||
room = None
|
||||
|
||||
try:
|
||||
room = Room.objects.filter(id_code=code)[0]
|
||||
except IndexError:
|
||||
return Response({'error': 'Aucune salle trouvée', 'code': '4044'}, status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
clientId = request.GET.get('clientId')
|
||||
participants = room.participants
|
||||
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)
|
||||
|
||||
admin = False
|
||||
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": 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):
|
||||
code = request.data.get('code')
|
||||
@ -105,7 +124,13 @@ class RoomAPI(APIView):
|
||||
@api_view(['GET'])
|
||||
def RoomExist(request, id_code):
|
||||
if Room.objects.filter(id_code=id_code).count() > 0:
|
||||
return Response({'data': {"id_code": id_code}}, status=status.HTTP_200_OK)
|
||||
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:
|
||||
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
|
||||
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)
|
||||
|
||||
exos = parcours.exercices
|
||||
@ -200,6 +229,8 @@ class ChallengeAPI(APIView):
|
||||
exos = request.data.get('exos')
|
||||
parcours_id = request.data.get('id_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')
|
||||
|
||||
parcours = Parcours.objects.filter(id_code=parcours_id)
|
||||
@ -214,14 +245,18 @@ class ChallengeAPI(APIView):
|
||||
correctionDB = corrections[0]
|
||||
|
||||
participants = list(
|
||||
filter(lambda p: p['code'] == user_code, room.participants))
|
||||
if(len(participants) == 0):
|
||||
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 and not userInRoom:
|
||||
return Response({'error': 'Vous n\'êtes pas un participant'}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
# Corriger selon la correction les exos envoyé dans exos.exos
|
||||
student_answer = exos['result']
|
||||
correction = correctionDB.correction
|
||||
inpppp = 0
|
||||
|
||||
def corrige(ans):
|
||||
correctionExos = list(
|
||||
@ -234,7 +269,8 @@ class ChallengeAPI(APIView):
|
||||
|
||||
correctInputs = exoCorrect['inputs']
|
||||
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)
|
||||
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]
|
||||
@ -243,26 +279,25 @@ class ChallengeAPI(APIView):
|
||||
return {**ans, "exos": corrigedList}
|
||||
|
||||
corriged = list((map(corrige, student_answer)))
|
||||
|
||||
#l6 = uniquement les isCorrect
|
||||
|
||||
# l6 = uniquement les isCorrect
|
||||
l2 = [exs['exos'] for exs in corriged]
|
||||
l4 = [ex['inputs'] for exs in l2 for ex in exs]
|
||||
l5 = [ex for exs in l4 for ex in exs]
|
||||
l6 = [e['isCorrect'] for e in l5]
|
||||
|
||||
|
||||
|
||||
note = {
|
||||
"total": len(l6),
|
||||
"value": l6.count(True),
|
||||
"isTrust": l6.count(None) == 0
|
||||
}
|
||||
adding_challenger = Parcours.objects.challenge(
|
||||
parcours_id, user_code, {"result": corriged, "timer": exos['timer'], "note": note})
|
||||
parcours_id, user_code, {"result": corriged, "timer": exos['timer'], "note": note}, request.user.is_authenticated)
|
||||
correctionDB.delete()
|
||||
|
||||
|
||||
channel_layer = get_channel_layer()
|
||||
async_to_sync(channel_layer.group_send)(f"owner__{room.id_code}", {
|
||||
'type': "challenge_parcours", 'id_code': parcours_id, "participant": participants[0], "validate": adding_challenger['validate'], 'exos': {'note': note, 'endAt': getNow(), "timer": exos['timer']}})
|
||||
'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)
|
||||
|
||||
def put(self, request, format=None):
|
||||
@ -272,7 +307,7 @@ class ChallengeAPI(APIView):
|
||||
clientId = request.data.get('clientId')
|
||||
user_code = request.data.get('user_code')
|
||||
note = request.data.get('note')
|
||||
|
||||
|
||||
print(f'PARCOURS: {parcours_id}')
|
||||
parcours = Parcours.objects.filter(id_code=parcours_id)
|
||||
if len(parcours) == 0:
|
||||
@ -282,7 +317,7 @@ class ChallengeAPI(APIView):
|
||||
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))
|
||||
|
||||
@ -300,10 +335,11 @@ class ChallengeAPI(APIView):
|
||||
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}]}]
|
||||
*list(filter(lambda p: p['code'] != user_code, parcours.challenger)), {**challenger[0], "validate": date if note['value'] * 20 / note['total'] >= condition else False, "exos": [*list(filter(lambda c: c['code'] != challenge_code, trys)), {**challenge, "result": result, "note": note}]}]
|
||||
parcours.save()
|
||||
return Response({"data": {}}, status=status.HTTP_200_OK)
|
||||
|
||||
|
||||
class ParcoursAPI(APIView):
|
||||
|
||||
def delete(self, request, format=None):
|
||||
@ -394,9 +430,12 @@ class ParcoursAPI(APIView):
|
||||
|
||||
room = parcours.room
|
||||
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)
|
||||
|
||||
exos = parcours.exercices
|
||||
|
Binary file not shown.
6
backend/api/uploads/exercices/exo_BCCMKX/main.py
Normal file
6
backend/api/uploads/exercices/exo_BCCMKX/main.py
Normal file
@ -0,0 +1,6 @@
|
||||
import random
|
||||
|
||||
def main():
|
||||
return {'calcul': f'1 + [3] = 4'}
|
||||
|
||||
print('test')
|
10
backend/api/uploads/exercices/exo_CPJLYD/main.py
Normal file
10
backend/api/uploads/exercices/exo_CPJLYD/main.py
Normal 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}
|
10
backend/api/uploads/exercices/exo_CYLRGK/main.py
Normal file
10
backend/api/uploads/exercices/exo_CYLRGK/main.py
Normal 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}
|
10
backend/api/uploads/exercices/exo_DAABOY/main.py
Normal file
10
backend/api/uploads/exercices/exo_DAABOY/main.py
Normal 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}
|
10
backend/api/uploads/exercices/exo_DLILZI/main.py
Normal file
10
backend/api/uploads/exercices/exo_DLILZI/main.py
Normal 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}
|
10
backend/api/uploads/exercices/exo_DSMBIT/main.py
Normal file
10
backend/api/uploads/exercices/exo_DSMBIT/main.py
Normal 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}
|
10
backend/api/uploads/exercices/exo_EJTHGG/main.py
Normal file
10
backend/api/uploads/exercices/exo_EJTHGG/main.py
Normal 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}
|
10
backend/api/uploads/exercices/exo_ERDIGN/main.py
Normal file
10
backend/api/uploads/exercices/exo_ERDIGN/main.py
Normal 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
Loading…
Reference in New Issue
Block a user