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(
|
||||
"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(
|
||||
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=[
|
||||
FileAllowed(
|
||||
[
|
||||
@ -41,13 +55,11 @@ class RefCompLoadForm(FlaskForm):
|
||||
submit = SubmitField("Valider")
|
||||
cancel = SubmitField("Annuler")
|
||||
|
||||
def validate(self, extra_validators=None):
|
||||
def validate(self, extra_validators=None) -> bool:
|
||||
if not super().validate(extra_validators):
|
||||
return False
|
||||
if (self.referentiel_standard.data == "0") == (not self.upload.data):
|
||||
self.referentiel_standard.errors.append(
|
||||
"Choisir soit un référentiel, soit un fichier xml"
|
||||
)
|
||||
if not self.upload.data:
|
||||
self.upload.errors.append("Choisir un fichier XML")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
@ -3,7 +3,19 @@
|
||||
{% import 'wtf.j2' as wtf %}
|
||||
|
||||
{% 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="col-md-5">
|
||||
@ -13,14 +25,21 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<ul>
|
||||
<ul class="sco-links">
|
||||
<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>
|
||||
</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
|
||||
<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>
|
||||
|
@ -14,7 +14,7 @@
|
||||
<li>
|
||||
<a class="stdlink" href="{{url_for(
|
||||
'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>
|
||||
</ul>
|
||||
</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,
|
||||
FormationRefCompForm,
|
||||
RefCompLoadForm,
|
||||
RefCompUploadForm,
|
||||
)
|
||||
from app.scodoc.gen_tables import GenTable
|
||||
from app.scodoc import sco_utils as scu
|
||||
@ -207,10 +208,9 @@ def refcomp_desassoc_formation(formation_id: int):
|
||||
@permission_required(Permission.EditFormation)
|
||||
def refcomp_load(formation_id=None):
|
||||
"""Formulaire association ref. compétence"""
|
||||
if formation_id is not None:
|
||||
formation = Formation.query.get_or_404(formation_id)
|
||||
else:
|
||||
formation = None
|
||||
formation = (
|
||||
Formation.get_formation(formation_id) if formation_id is not None else None
|
||||
)
|
||||
refs_distrib_files = sorted(
|
||||
list(
|
||||
(
|
||||
@ -253,34 +253,17 @@ def refcomp_load(formation_id=None):
|
||||
for r in refs_distrib_dict
|
||||
]
|
||||
if form.validate_on_submit():
|
||||
if form.upload.data:
|
||||
f = form.upload.data
|
||||
filename = secure_filename(f.filename)
|
||||
elif form.referentiel_standard.data:
|
||||
if form.referentiel_standard.data:
|
||||
try:
|
||||
filename = refs_distrib_dict[int(form.referentiel_standard.data)][
|
||||
"filename"
|
||||
]
|
||||
except (ValueError, IndexError) as exc:
|
||||
raise ScoValueError("choix invalide") from exc
|
||||
f = open(filename, encoding="utf-8")
|
||||
else:
|
||||
raise ScoValueError("choix invalide")
|
||||
try:
|
||||
xml_data = f.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
|
||||
# peut aussi lever ScoFormatError
|
||||
|
||||
flash(
|
||||
Markup(f"Référentiel <tt>{Path(filename).name}</tt> chargé."),
|
||||
category="info",
|
||||
)
|
||||
with open(filename, encoding="utf-8") as stream:
|
||||
_upload_ref_xml(filename, stream)
|
||||
|
||||
return redirect(
|
||||
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"])
|
||||
@scodoc
|
||||
@permission_required(Permission.EditFormation)
|
||||
|
Loading…
Reference in New Issue
Block a user