forked from ScoDoc/ScoDoc
145 lines
5.5 KiB
Python
145 lines
5.5 KiB
Python
##############################################################################
|
|
# ScoDoc
|
|
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
|
# See LICENSE
|
|
##############################################################################
|
|
from xml.etree import ElementTree
|
|
|
|
import sqlalchemy
|
|
|
|
from app import db
|
|
|
|
from app.models.but_refcomp import (
|
|
ApcReferentielCompetences,
|
|
ApcCompetence,
|
|
ApcSituationPro,
|
|
ApcAppCritique,
|
|
ApcComposanteEssentielle,
|
|
ApcNiveau,
|
|
ApcParcours,
|
|
ApcAnneeParcours,
|
|
ApcParcoursNiveauCompetence,
|
|
)
|
|
from app.scodoc.sco_exceptions import ScoFormatError, ScoValueError
|
|
|
|
|
|
def orebut_import_refcomp(xml_data: str, dept_id: int, orig_filename=None):
|
|
"""Importation XML Orébut
|
|
peut lever TypeError ou ScoFormatError
|
|
Résultat: instance de ApcReferentielCompetences
|
|
"""
|
|
# Vérifie que le même fichier n'a pas déjà été chargé:
|
|
if ApcReferentielCompetences.query.filter_by(
|
|
scodoc_orig_filename=orig_filename, dept_id=dept_id
|
|
).count():
|
|
raise ScoValueError(
|
|
f"""Un référentiel a déjà été chargé d'un fichier de même nom.
|
|
({orig_filename})
|
|
Supprimez-le ou changez le nom du fichier."""
|
|
)
|
|
|
|
try:
|
|
root = ElementTree.XML(xml_data)
|
|
except ElementTree.ParseError as exc:
|
|
raise ScoFormatError(f"fichier XML Orébut invalide (2): {exc.args}")
|
|
if root.tag != "referentiel_competence":
|
|
raise ScoFormatError("élément racine 'referentiel_competence' manquant")
|
|
args = ApcReferentielCompetences.attr_from_xml(root.attrib)
|
|
args["dept_id"] = dept_id
|
|
args["scodoc_orig_filename"] = orig_filename
|
|
ref = ApcReferentielCompetences(**args)
|
|
db.session.add(ref)
|
|
competences = root.find("competences")
|
|
if not competences:
|
|
raise ScoFormatError("élément 'competences' manquant")
|
|
for competence in competences.findall("competence"):
|
|
try:
|
|
c = ApcCompetence(**ApcCompetence.attr_from_xml(competence.attrib))
|
|
db.session.flush()
|
|
except sqlalchemy.exc.IntegrityError as exc:
|
|
# ne devrait plus se produire car pas d'unicité de l'id: donc inutile
|
|
db.session.rollback()
|
|
raise ScoValueError(
|
|
f"""Un référentiel a déjà été chargé avec les mêmes compétences ! ({competence.attrib["id"]})
|
|
"""
|
|
) from exc
|
|
ref.competences.append(c)
|
|
# --- SITUATIONS
|
|
situations = competence.find("situations")
|
|
for situation in situations:
|
|
libelle = "".join(situation.itertext()).strip()
|
|
s = ApcSituationPro(competence_id=c.id, libelle=libelle)
|
|
c.situations.append(s)
|
|
# --- COMPOSANTES ESSENTIELLES
|
|
composantes = competence.find("composantes_essentielles")
|
|
for composante in composantes:
|
|
libelle = "".join(composante.itertext()).strip()
|
|
compo_ess = ApcComposanteEssentielle(libelle=libelle)
|
|
c.composantes_essentielles.append(compo_ess)
|
|
# --- NIVEAUX (années)
|
|
niveaux = competence.find("niveaux")
|
|
for niveau in niveaux:
|
|
niv = ApcNiveau(**ApcNiveau.attr_from_xml(niveau.attrib))
|
|
c.niveaux.append(niv)
|
|
acs = niveau.find("acs")
|
|
for ac in acs:
|
|
libelle = "".join(ac.itertext()).strip()
|
|
code = ac.attrib["code"]
|
|
niv.app_critiques.append(ApcAppCritique(code=code, libelle=libelle))
|
|
# --- PARCOURS
|
|
parcours = root.find("parcours")
|
|
if not parcours:
|
|
raise ScoFormatError("élément 'parcours' manquant")
|
|
for parcour in parcours.findall("parcour"):
|
|
parc = ApcParcours(**ApcParcours.attr_from_xml(parcour.attrib))
|
|
ref.parcours.append(parc)
|
|
for annee in parcour.findall("annee"):
|
|
a = ApcAnneeParcours(**ApcAnneeParcours.attr_from_xml(annee.attrib))
|
|
parc.annees.append(a)
|
|
for competence in annee.findall("competence"):
|
|
comp_id_orebut = competence.attrib["id"]
|
|
niveau = int(competence.attrib["niveau"])
|
|
# Retrouve la competence
|
|
comp = ref.competences.filter_by(id_orebut=comp_id_orebut).first()
|
|
if comp is None:
|
|
raise ScoFormatError(f"competence {comp_id_orebut} non définie")
|
|
ass = ApcParcoursNiveauCompetence(
|
|
niveau=niveau, annee_parcours=a, competence=comp
|
|
)
|
|
db.session.add(ass)
|
|
|
|
db.session.commit()
|
|
return ref
|
|
|
|
|
|
"""
|
|
xmlfile = open("but-RT-refcomp-30112021.xml")
|
|
tree = ElementTree.parse(xmlfile)
|
|
# get root element
|
|
root = tree.getroot()
|
|
assert root.tag == "referentiel_competence"
|
|
|
|
ref = ApcReferentielCompetences(**ApcReferentielCompetences.attr_from_xml(root.attrib))
|
|
|
|
competences = root.find("competences")
|
|
if not competences:
|
|
raise ScoFormatError("élément 'competences' manquant")
|
|
|
|
competence = competences.findall("competence")[0] # XXX
|
|
|
|
from app.but.import_refcomp import *
|
|
dept_id = models.Departement.query.first().id
|
|
data = open("tests/data/but-RT-refcomp-exemple.xml").read()
|
|
ref = orebut_import_refcomp(data, dept_id)
|
|
#------
|
|
from app.but.import_refcomp import *
|
|
ref = ApcReferentielCompetences.query.first()
|
|
p = ApcParcours(code="PARC", libelle="Parcours Test")
|
|
ref.parcours.append(p)
|
|
annee = ApcAnneeParcours(numero=1)
|
|
p.annees.append(annee)
|
|
annee.competences
|
|
c = ref.competences.filter_by(titre="Administrer").first()
|
|
annee.competences.append(c)
|
|
"""
|