Ajout sauvegarde pour bdd et regex des ref

This commit is contained in:
Éric Li 2021-05-07 18:21:36 +02:00
parent 431df65c8d
commit 3c18b88f2e
9 changed files with 101 additions and 178 deletions

BIN
app.db

Binary file not shown.

View File

@ -1,9 +1,10 @@
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
from wtforms.validators import DataRequired, Regexp, Optional, ValidationError
from app import db
import app.models as models
import yaml
import os
import re
@ -13,6 +14,13 @@ 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")
@ -36,7 +44,7 @@ class ACForm(Form):
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()] )
saes = StringField("SAEs", validators=[DataRequired(), validate_ref_list("^(\s*(SAE\d{2}\s+)*)$", message="Les saes doit être de la forme SAE00.")] )
class SAEForm(Form):
regex = "^SAE\d{2}$"
@ -49,8 +57,8 @@ class SAEForm(Form):
projet = StringField("Projet", validators=[DataRequired()] )
description = TextAreaField("Description", validators=[DataRequired()] )
coef = StringField("Coef.", validators=[DataRequired()] )
acs = StringField("ACs", validators=[DataRequired()] )
ressources = StringField("Ressources", 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()] )
@ -63,8 +71,8 @@ class RessourceForm(Form):
heures_formation = StringField("Heures formation", validators=[DataRequired()] )
heures_tp = StringField("Heures TP", validators=[DataRequired()] )
coef = StringField("Coef.", validators=[DataRequired()] )
acs = StringField("ACs", validators=[DataRequired()] )
saes = StringField("SAEs", 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()] )
@ -81,6 +89,9 @@ class CompetenceForm(Form):
situations = TextAreaField("Situations", validators=[DataRequired()] )
niveaux = TextAreaField("Niveaux", validators=[DataRequired()] )
categorie_liste = ["saes","ressources","acs"]
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é
@ -93,7 +104,10 @@ def form_import(form):
return form
fichier_Yaml = yaml.safe_load(form.fichier.data.read())
for categorie, valeur in fichier_Yaml.items():
form[categorie].process_data(valeur)
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
@ -101,7 +115,10 @@ 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())[6:-1]:
output[categorie] = valeur
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))
@ -116,6 +133,36 @@ def form_charger(form):
model = getattr(models, temp[0])
referentiel = model.query.filter_by(code=temp[1]).first()
for categorie in list(referentiel.__dict__)[1:]:
form[categorie].process_data(referentiel.__dict__[categorie])
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
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())[6:-1]:
if categorie in categorie_liste:
resultat = []
refs = [ ref for ref in form[categorie].data.split(separateur) ]
ref_model = getattr(models, categorie.upper()[:-1])
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()

View File

@ -28,7 +28,7 @@ class PN(db.Model):
class AC(db.Model):
code = db.Column(db.String(6), primary_key = True)
titre = db.Column(db.String(255))
saes = db.relationship("SAE", secondary=SAEs_ACs, lazy=True, backref=db.backref("acs", lazy=True))
saes = db.relationship("SAE", secondary=SAEs_ACs, lazy=False, backref=db.backref("acs", lazy=False))
def __repr__(self):
return "<AC {}>".format(self.code)
@ -43,7 +43,7 @@ class SAE(db.Model):
description = db.Column(db.Text())
coef = db.Column(db.String(255))
#acs = db.relationship("AC", secondary=SAEs_ACs, lazy=True, backref=db.backref("saes", lazy=True))
ressources = db.relationship("Ressource", secondary=Ressources_SAEs, lazy=True, backref=db.backref("saes", lazy=True))
ressources = db.relationship("Ressource", secondary=Ressources_SAEs, lazy=False, backref=db.backref("saes", lazy=False))
livrables = db.Column(db.Text())
motscles = db.Column(db.String(255))

View File

