WIP: nouveau format XML Orebut ref. comp.

This commit is contained in:
Emmanuel Viennet 2022-01-03 12:25:42 +01:00
parent e0be0f8fee
commit 407c3ef472
3 changed files with 39 additions and 7 deletions

View File

@ -29,8 +29,8 @@ def orebut_import_refcomp(xml_data: str, dept_id: int, orig_filename=None):
"""
try:
root = ElementTree.XML(xml_data)
except ElementTree.ParseError:
raise ScoFormatError("fichier XML Orébut invalide")
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)
@ -77,7 +77,8 @@ def orebut_import_refcomp(xml_data: str, dept_id: int, orig_filename=None):
a = ApcAnneeParcours(**ApcAnneeParcours.attr_from_xml(annee.attrib))
parc.annees.append(a)
for competence in annee.findall("competence"):
nom = competence.attrib["nom"]
nom_court = competence.attrib["nom_court"]
XXX
niveau = int(competence.attrib["niveau"])
# Retrouve la competence
comp = ref.competences.filter_by(titre=nom).all()

View File

@ -9,11 +9,24 @@ from datetime import datetime
from enum import unique
from typing import Any
from sqlalchemy.orm import class_mapper
import sqlalchemy
from app import db
from app.scodoc.sco_utils import ModuleType
# from https://stackoverflow.com/questions/2537471/method-of-iterating-over-sqlalchemy-models-defined-columns
def attribute_names(cls):
"liste ids (noms de colonnes) d'un modèle"
return [
prop.key
for prop in class_mapper(cls).iterate_properties
if isinstance(prop, sqlalchemy.orm.ColumnProperty)
]
class XMLModel:
_xml_attribs = {} # to be overloaded
id = "_"
@ -24,8 +37,12 @@ class XMLModel:
and renamed for our models.
The mapping is specified by the _xml_attribs
attribute in each model class.
Keep only attributes corresponding to columns in our model:
other XML attributes are simply ignored.
"""
return {cls._xml_attribs.get(k, k): v for (k, v) in args.items()}
columns = attribute_names(cls)
renamed_attributes = {cls._xml_attribs.get(k, k): v for (k, v) in args.items()}
return {k: renamed_attributes[k] for k in renamed_attributes if k in columns}
def __repr__(self):
return f'<{self.__class__.__name__} {self.id} "{self.titre if hasattr(self, "titre") else ""}">'
@ -34,11 +51,16 @@ class XMLModel:
class ApcReferentielCompetences(db.Model, XMLModel):
id = db.Column(db.Integer, primary_key=True)
dept_id = db.Column(db.Integer, db.ForeignKey("departement.id"), index=True)
annexe = db.Column(db.Text())
specialite = db.Column(db.Text())
specialite_long = db.Column(db.Text())
type_titre = db.Column(db.Text())
type_structure = db.Column(db.Text())
type_departement = db.Column(db.Text()) # "secondaire", "tertiaire"
version_orebut = db.Column(db.Text())
_xml_attribs = { # Orébut xml attrib : attribute
"type": "type_titre",
"version": "version_orebut",
}
# ScoDoc specific fields:
scodoc_date_loaded = db.Column(db.DateTime, default=datetime.utcnow)
@ -64,9 +86,13 @@ class ApcReferentielCompetences(db.Model, XMLModel):
"""
return {
"dept_id": self.dept_id,
"annexe": self.annexe,
"specialite": self.specialite,
"specialite_long": self.specialite_long,
"type_structure": self.type_structure,
"type_departement": self.type_departement,
"type_titre": self.type_titre,
"version_orebut": self.version_orebut,
"scodoc_date_loaded": self.scodoc_date_loaded.isoformat() + "Z"
if self.scodoc_date_loaded
else "",
@ -88,12 +114,14 @@ class ApcCompetence(db.Model, XMLModel):
referentiel_id = db.Column(
db.Integer, db.ForeignKey("apc_referentiel_competences.id"), nullable=False
)
id_orebut = db.Column(db.Integer, nullable=True, index=True, unique=True)
titre = db.Column(db.Text(), nullable=False, index=True)
titre_long = db.Column(db.Text())
couleur = db.Column(db.Text())
numero = db.Column(db.Integer) # ordre de présentation
_xml_attribs = { # xml_attrib : attribute
"name": "titre",
"id": "id_orebut",
"nom_court": "titre", # was name
"libelle_long": "titre_long",
}
situations = db.relationship(
@ -117,6 +145,7 @@ class ApcCompetence(db.Model, XMLModel):
def to_dict(self):
return {
"id_orebut": self.id_orebut,
"titre": self.titre,
"titre_long": self.titre_long,
"couleur": self.couleur,

View File

@ -172,11 +172,13 @@ def refcomp_load(formation_id=None):
filename = secure_filename(f.filename)
try:
xml_data = f.read()
ref = orebut_import_refcomp(
_ = orebut_import_refcomp(
xml_data, dept_id=g.scodoc_dept_id, orig_filename=filename
)
except TypeError as exc:
raise ScoFormatError("fichier XML Orébut invalide") from exc
raise ScoFormatError(
f"fichier XML Orébut invalide (1): {exc.args}"
) from exc
except ScoFormatError:
raise