Generateurv2/backend/api/exercices/views.py
2022-05-18 10:15:54 +02:00

304 lines
14 KiB
Python

import base64
from cmath import inf
import csv
import importlib.util
import io
import os
import re
import subprocess
import tempfile
from django.http import FileResponse, HttpResponse
from django.shortcuts import render
from time import sleep
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.template.loader import get_template
import sympy
from .pdfmaker import pdf_settings
from .utils import TexError, checkExoModelObject
import requests
from api.Generateur import Csv_generator, Generateur
from .models import Exercice, Tag
from .serializers import ExerciceCreateSerializer, ExerciceSerializer, TagSerializer
# Create your views here.
class ExerciceAPI(APIView):
def get(self, request, format=None):
steps = Exercice.objects.all()
code_separ = '<@!code>\r\n'
code = request.GET.get('code')
nb_in_page = 24
if code == 'all':
return Response({"data": list(map(lambda ex: {**ExerciceSerializer(ex).data, 'exo_model': {'filename': ex.exo_model.name.split('/')[-1], "data": open(ex.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, ex.tags))}, steps))}, status=status.HTTP_200_OK)
elif code == "pdf":
return Response({"data": list(map(lambda ex: {**ExerciceSerializer(ex).data, 'exo_model': {'filename': ex.exo_model.name.split('/')[-1], "data": open(ex.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, ex.tags))}, list(filter(lambda s:s.isPdf == True, steps))))}, status=status.HTTP_200_OK)
elif code == "web":
return Response({"data": list(map(lambda ex: {**ExerciceSerializer(ex).data, 'exo_model': {'filename': ex.exo_model.name.split('/')[-1], "data": open(ex.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, ex.tags))}, list(filter(lambda s:s.isWeb == True, steps))))}, status=status.HTTP_200_OK)
elif code != 'all' and code != 'pdf' and code != "web":
exo = Exercice.objects.filter(id_code=code)[0]
print(open(exo.exo_model.name, 'r').read())
return Response({"data": {**ExerciceSerializer(exo).data, 'exo_model': {'filename': exo.exo_model.name.split('/')[-1], "data": open(exo.exo_model.name, 'r').read()}, "tags": list(map(lambda t: {**TagSerializer(Tag.objects.filter(id_code=t)[0]).data, 'value': Tag.objects.filter(id_code=t)[0].id_code, 'label': Tag.objects.filter(id_code=t)[0].name}, exo.tags))}}, status=status.HTTP_200_OK)
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)
def post(self, request, format=None):
file = request.FILES['file']
name = request.data.get('name')
consigne = request.data.get('consigne')
create_serializer = ExerciceCreateSerializer(
data={'exo_model': file, "consigne": consigne, "name": name}, context={'request': request})
if create_serializer.is_valid():
print(create_serializer.validated_data['exo_model'])
new_exo = Exercice(consigne=consigne,
exo_model=create_serializer.validated_data['exo_model']['file'], name=name)
new_exo.exemple = [] # Generateur(exo_model, 5)
new_exo.isPdf = create_serializer.validated_data['exo_model']['isPdf']
new_exo.isCsv = create_serializer.validated_data['exo_model']['isCsv']
new_exo.isWeb = create_serializer.validated_data['exo_model']['isWeb']
new_exo.save()
# sleep(2)
return Response({"status": "200", "errors": {}, "data": ExerciceSerializer(new_exo).data}, status=status.HTTP_200_OK)
print(create_serializer.errors, 'errs')
return Response({"status": "400", "errors": create_serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
def put(self, request, format=None):
file = request.FILES['file']
name = request.data.get('name')
consigne = request.data.get('consigne')
exo_model = request.data.get('exo_model')
id_code = request.data.get('id_code')
exo = Exercice.objects.filter(id_code=id_code)[0]
serializer = ExerciceCreateSerializer(
data={'exo_model': file, "consigne": consigne, "name": name})
errors = []
if serializer.is_valid():
exo.name = name
exo.consigne = consigne
exo.exo_model = serializer.validated_data['exo_model']['file']
exo.exemple =[]
exo.isPdf = serializer.validated_data['exo_model']['isPdf']
exo.isCsv = serializer.validated_data['exo_model']['isCsv']
exo.isWeb = serializer.validated_data['exo_model']['isWeb']
exo.save()
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)
def delete(self, request, format=None):
id_code = request.data.get('id_code')
exo = Exercice.objects.filter(id_code=id_code)[0]
exo.delete()
# sleep(2)
return Response({'status': "200", "data": id_code}, status=status.HTTP_200_OK)
class TagsAPI(APIView):
def get(self, request, format=None):
tags = Tag.objects.all()
return Response({"data": list(map(lambda tag: {**TagSerializer(tag).data, 'label': tag.name, "value": tag.id_code}, tags))}, status=status.HTTP_200_OK)
def post(self, request, format=None):
options = request.data.get('tags')
step = request.data.get('step')
step = Exercice.objects.filter(id_code=step)[0]
tagsList = []
for o in options:
# print(o)
if o['value'].startswith('new_opt'):
newTag = Tag(name=o['label'], color=o['color'])
newTag.save()
oldTags = step.tags
step.tags = [*oldTags, newTag.id_code]
step.save()
tagsList.append(
{'name': o['label'], 'color': o['color'], 'id_code': newTag.id_code})
else:
tagId = o['value']
tag = Tag.objects.filter(id_code=tagId)[0]
oldTags = step.tags
step.tags = [*oldTags, tag.id_code]
step.save()
tagsList.append(
{'name': o['label'], 'color': o['color'], 'id_code': tag.id_code})
return Response({'tags': tagsList}, status=status.HTTP_200_OK)
def delete(self, request, format=None):
tag = request.data.get('tag')
step = Exercice.objects.filter(id_code=request.data.get('step'))[0]
step.tags = list(filter(lambda t: t != tag, step.tags))
step.save()
tagObj = Tag.objects.filter(id_code=tag)[0]
return Response({"data": {"name": tagObj.name}}, status=status.HTTP_200_OK)
class Editor(APIView):
def post(self, request, format=None):
code = request.data.get('code')
if code == None:
return Response([''], status=status.HTTP_200_OK)
with tempfile.TemporaryDirectory() as tempdir:
with open(os.path.join(tempdir, "tmp.py"), 'w') as script:
script.write(code)
proc = subprocess.Popen(['python3.10', 'tmp.py', ],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=tempdir)
print(open(os.path.join(tempdir, "tmp.py"), 'r').read())
out, err = proc.communicate()
out = out.decode().splitlines()
return Response({"out": out, "error": err.decode('utf-8').splitlines()}, status=status.HTTP_200_OK)
class CSV_Generator(APIView):
def get(self, request, code, format=None):
ex = Exercice.objects.filter(id_code=code)[0]
if ex.isCsv == False:
return Response({'error': "Bah non en fait"}, status=status.HTTP_401_UNAUTHORIZED)
model = ex.exo_model.name
consigne = ex.consigne
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment;filename="test.csv"'
writer = csv.writer(response, delimiter=',',
quotechar=',', quoting=csv.QUOTE_MINIMAL, dialect='excel') # mettre | comme sep un jour
Csv_generator(model, 10, 10, 10,
consigne, writer)
return response
class PDF(APIView):
def post(self, request, format=None):
print('exos', request.data.get('exos'))
exos = list(map(lambda ex: pdf_settings(
Exercice.objects.filter(id_code=ex['id_code'])[0].exo_model.name, 14, int(ex['numberInExo']), int(ex['numberOfExo']), 1, ex['consigne']), request.data.get('exos')))
# print(exos)
# dans str mettre space(0.5) replace by \hspace{0.5cm}
template_name = 'test.tex'
symbols = {
"": "\\approx",
'': '\\neq',
"": "\\simeq"
}
# a refaire pour supp les symbols
for e in range(len(exos)):
for exo in range(len(exos[e]['exos'])):
# print(exos[e]['exos'][exo])
exos[e]['exos'][exo]['calcul'] = sympy.latex(
exos[e]['exos'][exo]['calcul'])
exos[e]['exos'][exo]['calcul'] = exos[e]['exos'][exo]['calcul'].replace(
'', '\\ensuremath{\\simeq}')
exos[e]['exos'][exo]['calcul'] = exos[e]['exos'][exo]['calcul'].replace(
'', '\\ensurmath{\approx}')
exos[e]['exos'][exo]['calcul'] = exos[e]['exos'][exo]['calcul'].replace(
'', '\\ensuremath{\neq}')
exos[e]['exos'][exo]['correction'] = sympy.latex(
exos[e]['exos'][exo]['correction'])
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
'', '\\ensuremath{\\simeq}')
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
'', '\\ensurmath{\approx}')
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
'', '\\ensuremath{\neq}')
exp_list = re.findall(
r'\[([A-Za-z0-9_]+)\]', exos[e]['exos'][exo]['correction'])
red = '{red}'
for exp in exp_list:
exos[e]['exos'][exo]['correction'] = exos[e]['exos'][exo]['correction'].replace(
f'[{exp}]', f'\\textcolor{red}{{{exp}}}')
context = {'exos': exos, 'title': request.data.get(
'title'), 'police': request.data.get('police')}
template = get_template('test.tex')
latex = template.render(context) # latex to compile
# print(latex)
with tempfile.TemporaryDirectory() as tempdir:
direct = tempdir
with open(os.path.join(direct, 'tmp.tex'), 'x', encoding='utf-8') as f:
f.write(latex)
command = f'xelatex -interaction=batchmode tmp.tex'
try:
subprocess.run(command, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
cwd=direct)
except TexError:
raise TexError(log=log, source=latex,
template_name='test.tex')
try:
subprocess.run(command, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
cwd=direct)
except TexError:
raise TexError(log=log, source=latex,
template_name='test.tex')
with open(os.path.join(direct, 'tmp.pdf'), 'rb') as out:
pdf = out.read()
buffer = io.BytesIO(out.read())
fich_name = request.data.get('file')
if fich_name.count('.') >= 1:
ext = fich_name.split('.')[-1]
# print(ext)
if ext == 'pdf':
fich_name = fich_name
elif ext != 'pdf':
# print('nipe')
fich_name = fich_name.replace(f'.{ext}', '.pdf')
else:
fich_name = fich_name + '.pdf'
return Response({'pdf': base64.b64encode(pdf), 'filename': fich_name}, status=status.HTTP_200_OK)
''' return PDFResponse(base64.b64encode(pdf), filename=fich_name)
subprocess.run('ls', cwd=direct)
'''
class Test(APIView):
def get(self, request, format=None):
code = "VZRKLZ"
ex = Exercice.objects.filter(id_code=code)[0]
model = ex.exo_model
print('model', model.name)
oplist = Generateur(model.name, 2, 'calcul')
return Response({"data": oplist}, status=status.HTTP_200_OK)
class ExoModelApi(APIView):
def get(self, request, format=None):
code = request.GET.get('code')
exo = Exercice.objects.filter(id_code=code)[0]
print(exo.exo_model.name)
model = open(exo.exo_model.name, 'rb')
return FileResponse(model, status=status.HTTP_200_OK)