EditionPN/app/forms.py

185 lines
9.2 KiB
Python

from flask import redirect, url_for
from flask_wtf import FlaskForm
from flask_wtf.file import FileAllowed
from wtforms import StringField, SubmitField, FileField, TextAreaField, RadioField
from wtforms.validators import DataRequired, Regexp, Optional, ValidationError
from app import db
import app.models as models
import yaml
import os
import re
REPERTOIRE_YAML = "./export/"
if not os.path.exists(REPERTOIRE_YAML):
os.makedirs(REPERTOIRE_YAML)
def validate_ref_list(regex, message):
def _validate_ref_list(form, field):
refs = field.data.strip() + " "
if re.match(regex, refs) == None:
raise ValidationError(message)
return _validate_ref_list
class Form(FlaskForm):
sauvegarder = SubmitField("Sauvegarder")
charger = SubmitField("Charger")
supprimer = SubmitField("Supprimer")
exporter = SubmitField("Exporter")
fichier = FileField("Choisir fichier", validators=[FileAllowed(["yml"], "Fichier Yaml seulement!")])
importer = SubmitField("Importer")
referentiel = RadioField("Liste des référentiels", validators=[Optional()])
class PNForm(Form):
regex = "^PN\d$"
code = StringField("Code", validators=[DataRequired(), Regexp("^PN\d$", message="Le code doit être de la forme PN0.")])
nom = StringField("Nom", validators=[DataRequired()] )
diminutif = StringField("Diminutif", validators=[DataRequired()] )
description = TextAreaField("Description", validators=[DataRequired()] )
type = RadioField("Type", choices=["1","2","3"], validators=[DataRequired()])
class ACForm(Form):
regex = "^AC\d{4}$"
code = StringField("Code", validators=[DataRequired(), Regexp("^AC\d{4}$", message="Le code doit être de la forme AC0000.")])
titre = StringField("Titre", validators=[DataRequired()] )
saes = StringField("SAEs", validators=[DataRequired(), validate_ref_list("^(\s*(SAE\d{2}\s+)*)$", message="Les saes doit être de la forme SAE00.")] )
ressources = StringField("Ressources", validators=[DataRequired(), validate_ref_list("^(\s*(R\d{3}\s+)*)$", message="Les ressources doit être de la forme R000.")] )
class SAEForm(Form):
regex = "^SAE\d{2}$"
code = StringField("Code", validators=[DataRequired(), Regexp("^SAE\d{2}$", message="Le code doit être de la forme SAE00.")])
titre = StringField("Titre", validators=[DataRequired()] )
semestre = StringField("Semestre", validators=[DataRequired()] )
heures_encadrees = StringField("Heures encadrées", validators=[DataRequired()] )
heures_tp = StringField("Heures TP", validators=[DataRequired()] )
projet = StringField("Projet", validators=[DataRequired()] )
description = TextAreaField("Description", validators=[DataRequired()] )
coef = StringField("Coef.", validators=[DataRequired()] )
acs = StringField("ACs", validators=[DataRequired(), validate_ref_list("^(\s*(AC\d{4}\s+)*)$", message="Les acs être de la forme AC0000.")] )
ressources = StringField("Ressources", validators=[DataRequired(), validate_ref_list("^(\s*(R\d{3}\s+)*)$", message="Les ressources doit être de la forme R000.")] )
livrables = TextAreaField("Livrables", validators=[DataRequired()] )
motscles = StringField("Mots clés", validators=[DataRequired()] )
class RessourceForm(Form):
regex = "^R\{3}$"
code = StringField("Code", validators=[DataRequired(), Regexp("^R\{3}$", message="Le code doit être de la forme R000.")])
nom = StringField("Nom", validators=[DataRequired()] )
semestre = StringField("Semestre", validators=[DataRequired()] )
heures_formation = StringField("Heures formation", validators=[DataRequired()] )
heures_tp = StringField("Heures TP", validators=[DataRequired()] )
coef = StringField("Coef.", validators=[DataRequired()] )
acs = StringField("ACs", validators=[DataRequired(), validate_ref_list("^(\s*(AC\d{4}\s+)*)$", message="Les acs doit être de la forme AC0000.")] )
saes = StringField("SAEs", validators=[DataRequired(), validate_ref_list("^(\s*(SAE\d{2}\s+)*)$", message="Les saes doit être de la forme SAE00.")] )
prerequis = StringField("Prérequis", validators=[DataRequired()] )
contexte = TextAreaField("Contexte", validators=[DataRequired()] )
contenu = TextAreaField("Contenu", validators=[DataRequired()] )
motscles = StringField("Mots clés", validators=[DataRequired()] )
class CompetenceForm(Form):
regex = "^RT\d$"
code = StringField("Code", validators=[DataRequired(), Regexp("^RT\d$", message="Le code doit être de la forme RT0.")])
nom = StringField("Nom", validators=[DataRequired()] )
diminutif = StringField("Diminutif", validators=[DataRequired()] )
description = TextAreaField("Description", validators=[DataRequired()] )
composantes = TextAreaField("Composantes", validators=[DataRequired()] )
situations = TextAreaField("Situations", validators=[DataRequired()] )
niveaux = TextAreaField("Niveaux", validators=[DataRequired()] )
categorie_liste = ["saes","ressources","acs"]
categorie_to_model = {"saes": "SAE", "ressources": "Ressource", "acs": "AC"}
separateur = None
def form_import(form):
""" Si le bouton import a été appuyé et qu'il n'y a pas d'erreur d'import => importe le fichier yaml"""
# Bouton import appuyé et fichier yaml selectionné
if form.importer.data and len(form.fichier.errors) == 0:
if form.fichier.data.filename == "":
form.fichier.errors.append("Aucun fichier selectioné.")
return form
if re.match(form.regex, form.fichier.data.filename[:-4]) == None:
form.fichier.errors.append("Mauvais type de référentiel!")
return form
fichier_Yaml = yaml.safe_load(form.fichier.data.read())
for categorie, valeur in fichier_Yaml.items():
if categorie in categorie_liste:
form[categorie].process_data(" ".join(valeur))
else:
form[categorie].process_data(valeur)
form.validate_on_submit() # Réinitialise les messages d'erreur
return form
def form_export(form):
""" Si le formulaire est valide => exporte dans un fichier yaml avec les informations du formulaire """
output = {}
for categorie, valeur in list(form.data.items())[7:-1]:
if categorie in categorie_liste:
output[categorie] = [ referentiel for referentiel in valeur.split(separateur) ]
else:
output[categorie] = valeur
fichier = REPERTOIRE_YAML + form.code.data + ".yml"
with open(fichier, "w", encoding="utf8") as fid:
fid.write(yaml.dump(output))
def form_charger(form):
""" Si le bouton charger est appuyé et qu'un référentiel du BDD a été selectionné => remplie le formulaire avec ses informations """
if form.charger.data:
if form.referentiel.data == None:
form.referentiel.errors.append("Aucun référentiel n'a été selectionné!")
else:
temp = form.referentiel.data[1:-1].split()
model = getattr(models, temp[0])
referentiel = model.query.filter_by(code=temp[1]).first()
for categorie in list(referentiel.__dict__)[1:]:
if categorie in categorie_liste:
form[categorie].process_data(" ".join(ref.code for ref in referentiel.__dict__[categorie]))
else:
form[categorie].process_data(referentiel.__dict__[categorie])
form.validate_on_submit()
return form
def form_sauvegarder(form):
""" Si le bouton sauvegarder est appuyé et que le formulaire est valide => ajoute le référentiel dans la table respectif du base de données """
if form.sauvegarder.data:
model = getattr(models, "".join( c for c in form.code.data if not c.isdigit()))
referentiel = model.query.filter_by(code=form.code.data).first()
if referentiel == None:
referentiel = model()
# Si le référentiel contient une catégorie avec une liste de référentiels
for categorie, valeur in list(form.data.items())[7:-1]:
if categorie in categorie_liste:
resultat = []
refs = [ ref for ref in form[categorie].data.split(separateur) ]
ref_model = getattr(models, categorie_to_model[categorie])
for ref in refs:
ref_bdd = ref_model.query.filter_by(code=ref).first()
if ref_bdd == None:
ref_new = ref_model(code=ref)
resultat.append(ref_new)
db.session.add(ref_new)
else:
resultat.append(ref_bdd)
form[categorie].process_data(resultat)
form.populate_obj(referentiel)
db.session.add(referentiel)
db.session.commit()
def form_supprimer(form):
if form.supprimer.data:
if form.referentiel.data == None:
form.referentiel.errors.append("Aucun référentiel n'a été selectionné!")
else:
temp = form.referentiel.data[1:-1].split()
model = getattr(models, temp[0])
referentiel = model.query.filter_by(code=temp[1]).first()
db.session.delete(referentiel)
db.session.commit()
return True, redirect(url_for(temp[0]))
return False, form