@ -21,13 +21,7 @@ def PN():
if form.exporter.data:
flash("Ajout du référentiel PN: {} ".format(form.code.data))
form_export(form)
if form.sauvegarder.data:
pn = models.PN.query.filter_by(code=form.code.data).first()
if pn == None:
pn = models.PN()
form.populate_obj(pn)
db.session.add(pn)
db.session.commit()
form_sauvegarder(form)
return redirect(url_for("PN"))
return render_template("PN.html", form = form)
@ -42,13 +36,7 @@ def AC():
if form.exporter.data:
flash("Ajout du référentiel AC: {} ".format(form.code.data))
form_export(form)
if form.sauvegarder.data:
ac = models.AC.query.filter_by(code=form.code.data).first()
if ac == None:
ac = models.AC()
form.populate_obj(ac)
db.session.add(ac)
db.session.commit()
form_sauvegarder(form)
return redirect(url_for("AC"))
return render_template("AC.html", form = form)
@ -63,13 +51,7 @@ def SAE():
if form.exporter.data:
flash("Ajout du référentiel SAE: {} ".format(form.code.data))
form_export(form)
if form.sauvegarder.data:
sae = models.SAE.query.filter_by(code=form.code.data).first()
if sae == None:
sae = models.SAE()
form.populate_obj(sae)
db.session.add(sae)
db.session.commit()
form_sauvegarder(form)
return redirect(url_for("SAE"))
return render_template("SAE.html", form = form)
@ -84,13 +66,7 @@ def Ressource():
if form.exporter.data:
flash("Ajout du référentiel Ressource: {} ".format(form.code.data))
form_export(form)
if form.sauvegarder.data:
ressource = models.Ressource.query.filter_by(code=form.code.data).first()
if ressource == None:
ressource = models.Ressource()
form.populate_obj(ressource)
db.session.add(ressource)
db.session.commit()
form_sauvegarder(form)
return redirect(url_for("Ressource"))
return render_template("Ressource.html", form = form)
@ -105,12 +81,6 @@ def Competence():
if form.exporter.data:
flash("Ajout du référentielCompetence: {} ".format(form.code.data))
form_export(form)
if form.sauvegarder.data:
competence = models.Competence.query.filter_by(code=form.code.data).first()
if competence == None:
competence = models.Competence()
form.populate_obj(competence)
db.session.add(competence)
db.session.commit()
form_sauvegarder(form)
return redirect(url_for("Competence"))
return render_template("Competence.html", form = form)

View File

@ -51,7 +51,7 @@
</div>
<ul>
{% for referentiel in form.referentiel %}
<li>{{ referentiel }} {{ referentiel.data.code }} - {{ referentiel.data.nom }}{{ referentiel.data.titre }}</li>
<li>{{ referentiel }} {{ referentiel.data.code }} - {% if referentiel.data.nom == None or referentiel.data.titre == None %}/!\ Référentiel à compléter /!\{% else %}{{ referentiel.data.nom }}{{ referentiel.data.titre }}{% endif %}</li>
{% endfor %}
</ul>
</div>

View File

