Merge branch 'master' of https://scodoc.org/git/viennet/ScoDoc into refactor_nt

This commit is contained in:
Emmanuel Viennet 2022-01-07 18:55:14 +01:00
commit fbb4b0841b
11 changed files with 62 additions and 32 deletions

View File

@ -73,9 +73,9 @@ def bulletin_but_xml_compat(
results = bulletin_but.ResultatsSemestreBUT(sem) results = bulletin_but.ResultatsSemestreBUT(sem)
nb_inscrits = len(results.etuds) nb_inscrits = len(results.etuds)
if (not sem.bul_hide_xml) or force_publishing: if (not sem.bul_hide_xml) or force_publishing:
published = "1" published = 1
else: else:
published = "0" published = 0
if xml_nodate: if xml_nodate:
docdate = "" docdate = ""
else: else:
@ -84,7 +84,7 @@ def bulletin_but_xml_compat(
"etudid": str(etudid), "etudid": str(etudid),
"formsemestre_id": str(formsemestre_id), "formsemestre_id": str(formsemestre_id),
"date": docdate, "date": docdate,
"publie": published, "publie": str(published),
} }
if sem.etapes: if sem.etapes:
el["etape_apo"] = sem.etapes[0].etape_apo or "" el["etape_apo"] = sem.etapes[0].etape_apo or ""
@ -218,7 +218,8 @@ def bulletin_but_xml_compat(
value=scu.fmt_note( value=scu.fmt_note(
results.modimpls_results[ results.modimpls_results[
e.moduleimpl_id e.moduleimpl_id
].evals_notes[e.id][etud.id] ].evals_notes[e.id][etud.id],
note_max=e.note_max,
), ),
) )
) )

View File

@ -416,6 +416,20 @@ def bonus_iutbeziers(notes_sport, coefs, infos=None):
return bonus return bonus
def bonus_iutlr(notes_sport, coefs, infos=None):
"""Calcul bonus modules optionels (sport, culture), règle IUT La Rochelle
Si la note de sport est comprise entre 0 et 10 : pas d'ajout de point
Si la note de sport est comprise entre 10.1 et 20 : ajout de 1% de cette note sur la moyenne générale du semestre
"""
# les coefs sont ignorés
# une seule note
note_sport = notes_sport[0]
if note_sport <= 10:
return 0
bonus = note_sport * 0.01 # 1%
return bonus
def bonus_demo(notes_sport, coefs, infos=None): def bonus_demo(notes_sport, coefs, infos=None):
"""Fausse fonction "bonus" pour afficher les informations disponibles """Fausse fonction "bonus" pour afficher les informations disponibles
et aider les développeurs. et aider les développeurs.

View File

@ -108,13 +108,14 @@ def apo_compare_csv(A_file, B_file, autodetect=True):
def _load_apo_data(csvfile, autodetect=True): def _load_apo_data(csvfile, autodetect=True):
"Read data from request variable and build ApoData" "Read data from request variable and build ApoData"
data = csvfile.read() data_b = csvfile.read()
if autodetect: if autodetect:
data, message = sco_apogee_csv.fix_data_encoding(data) data_b, message = sco_apogee_csv.fix_data_encoding(data_b)
if message: if message:
log("apo_compare_csv: %s" % message) log("apo_compare_csv: %s" % message)
if not data: if not data_b:
raise ScoValueError("apo_compare_csv: no data") raise ScoValueError("apo_compare_csv: no data")
data = data_b.decode(sco_apogee_csv.APO_INPUT_ENCODING)
apo_data = sco_apogee_csv.ApoData(data, orig_filename=csvfile.filename) apo_data = sco_apogee_csv.ApoData(data, orig_filename=csvfile.filename)
return apo_data return apo_data

View File

