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
|
/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
|
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
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -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.
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 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):
|
||||||
|
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
|
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')
|
||||||
|
|
||||||
|
@ -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),
|
||||||
]
|
]
|
||||||
|
@ -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')
|
||||||
|
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,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()
|
||||||
|
if self.scope['user'].is_anonymous:
|
||||||
nick = text_data_json['data']['nick']
|
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)
|
||||||
|
if self.scope['user'].is_anonymous:
|
||||||
new_participant = await self.add_participant(nick, self.clientId)
|
new_participant = await self.add_participant(nick, self.clientId)
|
||||||
self.user = new_participant
|
self.user = new_participant
|
||||||
print('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
|
||||||
|
if status == 'anonymous':
|
||||||
new_participant = await self.add_participant(nick, str(uuid4()))
|
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,15 +168,39 @@ 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']
|
||||||
|
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:
|
||||||
|
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:
|
||||||
participants = await self.get_participants()
|
participants = await self.get_participants()
|
||||||
|
|
||||||
if client in list(map(lambda p: p['clientId'], participants)):
|
if client in list(map(lambda p: p['clientId'], participants)):
|
||||||
self.clientId = client
|
self.clientId = client
|
||||||
|
|
||||||
participant = list(filter(lambda p: p['clientId'] == client, participants))[0]
|
participant = list(
|
||||||
|
filter(lambda p: p['clientId'] == client, participants))[0]
|
||||||
|
|
||||||
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']:
|
||||||
print('add in admin')
|
print('add in admin')
|
||||||
@ -154,24 +220,26 @@ class RoomConsumer(AsyncWebsocketConsumer):
|
|||||||
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"]
|
||||||
|
if status == 'anonymous':
|
||||||
await self.del_participant(code)
|
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):
|
||||||
|
if self.scope['user'].is_anonymous:
|
||||||
return Room.objects.disconnect(self.room_id, self.user['code'])
|
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}))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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
|
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,7 +45,7 @@ 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
|
||||||
@ -52,15 +55,45 @@ class RoomManager(models.Manager):
|
|||||||
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, }
|
new_waiter = {'nick': new_name, 'code': code, "status": 'user' if isUser == True else 'anonymous'}
|
||||||
room.waiters = [*waiters, new_waiter]
|
room.waiters = [*waiters, new_waiter]
|
||||||
room.save()
|
room.save()
|
||||||
return new_waiter
|
return new_waiter
|
||||||
@ -100,50 +132,61 @@ 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)
|
||||||
|
anonymousMembers = models.JSONField(default=list, null=True)
|
||||||
|
userMembers = models.ManyToManyField("users.CustomUser")
|
||||||
waiters = models.JSONField(default=list)
|
waiters = models.JSONField(default=list)
|
||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
owner = models.JSONField(default=dict)
|
owner = models.JSONField(default=dict)
|
||||||
public_result = models.BooleanField(default=False)
|
public_result = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
online = models.JSONField(default=list)
|
||||||
private = models.BooleanField(default=True)
|
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(
|
challenger = list(
|
||||||
filter(lambda p: p['code'] == user_code, parcours.room.participants))[0]
|
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
|
validate = None
|
||||||
|
|
||||||
date = getNow()
|
date = getNow()
|
||||||
@ -153,7 +196,7 @@ class ParcoursManager(models.Manager):
|
|||||||
result['note']['total'] >= condition else False
|
result['note']['total'] >= condition else False
|
||||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||||
parcours.challenger = [*parcours.challenger,
|
parcours.challenger = [*parcours.challenger,
|
||||||
{**challenger, 'exos': [{**result, 'endAt': date, 'code':code}], "validate": validate}]
|
{**challenger, 'exos': [{**result, 'endAt': date, 'code': code}], "validate": validate}]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
validate = False
|
validate = False
|
||||||
@ -166,13 +209,13 @@ class ParcoursManager(models.Manager):
|
|||||||
oldChallenger = challengers[0]['exos']
|
oldChallenger = challengers[0]['exos']
|
||||||
while True:
|
while True:
|
||||||
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
code = ''.join(random.choices(string.ascii_uppercase, k=6))
|
||||||
if len(list(filter(lambda c:c['code'] == code, oldChallenger))) == 0:
|
if len(list(filter(lambda c: c['code'] == code, oldChallenger))) == 0:
|
||||||
break
|
break
|
||||||
parcours.challenger = [*list(filter(lambda c: c['code'] != challenger['code'], parcours.challenger)),
|
parcours.challenger = [*list(filter(lambda c: c['code'] != challenger['code'], parcours.challenger)),
|
||||||
{**challenger, 'exos': [*challengers[0]['exos'], {**result, 'endAt': date, "code": code}], "validate": validate}]
|
{**challenger, 'exos': [*challengers[0]['exos'], {**result, 'endAt': date, "code": code}], "validate": validate}]
|
||||||
|
|
||||||
parcours.save()
|
parcours.save()
|
||||||
return {'validate': validate}
|
return {'validate': validate, 'code': code}
|
||||||
|
|
||||||
|
|
||||||
class Parcours(models.Model):
|
class Parcours(models.Model):
|
||||||
@ -189,6 +232,8 @@ class Parcours(models.Model):
|
|||||||
|
|
||||||
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)
|
||||||
|
@ -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):
|
||||||
|
@ -25,13 +25,23 @@ 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')
|
||||||
|
|
||||||
|
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')
|
nick = request.data.get('nick')
|
||||||
code = ''.join(
|
code = ''.join(
|
||||||
random.choices(string.ascii_uppercase, k=6))
|
random.choices(string.ascii_uppercase, k=6))
|
||||||
clientId = str(uuid4())
|
clientId = str(uuid4())
|
||||||
room = Room(name=name, owner={'name': nick, 'code': code, "clientId": clientId}, participants=[{'nick': nick, 'owner': True, 'code': code, "clientId": clientId}]
|
room = Room(name=name, owner={'name': nick, 'code': code, "clientId": clientId}, anonymousMembers=[{'nick': nick, 'owner': True, 'code': code, "clientId": clientId}]
|
||||||
)
|
)
|
||||||
room.save()
|
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)
|
||||||
@ -40,22 +50,31 @@ class RoomAPI(APIView):
|
|||||||
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
|
||||||
|
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