generateur_v3/backend/api/services/exoValidation.py
2022-09-16 21:50:55 +02:00

102 lines
3.0 KiB
Python

from fastapi.exceptions import HTTPException
from fastapi import UploadFile, status
from tortoise.validators import Validator
from tortoise.exceptions import ValidationError
import types
from services.timeout import timeout
from services.io import is_binary_file
import os
def checkExoSupportCompatibility(obj):
isPdf = False if (obj['pdf'] == None or (
obj['calcul'] == False and obj['pdf'] == False)) else True
isCsv = False if (obj['csv'] == None or (
obj['calcul'] == False and obj['csv'] == False)) else True
isWeb = False if (obj['web'] == None or (
obj['calcul'] == False and obj['web'] == False)) else True
return {
'pdf': isPdf, 'csv': isCsv, 'web': isWeb}
def get_module_from_string(value: str, *args, **kwargs):
locs = {}
try:
exec(value, dict(), locs)
except Exception as err:
raise ValueError(err)
return locs
def execute_main_if_avalaible(spec, *args, **kwargs):
try:
return spec["main"]()
except KeyError as atrerror:
raise ValueError(f"Fonction 'main' introuvable")
except Exception as e:
raise ValueError(f'[Error] : {e}')
def get_spec_with_timeout(data, time):
return get_module_from_string(data)
with timeout(time, ValidationError('[Error] : Script took too long')):
return get_module_from_string(data)
def fill_empty_values(object):
default_object = {"calcul": False, 'pdf': False, 'csv': False,
'web': False, 'correction': False}
return {**default_object, **object}
def get_support_from_data(data: str):
locs = get_spec_with_timeout(data, 5)
result = execute_main_if_avalaible(locs)
result = fill_empty_values(result)
exo_supports_compatibility = checkExoSupportCompatibility(result)
return exo_supports_compatibility
def get_support_from_path(path: str):
if not os.path.exists(path):
raise ValidationError('[Error] : No such file or directory')
is_binary = is_binary_file(path)
if is_binary:
mode = 'rb'
else:
mode = 'r'
with open(path, mode) as f:
data = f.read() if mode == "r" else f.read().decode('utf8')
return get_support_from_data(data)
async def validate_file(file: UploadFile):
data = await file.read()
try:
exo_supports_compatibility = get_support_from_data(
data)
if not exo_supports_compatibility['pdf'] and not exo_supports_compatibility['csv'] and not exo_supports_compatibility['web']:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail={"exo_source_error":
'Exercice non valide (compatible avec aucun support)'})
except ValueError as e:
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail={
"exo_source_error": e.args[0]})
except HTTPException as e:
raise e
await file.seek(0)
return file
async def validate_file_optionnal(file: UploadFile = None):
if not file:
return None
return await validate_file(file)