Améliore téléchargement fichiers (REQUEST => send_file)

This commit is contained in:
Emmanuel Viennet 2021-09-16 00:15:10 +02:00
parent 6dba8933c4
commit 0fedb7771c
28 changed files with 114 additions and 92 deletions

View File

@ -610,7 +610,6 @@ class GenTable(object):
format="html",
page_title="",
filename=None,
REQUEST=None,
javascripts=[],
with_html_headers=True,
publish=True,
@ -643,35 +642,55 @@ class GenTable(object):
H.append(html_sco_header.sco_footer())
return "\n".join(H)
elif format == "pdf":
objects = self.pdf()
doc = sco_pdf.pdf_basic_page(
objects, title=title, preferences=self.preferences
pdf_objs = self.pdf()
pdf_doc = sco_pdf.pdf_basic_page(
pdf_objs, title=title, preferences=self.preferences
)
if publish:
return scu.sendPDFFile(REQUEST, doc, filename + ".pdf")
return scu.send_file(
pdf_doc,
filename,
suffix=".pdf",
mime=scu.PDF_MIMETYPE,
attached=True,
)
else:
return doc
elif format == "xls" or format == "xlsx":
return pdf_doc
elif format == "xls" or format == "xlsx": # dans les 2 cas retourne du xlsx
xls = self.excel()
if publish:
return sco_excel.send_excel_file(
REQUEST, xls, filename + scu.XLSX_SUFFIX
return scu.send_file(
xls,
filename,
suffix=scu.XLSX_SUFFIX,
mime=scu.XLSX_MIMETYPE,
attached=True,
)
else:
return xls
elif format == "text":
return self.text()
elif format == "csv":
return scu.sendCSVFile(REQUEST, self.text(), filename + ".csv")
return scu.send_file(
self.text(),
filename,
suffix=".csv",
mime=scu.CSV_MIMETYPE,
attached=True,
)
elif format == "xml":
xml = self.xml()
if REQUEST and publish:
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
if publish:
return scu.send_file(
xml, filename, suffix=".xml", mime=scu.XML_MIMETYPE, attached=True
)
return xml
elif format == "json":
js = self.json()
if REQUEST and publish:
REQUEST.RESPONSE.setHeader("content-type", scu.JSON_MIMETYPE)
if publish:
return scu.send_file(
js, filename, suffix=".json", mime=scu.JSON_MIMETYPE, attached=True
)
return js
else:
log("make_page: format=%s" % format)
@ -732,5 +751,5 @@ if __name__ == "__main__":
document.build(objects)
data = doc.getvalue()
open("/tmp/gen_table.pdf", "wb").write(data)
p = T.make_page(format="pdf", REQUEST=None)
p = T.make_page(format="pdf")
open("toto.pdf", "wb").write(p)

View File

@ -844,9 +844,9 @@ def ListeAbsEtud(
# Formats non HTML et demande d'une seule table:
if format != "html" and format != "text":
if absjust_only == 1:
return tab_absjust.make_page(format=format, REQUEST=REQUEST)
return tab_absjust.make_page(format=format)
else:
return tab_absnonjust.make_page(format=format, REQUEST=REQUEST)
return tab_absnonjust.make_page(format=format)
if format == "html":
# Mise en forme HTML:

View File

@ -47,12 +47,13 @@
qui est une description (humaine, format libre) de l'archive.
"""
import os
import time
import datetime
import glob
import mimetypes
import os
import re
import shutil
import glob
import time
import flask
from flask import g
@ -246,29 +247,13 @@ class BaseArchiver(object):
def get_archived_file(self, REQUEST, oid, archive_name, filename):
"""Recupere donnees du fichier indiqué et envoie au client"""
# XXX très incomplet: devrait inférer et assigner un type MIME
archive_id = self.get_id_from_name(oid, archive_name)
data = self.get(archive_id, filename)
ext = os.path.splitext(filename.lower())[1]
if ext == ".html" or ext == ".htm":
return data
elif ext == ".xml":
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
return data
elif ext == ".xls":
return sco_excel.send_excel_file(
REQUEST, data, filename, mime=scu.XLS_MIMETYPE
)
elif ext == ".xlsx":
return sco_excel.send_excel_file(
REQUEST, data, filename, mime=scu.XLSX_MIMETYPE
)
elif ext == ".csv":
return scu.sendCSVFile(REQUEST, data, filename)
elif ext == ".pdf":
return scu.sendPDFFile(REQUEST, data, filename)
REQUEST.RESPONSE.setHeader("content-type", "application/octet-stream")
return data # should set mimetype for known files like images
mime = mimetypes.guess_type(filename)[0]
if mime is None:
mime = "application/octet-stream"
return scu.send_file(data, filename, mime=mime)
class SemsArchiver(BaseArchiver):

View File

@ -197,4 +197,4 @@ def formsemestre_estim_cost(
coef_tp,
)
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)

View File

@ -70,7 +70,6 @@ def report_debouche_date(start_year=None, format="html", REQUEST=None):
init_qtip=True,
javascripts=["js/etud_info.js"],
format=format,
REQUEST=REQUEST,
with_html_headers=True,
)

View File

@ -1039,7 +1039,7 @@ def formation_table_recap(formation_id, format="html", REQUEST=None):
pdf_title=title,
preferences=sco_preferences.SemPreferences(),
)
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
def ue_list_semestre_ids(ue):

View File

@ -578,7 +578,7 @@ def _view_etuds_page(
preferences=sco_preferences.SemPreferences(),
)
if format != "html":
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
H.append(tab.html())
@ -678,7 +678,8 @@ def view_apo_csv(etape_apo="", semset_id="", format="html", REQUEST=None):
sem_id = semset["sem_id"]
csv_data = sco_etape_apogee.apo_csv_get(etape_apo, annee_scolaire, sem_id)
if format == "raw":
return scu.sendCSVFile(REQUEST, csv_data, etape_apo + ".txt")
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"])
(
@ -753,7 +754,7 @@ def view_apo_csv(etape_apo="", semset_id="", format="html", REQUEST=None):
)
if format != "html":
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
H += [
tab.html(),

View File

@ -921,7 +921,7 @@ def formsemestre_evaluations_delai_correction(
+ "",
filename=scu.make_filename("evaluations_delais_" + sem["titreannee"]),
)
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
def module_evaluation_insert_before(ModEvals, next_eval):

View File

@ -246,9 +246,7 @@ def scodoc_table_results(
"&types_parcours=".join([str(x) for x in types_parcours]),
)
if format != "html":
return tab.make_page(
format=format, with_html_headers=False, REQUEST=REQUEST
)
return tab.make_page(format=format, with_html_headers=False)
tab_html = tab.html()
nb_rows = tab.get_nb_rows()
else:

View File

@ -404,6 +404,4 @@ def search_inscr_etud_by_nip(code_nip, REQUEST=None, format="json"):
)
tab = GenTable(columns_ids=columns_ids, rows=T)
return tab.make_page(
format=format, with_html_headers=False, REQUEST=REQUEST, publish=True
)
return tab.make_page(format=format, with_html_headers=False, publish=True)

View File

@ -583,7 +583,7 @@ def view_formsemestre_by_etape(etape_apo=None, format="html", REQUEST=None):
</form>""",
)
tab.base_url = "%s?etape_apo=%s" % (REQUEST.URL0, etape_apo or "")
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
def sem_has_etape(sem, code_etape):

View File

@ -728,7 +728,7 @@ def formsemestre_description(
tab.html_before_table += "checked"
tab.html_before_table += ">indiquer les évaluations</input></form>"
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
# genere liste html pour accès aux groupes de ce semestre

View File

@ -706,7 +706,7 @@ def groups_table(
):
if format == "moodlecsv":
format = "csv"
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
elif format == "xlsappel":
xls = sco_excel.excel_feuille_listeappel(
@ -977,4 +977,4 @@ def export_groups_as_moodle_csv(formsemestre_id=None, REQUEST=None):
text_with_titles=prefs["moodle_csv_with_headerline"],
preferences=prefs,
)
return tab.make_page(format="csv", REQUEST=REQUEST)
return tab.make_page(format="csv")

View File

@ -482,7 +482,7 @@ def _make_table_notes(
# html_generate_cells=False # la derniere ligne (moyennes) est incomplete
)
t = tab.make_page(format=format, with_html_headers=False, REQUEST=REQUEST)
t = tab.make_page(format=format, with_html_headers=False)
if format != "html":
return t

View File

@ -85,7 +85,7 @@ def scodoc_table_etuds_lycees(format="html", REQUEST=None):
no_links=True,
)
tab.base_url = REQUEST.URL0
t = tab.make_page(format=format, with_html_headers=False, REQUEST=REQUEST)
t = tab.make_page(format=format, with_html_headers=False)
if format != "html":
return t
H = [
@ -192,7 +192,7 @@ def formsemestre_etuds_lycees(
tab.base_url += "&only_primo=1"
if no_grouping:
tab.base_url += "&no_grouping=1"
t = tab.make_page(format=format, with_html_headers=False, REQUEST=REQUEST)
t = tab.make_page(format=format, with_html_headers=False)
if format != "html":
return t
F = [

View File

@ -393,7 +393,7 @@ def do_placement(REQUEST):
preferences=sco_preferences.SemPreferences(M["formsemestre_id"]),
# html_generate_cells=False # la derniere ligne (moyennes) est incomplete
)
t = tab.make_page(format="pdf", with_html_headers=False, REQUEST=REQUEST)
t = tab.make_page(format="pdf", with_html_headers=False)
return t

View File

@ -217,6 +217,5 @@ def formsemestre_poursuite_report(formsemestre_id, format="html", REQUEST=None):
init_qtip=True,
javascripts=["js/etud_info.js"],
format=format,
REQUEST=REQUEST,
with_html_headers=True,
)

View File

@ -535,7 +535,6 @@ def formsemestre_pvjury(formsemestre_id, format="html", publish=True, REQUEST=No
return tab.make_page(
format=format,
with_html_headers=False,
REQUEST=REQUEST,
publish=publish,
)
tab.base_url = "%s?formsemestre_id=%s" % (REQUEST.URL0, formsemestre_id)

View File

@ -27,8 +27,9 @@
"""Tableau recapitulatif des notes d'un semestre
"""
import time
import datetime
import json
import time
from xml.etree import ElementTree
import app.scodoc.sco_utils as scu
@ -227,11 +228,14 @@ def do_formsemestre_recapcomplet(
if format == "xml" or format == "html":
return data
elif format == "csv":
return scu.sendCSVFile(REQUEST, data, filename)
elif format[:3] == "xls":
return sco_excel.send_excel_file(REQUEST, data, filename)
return scu.send_file(data, filename=filename, mime=scu.CSV_MIMETYPE)
elif format[:3] == "xls" or format[:3] == "xlsx":
return scu.send_file(data, filename=filename, mime=scu.XLSX_MIMETYPE)
elif format == "json":
return scu.sendJSON(REQUEST, data)
js = json.dumps(data, indent=1, cls=scu.ScoDocJSONEncoder)
return scu.send_file(
js, filename=filename, suffix=scu.JSON_SUFFIX, mime=scu.JSON_MIMETYPE
)
else:
raise ValueError("unknown format %s" % format)

View File

@ -355,7 +355,6 @@ def formsemestre_report_counts(
t = tab.make_page(
title="""<h2 class="formsemestre">Comptes croisés</h2>""",
format=format,
REQUEST=REQUEST,
with_html_headers=False,
)
if format != "html":
@ -722,7 +721,7 @@ def formsemestre_suivi_cohorte(
)
if only_primo:
tab.base_url += "&only_primo=on"
t = tab.make_page(format=format, with_html_headers=False, REQUEST=REQUEST)
t = tab.make_page(format=format, with_html_headers=False)
if format != "html":
return t
@ -1210,7 +1209,7 @@ def formsemestre_suivi_parcours(
tab.base_url += "&only_primo=1"
if no_grouping:
tab.base_url += "&no_grouping=1"
t = tab.make_page(format=format, with_html_headers=False, REQUEST=REQUEST)
t = tab.make_page(format=format, with_html_headers=False)
if format != "html":
return t
F = [

View File

@ -468,7 +468,7 @@ def semset_page(format="html", REQUEST=None):
preferences=sco_preferences.SemPreferences(),
)
if format != "html":
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
page_title = "Ensembles de semestres"
H = [

View File

@ -167,7 +167,7 @@ def evaluation_list_operations(evaluation_id, REQUEST=None):
% (E["description"], E["jour"]),
preferences=sco_preferences.SemPreferences(M["formsemestre_id"]),
)
return tab.make_page(REQUEST=REQUEST)
return tab.make_page()
def formsemestre_list_saisies_notes(formsemestre_id, format="html", REQUEST=None):
@ -222,7 +222,7 @@ def formsemestre_list_saisies_notes(formsemestre_id, format="html", REQUEST=None
+ scu.timedate_human_repr()
+ "",
)
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
def get_note_history(evaluation_id, etudid, REQUEST=None, fmt=""):

View File

@ -217,7 +217,7 @@ def list_users(
preferences=sco_preferences.SemPreferences(),
)
return tab.make_page(format=format, with_html_headers=False, REQUEST=REQUEST)
return tab.make_page(format=format, with_html_headers=False)
def get_user_list(dept=None, with_inactives=False):

View File

@ -54,6 +54,7 @@ from flask import g, current_app
from PIL import Image as PILImage
from flask import g, url_for, request, make_response
from werkzeug.wrappers import response
from config import Config
from app import log
@ -300,12 +301,33 @@ SCO_DUMP_UP_URL = "https://scodoc.iutv.univ-paris13.fr/scodoc-installmgr/upload-
CSV_FIELDSEP = ";"
CSV_LINESEP = "\n"
CSV_MIMETYPE = "text/comma-separated-values"
CSV_SUFFIX = ".csv"
JSON_MIMETYPE = "application/json"
JSON_SUFFIX = ".json"
PDF_MIMETYPE = "application/pdf"
PDF_SUFFIX = ".pdf"
XLS_MIMETYPE = "application/vnd.ms-excel"
XLSX_MIMETYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
XLSX_SUFFIX = ".xlsx"
PDF_MIMETYPE = "application/pdf"
XML_MIMETYPE = "text/xml"
JSON_MIMETYPE = "application/json"
XML_SUFFIX = ".xml"
def get_mime_suffix(format_code: str) -> tuple[str, str]:
"""Returns (MIME, SUFFIX) from format_code == "xls", "xml", ...
SUFFIX includes the dot: ".xlsx", ".xml", ...
"xls" and "xlsx" format codes give XLSX
"""
d = {
"csv": (CSV_MIMETYPE, CSV_SUFFIX),
"xls": (XLSX_MIMETYPE, XLSX_SUFFIX),
"xlsx": (XLSX_MIMETYPE, XLSX_SUFFIX),
"pdf": (PDF_MIMETYPE, PDF_SUFFIX),
"xml": (XML_MIMETYPE, XML_SUFFIX),
"json": (JSON_MIMETYPE, JSON_SUFFIX),
}
return d[format_code]
# Admissions des étudiants
# Différents types de voies d'admission:
@ -490,7 +512,7 @@ def is_valid_filename(filename):
return VALID_EXP.match(filename)
def sendCSVFile(REQUEST, data, filename):
def sendCSVFile(REQUEST, data, filename): # DEPRECATED ne plus utiliser
"""publication fichier.
(on ne doit rien avoir émis avant, car ici sont générés les entetes)
"""
@ -528,9 +550,7 @@ class ScoDocJSONEncoder(json.JSONEncoder):
def sendJSON(REQUEST, data):
js = json.dumps(data, indent=1, cls=ScoDocJSONEncoder)
if REQUEST:
REQUEST.RESPONSE.setHeader("content-type", JSON_MIMETYPE)
return js
return send_file(js, filename="sco_data.json", mime=JSON_MIMETYPE, attached=False)
def sendXML(REQUEST, data, tagname=None, force_outer_xml_tag=True):
@ -558,7 +578,8 @@ def sendResult(REQUEST, data, name=None, format=None, force_outer_xml_tag=True):
raise ValueError("invalid format: %s" % format)
def send_file(self, data, filename, suffix="", mime=None, attached=False):
def send_file(data, filename, suffix="", mime=None, attached=True):
"Build Flask Response for file download of given type"
if suffix:
filename += suffix
filename = make_filename(filename)

View File

@ -966,7 +966,7 @@ ou entrez une date pour visualiser les absents un jour donné&nbsp;:
"""
% (REQUEST.URL0, formsemestre_id, groups_infos.get_form_elem()),
)
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
@bp.route("/EtatAbsencesDate")
@ -1102,7 +1102,7 @@ def AddBilletAbsence(
billets = sco_abs.billet_absence_list(cnx, {"billet_id": billet_id})
tab = _tableBillets(billets, etud=etud)
log("AddBilletAbsence: new billet_id=%s (%gs)" % (billet_id, time.time() - t0))
return tab.make_page(REQUEST=REQUEST, format="xml")
return tab.make_page(format="xml")
else:
return billet_id
@ -1233,7 +1233,7 @@ def listeBilletsEtud(etudid=False, REQUEST=None, format="html"):
cnx = ndb.GetDBConnexion()
billets = sco_abs.billet_absence_list(cnx, {"etudid": etud["etudid"]})
tab = _tableBillets(billets, etud=etud)
return tab.make_page(REQUEST=REQUEST, format=format)
return tab.make_page(format=format)
@bp.route(

View File

@ -224,7 +224,7 @@ def index_html(REQUEST=None, etud_nom=None, limit=50, offset="", format="html"):
preferences=context.get_preferences(),
)
if format != "html":
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
else:
H = [
entreprise_header(REQUEST=REQUEST, page_title="Suivi entreprises"),
@ -297,7 +297,7 @@ def entreprise_contact_list(entreprise_id=None, format="html", REQUEST=None):
preferences=context.get_preferences(),
)
if format != "html":
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
H.append(tab.html())
@ -403,7 +403,7 @@ def entreprise_correspondant_list(
preferences=context.get_preferences(),
)
if format != "html":
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
H.append(tab.html())

View File

@ -1090,7 +1090,7 @@ def view_module_abs(REQUEST, moduleimpl_id, format="html"):
)
if format != "html":
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
return "\n".join(H) + tab.html() + html_sco_header.sco_footer()
@ -1257,7 +1257,7 @@ def formsemestre_enseignants_list(REQUEST, formsemestre_id, format="html"):
caption="Tous les enseignants (responsables ou associés aux modules de ce semestre) apparaissent. Le nombre de saisies d'absences est le nombre d'opérations d'ajout effectuées sur ce semestre, sans tenir compte des annulations ou double saisies.",
preferences=sco_preferences.SemPreferences(formsemestre_id),
)
return T.make_page(page_title=title, title=title, REQUEST=REQUEST, format=format)
return T.make_page(page_title=title, title=title, format=format)
@bp.route("/edit_enseignants_form_delete", methods=["GET", "POST"])

View File

@ -279,7 +279,7 @@ def showEtudLog(etudid, format="html", REQUEST=None):
preferences=sco_preferences.SemPreferences(),
)
return tab.make_page(format=format, REQUEST=REQUEST)
return tab.make_page(format=format)
# ---------- PAGE ACCUEIL (listes) --------------