forked from ScoDoc/ScoDoc
Morceaux manquants.
This commit is contained in:
parent
92bdf1bb8b
commit
51933d057b
76
app/forms/main/config_apo.py
Normal file
76
app/forms/main/config_apo.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
# -*- mode: python -*-
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# ScoDoc
|
||||||
|
#
|
||||||
|
# Copyright (c) 1999 - 2022 Emmanuel Viennet. All rights reserved.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
#
|
||||||
|
# Emmanuel Viennet emmanuel.viennet@viennet.net
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
"""
|
||||||
|
Formulaires configuration Exports Apogée (codes)
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
|
||||||
|
from flask import flash, url_for, redirect, render_template
|
||||||
|
from flask_wtf import FlaskForm
|
||||||
|
from wtforms import SubmitField, validators
|
||||||
|
from wtforms.fields.simple import StringField
|
||||||
|
|
||||||
|
from app import models
|
||||||
|
from app.models import ScoDocSiteConfig
|
||||||
|
from app.models import SHORT_STR_LEN
|
||||||
|
|
||||||
|
from app.scodoc import sco_utils as scu
|
||||||
|
|
||||||
|
|
||||||
|
def _build_code_field(code):
|
||||||
|
return StringField(
|
||||||
|
label=code,
|
||||||
|
validators=[
|
||||||
|
validators.regexp(
|
||||||
|
r"^[A-Z0-9_]*$",
|
||||||
|
message="Ne doit comporter que majuscules et des chiffres",
|
||||||
|
),
|
||||||
|
validators.Length(
|
||||||
|
max=SHORT_STR_LEN,
|
||||||
|
message=f"L'acronyme ne doit pas dépasser {SHORT_STR_LEN} caractères",
|
||||||
|
),
|
||||||
|
validators.DataRequired("code requis"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CodesDecisionsForm(FlaskForm):
|
||||||
|
ADC = _build_code_field("ADC")
|
||||||
|
ADJ = _build_code_field("ADJ")
|
||||||
|
ADM = _build_code_field("ADM")
|
||||||
|
AJ = _build_code_field("AJ")
|
||||||
|
ATB = _build_code_field("ATB")
|
||||||
|
ATJ = _build_code_field("ATJ")
|
||||||
|
ATT = _build_code_field("ATT")
|
||||||
|
CMP = _build_code_field("CMP")
|
||||||
|
DEF = _build_code_field("DEF")
|
||||||
|
DEM = _build_code_field("DEF")
|
||||||
|
NAR = _build_code_field("NAR")
|
||||||
|
RAT = _build_code_field("RAT")
|
||||||
|
submit = SubmitField("Valider")
|
||||||
|
cancel = SubmitField("Annuler", render_kw={"formnovalidate": True})
|
178
app/models/config.py
Normal file
178
app/models/config.py
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
# -*- coding: UTF-8 -*
|
||||||
|
|
||||||
|
"""Model : site config WORK IN PROGRESS #WIP
|
||||||
|
"""
|
||||||
|
|
||||||
|
from app import db, log
|
||||||
|
from app.scodoc import bonus_sport
|
||||||
|
from app.scodoc.sco_exceptions import ScoValueError
|
||||||
|
import functools
|
||||||
|
|
||||||
|
from app.scodoc.sco_codes_parcours import (
|
||||||
|
ADC,
|
||||||
|
ADJ,
|
||||||
|
ADM,
|
||||||
|
AJ,
|
||||||
|
ATB,
|
||||||
|
ATJ,
|
||||||
|
ATT,
|
||||||
|
CMP,
|
||||||
|
DEF,
|
||||||
|
DEM,
|
||||||
|
NAR,
|
||||||
|
RAT,
|
||||||
|
)
|
||||||
|
|
||||||
|
CODES_SCODOC_TO_APO = {
|
||||||
|
ADC: "ADMC",
|
||||||
|
ADJ: "ADM",
|
||||||
|
ADM: "ADM",
|
||||||
|
AJ: "AJ",
|
||||||
|
ATB: "AJAC",
|
||||||
|
ATJ: "AJAC",
|
||||||
|
ATT: "AJAC",
|
||||||
|
CMP: "COMP",
|
||||||
|
DEF: "NAR",
|
||||||
|
DEM: "NAR",
|
||||||
|
NAR: "NAR",
|
||||||
|
RAT: "ATT",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def code_scodoc_to_apo_default(code):
|
||||||
|
"""Conversion code jury ScoDoc en code Apogée
|
||||||
|
(codes par défaut, c'est configurable via ScoDocSiteConfig.get_code_apo)
|
||||||
|
"""
|
||||||
|
return CODES_SCODOC_TO_APO.get(code, "DEF")
|
||||||
|
|
||||||
|
|
||||||
|
class ScoDocSiteConfig(db.Model):
|
||||||
|
"""Config. d'un site
|
||||||
|
Nouveau en ScoDoc 9: va regrouper les paramètres qui dans les versions
|
||||||
|
antérieures étaient dans scodoc_config.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
__tablename__ = "scodoc_site_config"
|
||||||
|
|
||||||
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
|
name = db.Column(db.String(128), nullable=False, index=True)
|
||||||
|
value = db.Column(db.Text())
|
||||||
|
|
||||||
|
BONUS_SPORT = "bonus_sport_func_name"
|
||||||
|
NAMES = {
|
||||||
|
BONUS_SPORT: str,
|
||||||
|
"always_require_ine": bool,
|
||||||
|
"SCOLAR_FONT": str,
|
||||||
|
"SCOLAR_FONT_SIZE": str,
|
||||||
|
"SCOLAR_FONT_SIZE_FOOT": str,
|
||||||
|
"INSTITUTION_NAME": str,
|
||||||
|
"INSTITUTION_ADDRESS": str,
|
||||||
|
"INSTITUTION_CITY": str,
|
||||||
|
"DEFAULT_PDF_FOOTER_TEMPLATE": str,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, name, value):
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__name__}('{self.name}', '{self.value}')>"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_dict(cls) -> dict:
|
||||||
|
"Returns all data as a dict name = value"
|
||||||
|
return {
|
||||||
|
c.name: cls.NAMES.get(c.name, lambda x: x)(c.value)
|
||||||
|
for c in ScoDocSiteConfig.query.all()
|
||||||
|
}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_bonus_sport_func(cls, func_name):
|
||||||
|
"""Record bonus_sport config.
|
||||||
|
If func_name not defined, raise NameError
|
||||||
|
"""
|
||||||
|
if func_name not in cls.get_bonus_sport_func_names():
|
||||||
|
raise NameError("invalid function name for bonus_sport")
|
||||||
|
c = ScoDocSiteConfig.query.filter_by(name=cls.BONUS_SPORT).first()
|
||||||
|
if c:
|
||||||
|
log("setting to " + func_name)
|
||||||
|
c.value = func_name
|
||||||
|
else:
|
||||||
|
c = ScoDocSiteConfig(cls.BONUS_SPORT, func_name)
|
||||||
|
db.session.add(c)
|
||||||
|
db.session.commit()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_bonus_sport_func_name(cls):
|
||||||
|
"""Get configured bonus function name, or None if None."""
|
||||||
|
f = cls.get_bonus_sport_func_from_name()
|
||||||
|
if f is None:
|
||||||
|
return ""
|
||||||
|
else:
|
||||||
|
return f.__name__
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_bonus_sport_func(cls):
|
||||||
|
"""Get configured bonus function, or None if None."""
|
||||||
|
return cls.get_bonus_sport_func_from_name()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_bonus_sport_func_from_name(cls, func_name=None):
|
||||||
|
"""returns bonus func with specified name.
|
||||||
|
If name not specified, return the configured function.
|
||||||
|
None if no bonus function configured.
|
||||||
|
Raises ScoValueError if func_name not found in module bonus_sport.
|
||||||
|
"""
|
||||||
|
if func_name is None:
|
||||||
|
c = ScoDocSiteConfig.query.filter_by(name=cls.BONUS_SPORT).first()
|
||||||
|
if c is None:
|
||||||
|
return None
|
||||||
|
func_name = c.value
|
||||||
|
if func_name == "": # pas de bonus défini
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
return getattr(bonus_sport, func_name)
|
||||||
|
except AttributeError:
|
||||||
|
raise ScoValueError(
|
||||||
|
f"""Fonction de calcul maison inexistante: {func_name}.
|
||||||
|
(contacter votre administrateur local)."""
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_bonus_sport_func_names(cls):
|
||||||
|
"""List available functions names
|
||||||
|
(starting with empty string to represent "no bonus function").
|
||||||
|
"""
|
||||||
|
return [""] + sorted(
|
||||||
|
[
|
||||||
|
getattr(bonus_sport, name).__name__
|
||||||
|
for name in dir(bonus_sport)
|
||||||
|
if name.startswith("bonus_")
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_code_apo(cls, code: str) -> str:
|
||||||
|
"""La représentation d'un code pour les exports Apogée.
|
||||||
|
Par exemple, à l'iUT du H., le code ADM est réprésenté par VAL
|
||||||
|
Les codes par défaut sont donnés dans sco_apogee_csv.
|
||||||
|
|
||||||
|
"""
|
||||||
|
cfg = ScoDocSiteConfig.query.filter_by(name=code).first()
|
||||||
|
if not cfg:
|
||||||
|
code_apo = code_scodoc_to_apo_default(code)
|
||||||
|
else:
|
||||||
|
code_apo = cfg.value
|
||||||
|
return code_apo
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def set_code_apo(cls, code: str, code_apo: str):
|
||||||
|
"""Enregistre nouvelle représentation du code"""
|
||||||
|
if code_apo != cls.get_code_apo(code):
|
||||||
|
cfg = ScoDocSiteConfig.query.filter_by(name=code).first()
|
||||||
|
if cfg is None:
|
||||||
|
cfg = ScoDocSiteConfig(code, code_apo)
|
||||||
|
else:
|
||||||
|
cfg.value = code_apo
|
||||||
|
db.session.add(cfg)
|
||||||
|
db.session.commit()
|
23
app/templates/config_codes_decisions.html
Normal file
23
app/templates/config_codes_decisions.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% import 'bootstrap/wtf.html' as wtf %}
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
<h1>Configuration des codes de décision exportés vers Apogée</h1>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="help">
|
||||||
|
<p>Ces codes (ADM, AJ, ...) sont utilisés pour représenter les décisions de jury
|
||||||
|
et les validations de semestres ou d'UE. les valeurs indiquées ici sont utilisées
|
||||||
|
dans les exports Apogée.
|
||||||
|
<p>
|
||||||
|
<p>Ne les modifier que si vous savez ce que vous faites !
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
{{ wtf.quick_form(form) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -1,7 +1,7 @@
|
|||||||
# -*- mode: python -*-
|
# -*- mode: python -*-
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
SCOVERSION = "9.1.29"
|
SCOVERSION = "9.1.30"
|
||||||
|
|
||||||
SCONAME = "ScoDoc"
|
SCONAME = "ScoDoc"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user