diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index 2fce3c39..c3bf6093 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -82,14 +82,15 @@ XXX A vérifier: import collections import datetime +from functools import reduce import io import os +import pprint import re import time - from zipfile import ZipFile -import pprint -from functools import reduce + +from flask import send_file # Pour la détection auto de l'encodage des fichiers Apogée: from chardet import detect as chardet_detect @@ -500,7 +501,7 @@ class ApoEtud(dict): # print 'comp_elt_annuel cur_sem=%s autre_sem=%s' % (cur_sem['formsemestre_id'], autre_sem['formsemestre_id']) if not cur_sem: # l'étudiant n'a pas de semestre courant ?! - log("comp_elt_annuel: %s no cur_sem" % etudid) + log("comp_elt_annuel: etudid %s has no cur_sem" % etudid) return VOID_APO_RES cur_nt = sco_cache.NotesTableCache.get(cur_sem["formsemestre_id"]) cur_decision = cur_nt.get_etud_decision_sem(etudid) @@ -756,22 +757,19 @@ class ApoData(object): else: self.sems_periode = None - def read_csv(self, data): + def read_csv(self, data: str): if not data: raise FormatError("Fichier Apogée vide !") - data_utf8 = data.decode(APO_INPUT_ENCODING).encode( - scu.SCO_ENCODING - ) # XXX #sco8 - f = StringIOFileLineWrapper(data_utf8) # pour traiter comme un fichier + f = StringIOFileLineWrapper(data) # pour traiter comme un fichier # check that we are at the begining of Apogee CSV line = f.readline().strip() if line != "XX-APO_TITRES-XX": raise FormatError("format incorrect: pas de XX-APO_TITRES-XX") # 1-- En-tête: du début jusqu'à la balise XX-APO_VALEURS-XX - idx = data_utf8.index("XX-APO_VALEURS-XX") - self.header = data_utf8[:idx] # en codage ScoDoc (utf8) + idx = data.index("XX-APO_VALEURS-XX") + self.header = data[:idx] # 2-- Titres: # on va y chercher apoC_Fichier_Exp qui donnera le nom du fichier @@ -1236,7 +1234,7 @@ def export_csv_to_apogee( # Create ZIP if not dest_zip: - data = io.StringIO() + data = io.BytesIO() dest_zip = ZipFile(data, "w") my_zip = True else: @@ -1293,7 +1291,7 @@ def export_csv_to_apogee( ) log(logf.getvalue()) # sortie aussi sur le log ScoDoc - csv_data = f.getvalue().decode(scu.SCO_ENCODING).encode(APO_OUTPUT_ENCODING) # XXX + csv_data = f.getvalue().encode(APO_OUTPUT_ENCODING) # Write data to ZIP dest_zip.writestr(csv_filename, csv_data) @@ -1304,13 +1302,12 @@ def export_csv_to_apogee( if my_zip: dest_zip.close() - size = data.tell() - content_type = "application/zip" - REQUEST.RESPONSE.setHeader( - "content-disposition", 'attachement; filename="%s-scodoc.zip"' % basename + data.seek(0) + return send_file( + data, + mimetype="application/zip", + download_name=basename + "-scodoc.zip", + as_attachment=True, ) - REQUEST.RESPONSE.setHeader("content-type", content_type) - REQUEST.RESPONSE.setHeader("content-length", size) - return data.getvalue() else: return None # zip modified in place diff --git a/app/scodoc/sco_etape_apogee.py b/app/scodoc/sco_etape_apogee.py index 1e7a4cdd..5409c58e 100644 --- a/app/scodoc/sco_etape_apogee.py +++ b/app/scodoc/sco_etape_apogee.py @@ -99,12 +99,14 @@ ApoCSVArchive = ApoCSVArchiver() # return archive_id -def apo_csv_store(csv_data, annee_scolaire, sem_id): +def apo_csv_store(csv_data: str, annee_scolaire, sem_id): """ - csv_data: maquette content, as a string, encoding given by APO_INPUT_ENCODING (latin-1, not utf8) + csv_data: maquette content (string) annee_scolaire: int (2016) sem_id: 0 (année ?), 1 (premier semestre de l'année) ou 2 (deuxième semestre) :return: etape_apo du fichier CSV stocké + + Note: le fichier CSV est stocké encodé en APO_OUTPUT_ENCODING """ # sanity check filesize = len(csv_data) @@ -128,7 +130,8 @@ def apo_csv_store(csv_data, annee_scolaire, sem_id): oid = "%d-%d" % (annee_scolaire, sem_id) description = "%s;%s;%s" % (str(apo_data.etape), annee_scolaire, sem_id) archive_id = ApoCSVArchive.create_obj_archive(oid, description) - ApoCSVArchive.store(archive_id, filename, csv_data) + csv_data_bytes = csv_data.encode(sco_apogee_csv.APO_OUTPUT_ENCODING) + ApoCSVArchive.store(archive_id, filename, csv_data_bytes) return apo_data.etape @@ -199,7 +202,7 @@ def apo_csv_get_archive(etape_apo, annee_scolaire="", sem_id=""): return None -def apo_csv_get(etape_apo="", annee_scolaire="", sem_id=""): +def apo_csv_get(etape_apo="", annee_scolaire="", sem_id="") -> str: """Get CSV data for given etape_apo :return: CSV, as a data string """ @@ -210,7 +213,9 @@ def apo_csv_get(etape_apo="", annee_scolaire="", sem_id=""): ) archive_id = info["archive_id"] data = ApoCSVArchive.get(archive_id, etape_apo + ".csv") - return data + # ce fichier a été archivé donc généré par ScoDoc + # son encodage est donc APO_OUTPUT_ENCODING + return data.decode(sco_apogee_csv.APO_OUTPUT_ENCODING) # ------------------------------------------------------------------------ diff --git a/app/scodoc/sco_etape_apogee_view.py b/app/scodoc/sco_etape_apogee_view.py index 3345eb10..eedb7d9c 100644 --- a/app/scodoc/sco_etape_apogee_view.py +++ b/app/scodoc/sco_etape_apogee_view.py @@ -28,22 +28,21 @@ """ScoDoc : formulaires gestion maquettes Apogee / export resultats """ -from io import StringIO +import io from zipfile import ZipFile import flask -from flask import url_for, g +from flask import url_for, g, send_file + +# from werkzeug.utils import send_file import app.scodoc.sco_utils as scu from app import log from app.scodoc import html_sco_header -from app.scodoc import notes_table from app.scodoc import sco_apogee_csv -from app.scodoc import sco_archives from app.scodoc import sco_etape_apogee from app.scodoc import sco_formations from app.scodoc import sco_formsemestre -from app.scodoc import sco_formsemestre_status from app.scodoc import sco_portal_apogee from app.scodoc import sco_preferences from app.scodoc import sco_semset @@ -180,15 +179,6 @@ def apo_semset_maq_status( H.append('