diff --git a/app/scodoc/sco_apogee_compare.py b/app/scodoc/sco_apogee_compare.py index 6c967604..0c93c665 100644 --- a/app/scodoc/sco_apogee_compare.py +++ b/app/scodoc/sco_apogee_compare.py @@ -43,6 +43,7 @@ Pour chaque étudiant commun: comparer les résultats """ +from flask import g, url_for from app import log from app.scodoc import sco_apogee_csv @@ -72,11 +73,11 @@ def apo_compare_csv_form(): """
Fichier Apogée A: - +
Fichier Apogée B: - +
autodétecter encodage
@@ -88,17 +89,36 @@ def apo_compare_csv_form(): return "\n".join(H) -def apo_compare_csv(A_file, B_file, autodetect=True): +def apo_compare_csv(file_a, file_b, autodetect=True): """Page comparing 2 Apogee CSV files""" - A = _load_apo_data(A_file, autodetect=autodetect) - B = _load_apo_data(B_file, autodetect=autodetect) - + try: + apo_data_a = _load_apo_data(file_a, autodetect=autodetect) + apo_data_b = _load_apo_data(file_b, autodetect=autodetect) + except (UnicodeDecodeError, UnicodeEncodeError) as exc: + dest_url = url_for("notes.semset_page", scodoc_dept=g.scodoc_dept) + if autodetect: + raise ScoValueError( + """ + Erreur: l'encodage de l'un des fichiers est mal détecté. + Essayez sans auto-détection, ou vérifiez le codage et le contenu + des fichiers. + """, + dest_url=dest_url, + ) from exc + else: + raise ScoValueError( + f""" + Erreur: l'encodage de l'un des fichiers est incorrect. + Vérifiez qu'il est bien en {sco_apogee_csv.APO_INPUT_ENCODING} + """, + dest_url=dest_url, + ) from exc H = [ html_sco_header.sco_header(page_title="Comparaison de fichiers Apogée"), "

Comparaison de fichiers Apogée

", _help_txt, '
', - _apo_compare_csv(A, B), + _apo_compare_csv(apo_data_a, apo_data_b), "
", """

Autre comparaison

""", html_sco_header.sco_footer(), @@ -112,9 +132,9 @@ def _load_apo_data(csvfile, autodetect=True): if autodetect: data_b, message = sco_apogee_csv.fix_data_encoding(data_b) if message: - log("apo_compare_csv: %s" % message) + log(f"apo_compare_csv: {message}") if not data_b: - raise ScoValueError("apo_compare_csv: no data") + raise ScoValueError("fichier vide ? (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) return apo_data diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index 212bb133..8d21d579 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -155,28 +155,25 @@ def fix_data_encoding( text: bytes, default_source_encoding=APO_INPUT_ENCODING, dest_encoding=APO_INPUT_ENCODING, -) -> bytes: +) -> tuple[bytes, str]: """Try to ensure that text is using dest_encoding returns converted text, and a message describing the conversion. + + Raises UnicodeEncodeError en cas de problème, en général liée à + une auto-détection errornée. """ message = "" detected_encoding = guess_data_encoding(text) if not detected_encoding: if default_source_encoding != dest_encoding: - message = "converting from %s to %s" % ( - default_source_encoding, - dest_encoding, - ) - text = text.decode(default_source_encoding).encode( - dest_encoding - ) # XXX #py3 #sco8 à tester + message = f"converting from {default_source_encoding} to {dest_encoding}" + text = text.decode(default_source_encoding).encode(dest_encoding) else: if detected_encoding != dest_encoding: - message = "converting from detected %s to %s" % ( - detected_encoding, - dest_encoding, + message = ( + f"converting from detected {default_source_encoding} to {dest_encoding}" ) - text = text.decode(detected_encoding).encode(dest_encoding) # XXX + text = text.decode(detected_encoding).encode(dest_encoding) return text, message diff --git a/app/scodoc/sco_etape_apogee_view.py b/app/scodoc/sco_etape_apogee_view.py index e37b0fd8..ac602873 100644 --- a/app/scodoc/sco_etape_apogee_view.py +++ b/app/scodoc/sco_etape_apogee_view.py @@ -591,19 +591,45 @@ def view_apo_csv_store(semset_id="", csvfile=None, data: bytes = "", autodetect= if not semset_id: raise ValueError("invalid null semset_id") semset = sco_semset.SemSet(semset_id=semset_id) - if csvfile: - data = csvfile.read() # bytes + try: + if csvfile: + data = csvfile.read() # bytes + if autodetect: + # check encoding (although documentation states that users SHOULD upload LATIN1) + + data, message = sco_apogee_csv.fix_data_encoding(data) + if message: + log(f"view_apo_csv_store: {message}") + else: + log("view_apo_csv_store: autodetection of encoding disabled by user") + if not 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) + except (UnicodeDecodeError, UnicodeEncodeError) as exc: + dest_url = url_for( + "notes.apo_semset_maq_status", + scodoc_dept=g.scodoc_dept, + semset_id=semset_id, + ) if autodetect: - # check encoding (although documentation states that users SHOULD upload LATIN1) - data, message = sco_apogee_csv.fix_data_encoding(data) - if message: - log("view_apo_csv_store: %s" % message) + raise ScoValueError( + f""" + Erreur: l'encodage du fichier est mal détecté. + Essayez sans auto-détection, ou vérifiez le codage et le contenu + du fichier (qui doit être en {sco_apogee_csv.APO_INPUT_ENCODING}). + """, + dest_url=dest_url, + ) from exc else: - log("view_apo_csv_store: autodetection of encoding disabled by user") - if not 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) + raise ScoValueError( + f""" + Erreur: l'encodage du fichier est incorrect. + Vérifiez qu'il est bien en {sco_apogee_csv.APO_INPUT_ENCODING} + """, + dest_url=dest_url, + ) from exc + # check si etape maquette appartient bien au semset apo_data = sco_apogee_csv.ApoData( data_str, periode=semset["sem_id"] diff --git a/sco_version.py b/sco_version.py index 98f0f59b..c42cd066 100644 --- a/sco_version.py +++ b/sco_version.py @@ -1,7 +1,7 @@ # -*- mode: python -*- # -*- coding: utf-8 -*- -SCOVERSION = "9.4.20" +SCOVERSION = "9.4.35" SCONAME = "ScoDoc"