forked from ScoDoc/ScoDoc
Chargement ref. comp. externe: autorise, sur page spéciale.
This commit is contained in:
parent
fdc01a5c3b
commit
9832bf1e74
@ -27,8 +27,22 @@ class RefCompLoadForm(FlaskForm):
|
|||||||
referentiel_standard = SelectField(
|
referentiel_standard = SelectField(
|
||||||
"Choisir un référentiel de compétences officiel BUT"
|
"Choisir un référentiel de compétences officiel BUT"
|
||||||
)
|
)
|
||||||
|
submit = SubmitField("Valider")
|
||||||
|
cancel = SubmitField("Annuler")
|
||||||
|
|
||||||
|
def validate(self, extra_validators=None) -> bool:
|
||||||
|
if not super().validate(extra_validators):
|
||||||
|
return False
|
||||||
|
if self.referentiel_standard.data == "0":
|
||||||
|
self.referentiel_standard.errors.append("Choisir soit un référentiel")
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class RefCompUploadForm(FlaskForm):
|
||||||
|
"Upload d'un référentiel"
|
||||||
upload = FileField(
|
upload = FileField(
|
||||||
label="... ou bien sélectionner un fichier XML au format Orébut (réservé aux développeurs !)",
|
label="Sélectionner un fichier XML au format Orébut",
|
||||||
validators=[
|
validators=[
|
||||||
FileAllowed(
|
FileAllowed(
|
||||||
[
|
[
|
||||||
@ -41,13 +55,11 @@ class RefCompLoadForm(FlaskForm):
|
|||||||
submit = SubmitField("Valider")
|
submit = SubmitField("Valider")
|
||||||
cancel = SubmitField("Annuler")
|
cancel = SubmitField("Annuler")
|
||||||
|
|
||||||
def validate(self, extra_validators=None):
|
def validate(self, extra_validators=None) -> bool:
|
||||||
if not super().validate(extra_validators):
|
if not super().validate(extra_validators):
|
||||||
return False
|
return False
|
||||||
if (self.referentiel_standard.data == "0") == (not self.upload.data):
|
if not self.upload.data:
|
||||||
self.referentiel_standard.errors.append(
|
self.upload.errors.append("Choisir un fichier XML")
|
||||||
"Choisir soit un référentiel, soit un fichier xml"
|
|
||||||
)
|
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -3,7 +3,19 @@
|
|||||||
{% import 'wtf.j2' as wtf %}
|
{% import 'wtf.j2' as wtf %}
|
||||||
|
|
||||||
{% block app_content %}
|
{% block app_content %}
|
||||||
<h1>Charger un référentiel de compétences</h1>
|
<h1>Charger un référentiel de compétences de BUT (officiel)</h1>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
|
||||||
|
<p> Les référentiels de compétence de BUT font partie du Programme National (PN)
|
||||||
|
de BUT et <em>ne sont pas modifiables</em>. ScoDoc est livré avec une copie des
|
||||||
|
référentiels officiels issus de l'application Orébut.</p>
|
||||||
|
|
||||||
|
<p> Il est aussi possible de définir un référentiel de compétences ad-hoc pour
|
||||||
|
des formations par compétences non BUT (mais ayant le même principe de
|
||||||
|
fonctionnement, avec une architecture en blocs de compétences et RCUEs).</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
@ -13,14 +25,21 @@
|
|||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<ul>
|
<ul class="sco-links">
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept, ) }}">
|
<a class="stdlink"
|
||||||
|
href="{{ url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept, ) }}">
|
||||||
Liste des référentiels de compétences chargés</a>
|
Liste des référentiels de compétences chargés</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="stdlink" href="{{url_for(
|
||||||
|
'notes.refcomp_upload_new', scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=formation.id if formation else None
|
||||||
|
)}}">Charger un référentiel de compétences ad-hoc non BUT</a>
|
||||||
|
</li>
|
||||||
{% if formation is not none %}
|
{% if formation is not none %}
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="stdlink"
|
||||||
href="{{ url_for('notes.refcomp_assoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id) }}">
|
href="{{ url_for('notes.refcomp_assoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id) }}">
|
||||||
Association à la formation {{ formation.acronyme }}</a>
|
Association à la formation {{ formation.acronyme }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
<li>
|
<li>
|
||||||
<a class="stdlink" href="{{url_for(
|
<a class="stdlink" href="{{url_for(
|
||||||
'notes.refcomp_load', scodoc_dept=g.scodoc_dept)
|
'notes.refcomp_load', scodoc_dept=g.scodoc_dept)
|
||||||
}}">Charger un nouveau référentiel de compétences Orébut</a>
|
}}">Charger un nouveau référentiel de compétences</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
59
app/templates/but/refcomp_upload_new.j2
Normal file
59
app/templates/but/refcomp_upload_new.j2
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{# -*- mode: jinja-html -*- #}
|
||||||
|
{% extends "sco_page_dept.j2" %}
|
||||||
|
{% import 'wtf.j2' as wtf %}
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
<h1>Charger un référentiel de compétences externe (non BUT)</h1>
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
|
||||||
|
<p>Cette page permet de charger votre propre référentiel de compétence.
|
||||||
|
Le fichier doit être au format XML, et doit respecter le schéma de référentiel
|
||||||
|
de compétences "Orébut", qui n'est pas documenté dans ScoDoc (voir le logiciel Orébut).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>Cette approche ne fonctionne que si votre formation suit les principes architecturaux
|
||||||
|
du BUT (blocs de compétences, RCUEs, ressources, SAÉs, etc.).
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="warning">Attention : ne pas utiliser cette page pour les référentiels de BUT.
|
||||||
|
Pour le BUT utiliser <em>impérativement</em> les référentiels officiels, qui sont
|
||||||
|
distribués avec ScoDoc : <a class="stdlink"
|
||||||
|
href="{{ url_for('notes.refcomp_load', scodoc_dept=g.scodoc_dept, ) }}">
|
||||||
|
Voir cette page</a>.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
{{ wtf.quick_form(form) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-5">
|
||||||
|
<ul class="sco-links">
|
||||||
|
<li>
|
||||||
|
<a class="stdlink"
|
||||||
|
href="{{ url_for('notes.refcomp_table', scodoc_dept=g.scodoc_dept, ) }}">
|
||||||
|
Liste des référentiels de compétences chargés</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="stdlink" href="{{url_for(
|
||||||
|
'notes.refcomp_upload_new', scodoc_dept=g.scodoc_dept,
|
||||||
|
formation_id=formation.id if formation else None
|
||||||
|
)}}">Charger un référentiel de compétences ad-hoc non BUT</a>
|
||||||
|
</li>
|
||||||
|
{% if formation is not none %}
|
||||||
|
<li>
|
||||||
|
<a class="stdlink"
|
||||||
|
href="{{ url_for('notes.refcomp_assoc_formation', scodoc_dept=g.scodoc_dept, formation_id=formation.id) }}">
|
||||||
|
Association à la formation {{ formation.acronyme }}</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -26,6 +26,7 @@ from app.but.forms.refcomp_forms import (
|
|||||||
FormationChangeRefCompForm,
|
FormationChangeRefCompForm,
|
||||||
FormationRefCompForm,
|
FormationRefCompForm,
|
||||||
RefCompLoadForm,
|
RefCompLoadForm,
|
||||||
|
RefCompUploadForm,
|
||||||
)
|
)
|
||||||
from app.scodoc.gen_tables import GenTable
|
from app.scodoc.gen_tables import GenTable
|
||||||
from app.scodoc import sco_utils as scu
|
from app.scodoc import sco_utils as scu
|
||||||
@ -207,10 +208,9 @@ def refcomp_desassoc_formation(formation_id: int):
|
|||||||
@permission_required(Permission.EditFormation)
|
@permission_required(Permission.EditFormation)
|
||||||
def refcomp_load(formation_id=None):
|
def refcomp_load(formation_id=None):
|
||||||
"""Formulaire association ref. compétence"""
|
"""Formulaire association ref. compétence"""
|
||||||
if formation_id is not None:
|
formation = (
|
||||||
formation = Formation.query.get_or_404(formation_id)
|
Formation.get_formation(formation_id) if formation_id is not None else None
|
||||||
else:
|
)
|
||||||
formation = None
|
|
||||||
refs_distrib_files = sorted(
|
refs_distrib_files = sorted(
|
||||||
list(
|
list(
|
||||||
(
|
(
|
||||||
@ -253,34 +253,17 @@ def refcomp_load(formation_id=None):
|
|||||||
for r in refs_distrib_dict
|
for r in refs_distrib_dict
|
||||||
]
|
]
|
||||||
if form.validate_on_submit():
|
if form.validate_on_submit():
|
||||||
if form.upload.data:
|
if form.referentiel_standard.data:
|
||||||
f = form.upload.data
|
|
||||||
filename = secure_filename(f.filename)
|
|
||||||
elif form.referentiel_standard.data:
|
|
||||||
try:
|
try:
|
||||||
filename = refs_distrib_dict[int(form.referentiel_standard.data)][
|
filename = refs_distrib_dict[int(form.referentiel_standard.data)][
|
||||||
"filename"
|
"filename"
|
||||||
]
|
]
|
||||||
except (ValueError, IndexError) as exc:
|
except (ValueError, IndexError) as exc:
|
||||||
raise ScoValueError("choix invalide") from exc
|
raise ScoValueError("choix invalide") from exc
|
||||||
f = open(filename, encoding="utf-8")
|
|
||||||
else:
|
else:
|
||||||
raise ScoValueError("choix invalide")
|
raise ScoValueError("choix invalide")
|
||||||
try:
|
with open(filename, encoding="utf-8") as stream:
|
||||||
xml_data = f.read()
|
_upload_ref_xml(filename, stream)
|
||||||
_ = orebut_import_refcomp(
|
|
||||||
xml_data, dept_id=g.scodoc_dept_id, orig_filename=Path(filename).name
|
|
||||||
)
|
|
||||||
except TypeError as exc:
|
|
||||||
raise ScoFormatError(
|
|
||||||
f"fichier XML Orébut invalide (1): {exc.args}"
|
|
||||||
) from exc
|
|
||||||
# peut aussi lever ScoFormatError
|
|
||||||
|
|
||||||
flash(
|
|
||||||
Markup(f"Référentiel <tt>{Path(filename).name}</tt> chargé."),
|
|
||||||
category="info",
|
|
||||||
)
|
|
||||||
|
|
||||||
return redirect(
|
return redirect(
|
||||||
url_for(
|
url_for(
|
||||||
@ -297,6 +280,65 @@ def refcomp_load(formation_id=None):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _upload_ref_xml(filename: str, stream):
|
||||||
|
"""
|
||||||
|
peut lever ScoFormatError.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
xml_data = stream.read()
|
||||||
|
_ = orebut_import_refcomp(
|
||||||
|
xml_data, dept_id=g.scodoc_dept_id, orig_filename=Path(filename).name
|
||||||
|
)
|
||||||
|
except TypeError as exc:
|
||||||
|
raise ScoFormatError(f"fichier XML Orébut invalide (1): {exc.args}") from exc
|
||||||
|
#
|
||||||
|
flash(
|
||||||
|
Markup(f"Référentiel <tt>{Path(filename).name}</tt> chargé."),
|
||||||
|
category="info",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route(
|
||||||
|
"/referentiel/comp/upload_new",
|
||||||
|
defaults={"formation_id": None},
|
||||||
|
methods=["GET", "POST"],
|
||||||
|
)
|
||||||
|
@bp.route("/referentiel/comp/upload_new/<int:formation_id>", methods=["GET", "POST"])
|
||||||
|
@scodoc
|
||||||
|
@permission_required(Permission.EditFormation)
|
||||||
|
def refcomp_upload_new(formation_id=None):
|
||||||
|
"""Formulaire chargement fichier externe ref. compétence"""
|
||||||
|
formation = (
|
||||||
|
Formation.get_formation(formation_id) if formation_id is not None else None
|
||||||
|
)
|
||||||
|
form = RefCompUploadForm()
|
||||||
|
if form.validate_on_submit():
|
||||||
|
if form.upload.data:
|
||||||
|
f = form.upload.data
|
||||||
|
filename = secure_filename(f.filename)
|
||||||
|
_upload_ref_xml(filename, f)
|
||||||
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"notes.refcomp_table",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if form.cancel.data: # cancel button
|
||||||
|
return redirect(
|
||||||
|
url_for(
|
||||||
|
"notes.refcomp_load",
|
||||||
|
scodoc_dept=g.scodoc_dept,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return render_template(
|
||||||
|
"but/refcomp_upload_new.j2",
|
||||||
|
form=form,
|
||||||
|
formation=formation,
|
||||||
|
title="Chargement réf. compétences externe",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/formation/<int:formation_id>/change_refcomp", methods=["GET", "POST"])
|
@bp.route("/formation/<int:formation_id>/change_refcomp", methods=["GET", "POST"])
|
||||||
@scodoc
|
@scodoc
|
||||||
@permission_required(Permission.EditFormation)
|
@permission_required(Permission.EditFormation)
|
||||||
|
Loading…
Reference in New Issue
Block a user