@ -173,8 +173,10 @@ def guess_data_encoding(text, threshold=0.6):
def fix_data_encoding( def fix_data_encoding(
text, default_source_encoding=APO_INPUT_ENCODING, dest_encoding=APO_INPUT_ENCODING text: bytes,
): default_source_encoding=APO_INPUT_ENCODING,
dest_encoding=APO_INPUT_ENCODING,
) -> bytes:
"""Try to ensure that text is using dest_encoding """Try to ensure that text is using dest_encoding
returns converted text, and a message describing the conversion. returns converted text, and a message describing the conversion.
""" """
@ -200,7 +202,7 @@ def fix_data_encoding(
class StringIOFileLineWrapper(object): class StringIOFileLineWrapper(object):
def __init__(self, data): def __init__(self, data: str):
self.f = io.StringIO(data) self.f = io.StringIO(data)
self.lineno = 0 self.lineno = 0
@ -655,7 +657,7 @@ class ApoEtud(dict):
class ApoData(object): class ApoData(object):
def __init__( def __init__(
self, self,
data, data: str,
periode=None, periode=None,
export_res_etape=True, export_res_etape=True,
export_res_sem=True, export_res_sem=True,
@ -693,7 +695,7 @@ class ApoData(object):
"<h3>Erreur lecture du fichier Apogée <tt>%s</tt></h3><p>" % filename "<h3>Erreur lecture du fichier Apogée <tt>%s</tt></h3><p>" % filename
+ e.args[0] + e.args[0]
+ "</p>" + "</p>"
) ) from e
self.etape_apogee = self.get_etape_apogee() # 'V1RT' self.etape_apogee = self.get_etape_apogee() # 'V1RT'
self.vdi_apogee = self.get_vdi_apogee() # '111' self.vdi_apogee = self.get_vdi_apogee() # '111'
self.etape = ApoEtapeVDI(etape=self.etape_apogee, vdi=self.vdi_apogee) self.etape = ApoEtapeVDI(etape=self.etape_apogee, vdi=self.vdi_apogee)
@ -760,7 +762,6 @@ class ApoData(object):
def read_csv(self, data: str): def read_csv(self, data: str):
if not data: if not data:
raise ScoFormatError("Fichier Apogée vide !") raise ScoFormatError("Fichier Apogée vide !")
f = StringIOFileLineWrapper(data) # pour traiter comme un fichier f = StringIOFileLineWrapper(data) # pour traiter comme un fichier
# check that we are at the begining of Apogee CSV # check that we are at the begining of Apogee CSV
line = f.readline().strip() line = f.readline().strip()
@ -768,7 +769,10 @@ class ApoData(object):
raise ScoFormatError("format incorrect: pas de XX-APO_TITRES-XX") raise ScoFormatError("format incorrect: pas de XX-APO_TITRES-XX")
# 1-- En-tête: du début jusqu'à la balise XX-APO_VALEURS-XX # 1-- En-tête: du début jusqu'à la balise XX-APO_VALEURS-XX
idx = data.index("XX-APO_VALEURS-XX") try:
idx = data.index("XX-APO_VALEURS-XX")
except ValueError as exc:
raise ScoFormatError("format incorrect: pas de XX-APO_VALEURS-XX") from exc
self.header = data[:idx] self.header = data[:idx]
# 2-- Titres: # 2-- Titres:
@ -1178,7 +1182,7 @@ def nar_etuds_table(apo_data, NAR_Etuds):
def export_csv_to_apogee( def export_csv_to_apogee(
apo_csv_data, apo_csv_data: str,
periode=None, periode=None,
dest_zip=None, dest_zip=None,
export_res_etape=True, export_res_etape=True,

View File

@ -43,7 +43,7 @@
apo_csv_get() apo_csv_get()
API: API:
apo_csv_store( annee_scolaire, sem_id) # apo_csv_store(csv_data, annee_scolaire, sem_id)
store maq file (archive) store maq file (archive)
apo_csv_get(etape_apo, annee_scolaire, sem_id, vdi_apo=None) apo_csv_get(etape_apo, annee_scolaire, sem_id, vdi_apo=None)
@ -101,7 +101,7 @@ ApoCSVArchive = ApoCSVArchiver()
def apo_csv_store(csv_data: str, annee_scolaire, sem_id): def apo_csv_store(csv_data: str, annee_scolaire, sem_id):
""" """
csv_data: maquette content (string) csv_data: maquette content (str))
annee_scolaire: int (2016) annee_scolaire: int (2016)
sem_id: 0 (année ?), 1 (premier semestre de l'année) ou 2 (deuxième semestre) sem_id: 0 (année ?), 1 (premier semestre de l'année) ou 2 (deuxième semestre)
:return: etape_apo du fichier CSV stocké :return: etape_apo du fichier CSV stocké
@ -378,7 +378,7 @@ e.associate_sco( apo_data)
print apo_csv_list_stored_archives() print apo_csv_list_stored_archives()
apo_csv_store(csv_data, annee_scolaire, sem_id) # apo_csv_store(csv_data, annee_scolaire, sem_id)

View File

@ -48,7 +48,7 @@ from app.scodoc import sco_preferences
from app.scodoc import sco_semset from app.scodoc import sco_semset
from app.scodoc import sco_etud from app.scodoc import sco_etud
from app.scodoc.gen_tables import GenTable from app.scodoc.gen_tables import GenTable
from app.scodoc.sco_apogee_csv import APO_PORTAL_ENCODING, APO_INPUT_ENCODING from app.scodoc.sco_apogee_csv import APO_INPUT_ENCODING, APO_OUTPUT_ENCODING
from app.scodoc.sco_exceptions import ScoValueError from app.scodoc.sco_exceptions import ScoValueError
@ -585,7 +585,7 @@ def _view_etuds_page(semset_id, title="", etuds=[], keys=(), format="html"):
return "\n".join(H) + html_sco_header.sco_footer() return "\n".join(H) + html_sco_header.sco_footer()
def view_apo_csv_store(semset_id="", csvfile=None, data="", autodetect=False): def view_apo_csv_store(semset_id="", csvfile=None, data: bytes = "", autodetect=False):
"""Store CSV data """Store CSV data
Le semset identifie l'annee scolaire et le semestre Le semset identifie l'annee scolaire et le semestre
Si csvfile, lit depuis FILE, sinon utilise data Si csvfile, lit depuis FILE, sinon utilise data
@ -593,9 +593,8 @@ def view_apo_csv_store(semset_id="", csvfile=None, data="", autodetect=False):
if not semset_id: if not semset_id:
raise ValueError("invalid null semset_id") raise ValueError("invalid null semset_id")
semset = sco_semset.SemSet(semset_id=semset_id) semset = sco_semset.SemSet(semset_id=semset_id)
if csvfile: if csvfile:
data = csvfile.read() data = csvfile.read() # bytes
if autodetect: if autodetect:
# check encoding (although documentation states that users SHOULD upload LATIN1) # check encoding (although documentation states that users SHOULD upload LATIN1)
data, message = sco_apogee_csv.fix_data_encoding(data) data, message = sco_apogee_csv.fix_data_encoding(data)
@ -605,19 +604,26 @@ def view_apo_csv_store(semset_id="", csvfile=None, data="", autodetect=False):
log("view_apo_csv_store: autodetection of encoding disabled by user") log("view_apo_csv_store: autodetection of encoding disabled by user")
if not data: if not data:
raise ScoValueError("view_apo_csv_store: no data") raise ScoValueError("view_apo_csv_store: no data")
# data est du bytes, encodé en APO_INPUT_ENCODING
data_str = data.decode(APO_INPUT_ENCODING)
# check si etape maquette appartient bien au semset # check si etape maquette appartient bien au semset
apo_data = sco_apogee_csv.ApoData( apo_data = sco_apogee_csv.ApoData(
data, periode=semset["sem_id"] data_str, periode=semset["sem_id"]
) # parse le fichier -> exceptions ) # parse le fichier -> exceptions
if apo_data.etape not in semset["etapes"]: if apo_data.etape not in semset["etapes"]:
raise ScoValueError( raise ScoValueError(
"Le code étape de ce fichier ne correspond pas à ceux de cet ensemble" "Le code étape de ce fichier ne correspond pas à ceux de cet ensemble"
) )
sco_etape_apogee.apo_csv_store(data, semset["annee_scolaire"], semset["sem_id"]) sco_etape_apogee.apo_csv_store(data_str, semset["annee_scolaire"], semset["sem_id"])
return flask.redirect("apo_semset_maq_status?semset_id=" + semset_id) return flask.redirect(
url_for(
"notes.apo_semset_maq_status",
scodoc_dept=g.scodoc_dept,
semset_id=semset_id,
)
)
def view_apo_csv_download_and_store(etape_apo="", semset_id=""): def view_apo_csv_download_and_store(etape_apo="", semset_id=""):
@ -629,9 +635,9 @@ def view_apo_csv_download_and_store(etape_apo="", semset_id=""):
data = sco_portal_apogee.get_maquette_apogee( data = sco_portal_apogee.get_maquette_apogee(
etape=etape_apo, annee_scolaire=semset["annee_scolaire"] etape=etape_apo, annee_scolaire=semset["annee_scolaire"]
) )
# here, data is utf8 # here, data is str
# but we store and generate latin1 files, to ease further import in Apogée # but we store and generate latin1 files, to ease further import in Apogée
data = data.decode(APO_PORTAL_ENCODING).encode(APO_INPUT_ENCODING) # XXX #py3 data = data.encode(APO_OUTPUT_ENCODING)
return view_apo_csv_store(semset_id, data=data, autodetect=False) return view_apo_csv_store(semset_id, data=data, autodetect=False)
@ -669,7 +675,7 @@ def view_apo_csv(etape_apo="", semset_id="", format="html"):
sem_id = semset["sem_id"] sem_id = semset["sem_id"]
csv_data = sco_etape_apogee.apo_csv_get(etape_apo, annee_scolaire, sem_id) csv_data = sco_etape_apogee.apo_csv_get(etape_apo, annee_scolaire, sem_id)
if format == "raw": if format == "raw":
scu.send_file(csv_data, etape_apo, suffix=".txt", mime=scu.CSV_MIMETYPE) return scu.send_file(csv_data, etape_apo, suffix=".txt", mime=scu.CSV_MIMETYPE)
apo_data = sco_apogee_csv.ApoData(csv_data, periode=semset["sem_id"]) apo_data = sco_apogee_csv.ApoData(csv_data, periode=semset["sem_id"])

View File

@ -292,6 +292,8 @@ def formsemestre_inscr_passage(
etuds = [int(x) for x in etuds.split(",") if x] etuds = [int(x) for x in etuds.split(",") if x]
elif isinstance(etuds, int): elif isinstance(etuds, int):
etuds = [etuds] etuds = [etuds]
elif etuds and isinstance(etuds[0], str):
etuds = [int(x) for x in etuds]
auth_etuds_by_sem, inscrits, candidats = list_authorized_etuds_by_sem(sem) auth_etuds_by_sem, inscrits, candidats = list_authorized_etuds_by_sem(sem)
etuds_set = set(etuds) etuds_set = set(etuds)

View File

@ -544,7 +544,7 @@ def check_paiement_etuds(etuds):
etud["paiementinscription_str"] = "(pb cnx Apogée)" etud["paiementinscription_str"] = "(pb cnx Apogée)"
def get_maquette_apogee(etape="", annee_scolaire=""): def get_maquette_apogee(etape="", annee_scolaire="") -> str:
"""Maquette CSV Apogee pour une étape et une annee scolaire""" """Maquette CSV Apogee pour une étape et une annee scolaire"""
maquette_url = get_maquette_url() maquette_url = get_maquette_url()
if not maquette_url: if not maquette_url:

View File

@ -395,6 +395,8 @@ def do_semset_add_sem(semset_id, formsemestre_id):
"""Add a sem to a semset""" """Add a sem to a semset"""
if not semset_id: if not semset_id:
raise ScoValueError("empty semset_id") raise ScoValueError("empty semset_id")
if formsemestre_id == "":
raise ScoValueError("pas de semestre choisi !")
s = SemSet(semset_id=semset_id) s = SemSet(semset_id=semset_id)
# check for valid formsemestre_id # check for valid formsemestre_id
_ = sco_formsemestre.get_formsemestre(formsemestre_id) # raise exc _ = sco_formsemestre.get_formsemestre(formsemestre_id) # raise exc

View File

@ -24,7 +24,7 @@
{% block app_content %} {% block app_content %}
<h1>Modification du compte ScoDoc <tt>{{form.user_name.data}}</tt></h1> <h1>Modification du compte ScoDoc <tt>{{form.user_name.data}}</tt></h1>
<div class="help"> <div class="help">
<p>Identifiez-vous avez votre mot de passe actuel</p> <p>Identifiez-vous avec votre mot de passe actuel</p>
</div> </div>
<form method=post> <form method=post>
{{ form.user_name }} {{ form.user_name }}

View File

@ -753,7 +753,7 @@ def user_info_page(user_name=None):
if not user_name: if not user_name:
user = current_user user = current_user
else: else:
user = User.query.filter_by(user_name=user_name).first() user = User.query.filter_by(user_name=str(user_name)).first()
if not user: if not user:
raise ScoValueError("invalid user_name") raise ScoValueError("invalid user_name")