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, SelectMultipleField, widgets, FieldList, FormField, HiddenField from wtforms.validators import DataRequired, Regexp, Optional, ValidationError from wtforms_alchemy import model_form_factory, ClassMap from wtforms_alchemy.fields import QuerySelectMultipleField from sqlalchemy_utils import ChoiceType 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) categorie_liste = ["saes","ressources","acs"] categorie_to_model = {"saes": "SAE", "ressources": "Ressource", "acs": "AC"} separateur = None BaseModelForm = model_form_factory(FlaskForm, include_primary_keys=True) class ModelForm(BaseModelForm): @classmethod def get_session(self): return db.session class RefListField(QuerySelectMultipleField): option_widget=widgets.CheckboxInput() class AccueilForm(FlaskForm): ajouter = SubmitField("Ajouter") reset = SubmitField("Reset") exporter = SubmitField("Exporter") importer = SubmitField("Importer") class CoefForm(FlaskForm): objetformation = HiddenField("Objet de formation") coef = StringField("Coef") class UEForm(FlaskForm): ue = HiddenField("Competence") acs = RefListField("Liste des ACs", query_factory=lambda: models.AC.query.all(), get_label=lambda ref: ref.getLabel()) ressources = RefListField("Liste des Ressources inclus dans les ACs", query_factory=lambda: [], get_label=lambda ref: ref.getLabel()) saes = RefListField("Liste des SAEs inclus dans les ACs", query_factory=lambda: [], get_label=lambda ref: ref.getLabel()) coef = FieldList(FormField(CoefForm)) class SemestreForm(FlaskForm): ues = RefListField("Liste des UEs", query_factory=lambda: models.Competence.query.all(), get_label=lambda ref: ref.getLabel()) ueform = FieldList(FormField(UEForm)) update = SubmitField("Update") class Form(ModelForm): class Meta: not_null_validator_type_map = ClassMap({db.String: [DataRequired()]}) 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()]) def chargerRef(self): if self.referentiel.data == None: self.referentiel.errors.append("Aucun référentiel n'a été selectionné!") return False else: return True def chargerBDD(self, referentiel): for categorie in list(self.data.keys())[7:-1]: self[categorie].process_data(referentiel.__dict__[categorie]) self.referentiel.process_data(referentiel) def importerRef(self): if len(self.fichier.errors) == 0: if self.fichier.data.filename == "": self.fichier.errors.append("Aucun fichier selectioné.") return if re.match(self.regex, self.fichier.data.filename[:-4]) == None: self.fichier.errors.append("Mauvais type de référentiel!") return fichier_Yaml = yaml.safe_load(self.fichier.data.read()) for categorie, valeur in fichier_Yaml.items(): if categorie in categorie_liste: model = getattr(models, categorie_to_model[categorie]) self[categorie].process_data([model.query.filter_by(code=ref).first() for ref in valeur]) else: self[categorie].process_data(valeur) self.validate() def exporterRef(self): """ Exporte dans un fichier yaml les informations du formulaire rempli """ output = {} for categorie, valeur in list(self.data.items())[7:-1]: if categorie in categorie_liste: output[categorie] = [ referentiel.code for referentiel in valeur ] else: output[categorie] = valeur fichier = REPERTOIRE_YAML + self.code.data + ".yml" with open(fichier, "w", encoding="utf8") as fid: fid.write(yaml.dump(output)) print(yaml.dump(output)) def supprimerRef(self): if self.referentiel.data == None: self.referentiel.erros.append("Aucun référentiel n'a été selectionné!") return False else: temp = self.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 def sauvegarderRef(self): model = getattr(models, self.__class__.__name__[:-4]) referentiel = model.query.filter_by(code=self.code.data).first() if referentiel == None: referentiel = model() self.populate_obj(referentiel) db.session.add(referentiel) db.session.commit() class PNForm(Form): regex = "^PN\d$" class Meta: model = models.PN type = RadioField("Type", choices=["1","2","3"]) class ACForm(Form): regex = "^AC\d{4}$" class Meta: model = models.AC saes = RefListField("Liste des SAEs", query_factory=lambda: models.SAE.query.all(), get_label=lambda ref: ref.getLabel()) ressources = RefListField("Liste des Ressources", query_factory=lambda: models.Ressource.query.all(), get_label=lambda ref: ref.getLabel()) class SAEForm(Form): regex = "^SAE\d{2}$" class Meta: model = models.SAE acs = RefListField("Liste des ACs", query_factory=lambda: models.AC.query.all(), get_label=lambda ref: ref.getLabel()) ressources = RefListField("Liste des Ressources", query_factory=lambda: models.Ressource.query.all(), get_label=lambda ref: ref.getLabel()) class RessourceForm(Form): regex = "^R\d{3}$" class Meta: model = models.Ressource acs = RefListField("Liste des ACs", query_factory=lambda: models.AC.query.all(), get_label=lambda ref: ref.getLabel()) saes = RefListField("Liste des SAEs", query_factory=lambda: models.SAE.query.all(), get_label=lambda ref: ref.getLabel()) class CompetenceForm(Form): regex = "^RT\d$" class Meta: model = models.Competence