@ -1,8 +1,8 @@
"""empty message
Revision ID: c000b3a8d714
Revises: c1377d41bf27
Create Date: 2021-05-06 17:50:35.360220
Revision ID: 15feabeae315
Revises:
Create Date: 2021-05-07 16:45:01.928258
"""
from alembic import op
@ -10,8 +10,8 @@ import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'c000b3a8d714'
down_revision = 'c1377d41bf27'
revision = '15feabeae315'
down_revision = None
branch_labels = None
depends_on = None
@ -21,7 +21,14 @@ def upgrade():
op.create_table('AC',
sa.Column('code', sa.String(length=6), nullable=False),
sa.Column('titre', sa.String(length=255), nullable=True),
sa.Column('saes', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('code')
)
op.create_table('PN',
sa.Column('code', sa.String(length=3), nullable=False),
sa.Column('nom', sa.String(length=255), nullable=True),
sa.Column('diminutif', sa.String(length=30), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('type', sa.String(length=1), nullable=True),
sa.PrimaryKeyConstraint('code')
)
op.create_table('SAE',
@ -33,8 +40,6 @@ def upgrade():
sa.Column('projet', sa.String(length=3), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.Column('coef', sa.String(length=255), nullable=True),
sa.Column('acs', sa.String(length=255), nullable=True),
sa.Column('ressources', sa.String(length=255), nullable=True),
sa.Column('livrables', sa.Text(), nullable=True),
sa.Column('motscles', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('code')
@ -56,21 +61,41 @@ def upgrade():
sa.Column('heures_formation', sa.String(length=3), nullable=True),
sa.Column('heures_tp', sa.String(length=3), nullable=True),
sa.Column('coef', sa.String(length=255), nullable=True),
sa.Column('acs', sa.String(length=255), nullable=True),
sa.Column('saes', sa.String(length=255), nullable=True),
sa.Column('prerequis', sa.String(length=255), nullable=True),
sa.Column('contexte', sa.Text(), nullable=True),
sa.Column('contenu', sa.Text(), nullable=True),
sa.Column('motscles', sa.String(length=255), nullable=True),
sa.PrimaryKeyConstraint('code')
)
op.create_table('Ressources_ACs',
sa.Column('Ressource_code', sa.String(length=4), nullable=True),
sa.Column('AC_code', sa.String(length=6), nullable=True),
sa.ForeignKeyConstraint(['AC_code'], ['AC.code'], ),
sa.ForeignKeyConstraint(['Ressource_code'], ['ressource.code'], )
)
op.create_table('Ressources_SAEs',
sa.Column('Ressource_code', sa.String(length=4), nullable=True),
sa.Column('SAE_code', sa.String(length=5), nullable=True),
sa.ForeignKeyConstraint(['Ressource_code'], ['ressource.code'], ),
sa.ForeignKeyConstraint(['SAE_code'], ['SAE.code'], )
)
op.create_table('SAEs_ACs',
sa.Column('SAE_code', sa.String(length=5), nullable=True),
sa.Column('AC_code', sa.String(length=6), nullable=True),
sa.ForeignKeyConstraint(['AC_code'], ['AC.code'], ),
sa.ForeignKeyConstraint(['SAE_code'], ['SAE.code'], )
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('SAEs_ACs')
op.drop_table('Ressources_SAEs')
op.drop_table('Ressources_ACs')
op.drop_table('ressource')
op.drop_table('competence')
op.drop_table('SAE')
op.drop_table('PN')
op.drop_table('AC')
# ### end Alembic commands ###

View File

@ -1,34 +0,0 @@
"""PN table
Revision ID: be67c6934c05
Revises:
Create Date: 2021-05-03 17:01:39.845539
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'be67c6934c05'
down_revision = None
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('PN',
sa.Column('code', sa.String(length=3), nullable=False),
sa.Column('nom', sa.String(length=255), nullable=True),
sa.Column('diminutif', sa.String(length=30), nullable=True),
sa.Column('description', sa.Text(), nullable=True),
sa.PrimaryKeyConstraint('code')
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_table('PN')
# ### end Alembic commands ###

View File

@ -1,28 +0,0 @@
"""PN table
Revision ID: c1377d41bf27
Revises: be67c6934c05
Create Date: 2021-05-03 17:20:44.055359
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'c1377d41bf27'
down_revision = 'be67c6934c05'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('PN', sa.Column('type', sa.Integer(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_column('PN', 'type')
# ### end Alembic commands ###

View File

@ -1,57 +0,0 @@
"""empty message
Revision ID: e52d97e91e29
Revises: c000b3a8d714
Create Date: 2021-05-07 14:03:45.369279
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'e52d97e91e29'
down_revision = 'c000b3a8d714'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.create_table('Ressources_ACs',
sa.Column('Ressource_code', sa.String(length=4), nullable=True),
sa.Column('AC_code', sa.String(length=6), nullable=True),
sa.ForeignKeyConstraint(['AC_code'], ['AC.code'], ),
sa.ForeignKeyConstraint(['Ressource_code'], ['ressource.code'], )
)
op.create_table('Ressources_SAEs',
sa.Column('Ressource_code', sa.String(length=4), nullable=True),
sa.Column('SAE_code', sa.String(length=5), nullable=True),
sa.ForeignKeyConstraint(['Ressource_code'], ['ressource.code'], ),
sa.ForeignKeyConstraint(['SAE_code'], ['SAE.code'], )
)
op.create_table('SAEs_ACs',
sa.Column('SAE_code', sa.String(length=5), nullable=True),
sa.Column('AC_code', sa.String(length=6), nullable=True),
sa.ForeignKeyConstraint(['AC_code'], ['AC.code'], ),
sa.ForeignKeyConstraint(['SAE_code'], ['SAE.code'], )
)
op.drop_column('AC', 'saes')
op.drop_column('SAE', 'ressources')
op.drop_column('SAE', 'acs')
op.drop_column('ressource', 'saes')
op.drop_column('ressource', 'acs')
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column('ressource', sa.Column('acs', sa.VARCHAR(length=255), nullable=True))
op.add_column('ressource', sa.Column('saes', sa.VARCHAR(length=255), nullable=True))
op.add_column('SAE', sa.Column('acs', sa.VARCHAR(length=255), nullable=True))
op.add_column('SAE', sa.Column('ressources', sa.VARCHAR(length=255), nullable=True))
op.add_column('AC', sa.Column('saes', sa.VARCHAR(length=255), nullable=True))
op.drop_table('SAEs_ACs')
op.drop_table('Ressources_SAEs')
op.drop_table('Ressources_ACs')
# ### end Alembic commands ###