forked from ScoDoc/ScoDoc
preparation envoi fichier
This commit is contained in:
parent
c8872bd220
commit
c44aa808df
@ -60,6 +60,7 @@ from app.scodoc import sco_pdf
|
|||||||
from app.scodoc import sco_xml
|
from app.scodoc import sco_xml
|
||||||
from app.scodoc.sco_pdf import SU
|
from app.scodoc.sco_pdf import SU
|
||||||
from app import log
|
from app import log
|
||||||
|
from app.scodoc.sco_utils import flaskPDFResponse
|
||||||
|
|
||||||
|
|
||||||
def mark_paras(L, tags):
|
def mark_paras(L, tags):
|
||||||
@ -648,30 +649,35 @@ class GenTable(object):
|
|||||||
objects, title=title, preferences=self.preferences
|
objects, title=title, preferences=self.preferences
|
||||||
)
|
)
|
||||||
if publish:
|
if publish:
|
||||||
return scu.sendPDFFile(REQUEST, doc, filename + ".pdf")
|
return scu.PDF_FORMAT.send_file(doc, filename, add_suffix=True, attached=True)
|
||||||
|
# return scu.flaskPDFResponse(doc, filename + ".pdf")
|
||||||
|
# return scu.sendPDFFile(REQUEST, doc, filename + ".pdf")
|
||||||
else:
|
else:
|
||||||
return doc
|
return doc
|
||||||
elif format == "xls" or format == "xlsx":
|
elif format == "xls" or format == "xlsx":
|
||||||
xls = self.excel()
|
xls = self.excel()
|
||||||
if publish:
|
if publish:
|
||||||
return sco_excel.send_excel_file(
|
return scu.XLSX_FORMAT.send_file(xls, filename, add_suffix=True, attached=True)
|
||||||
REQUEST, xls, filename + scu.XLSX_SUFFIX
|
# return sco_excel.send_from_flask(xls, filename + scu.XLSX_SUFFIX)
|
||||||
)
|
# return sco_excel.send_excel_file(REQUEST, xls, filename + scu.XLSX_SUFFIX)
|
||||||
else:
|
else:
|
||||||
return xls
|
return xls
|
||||||
elif format == "text":
|
elif format == "text":
|
||||||
return self.text()
|
return self.text()
|
||||||
elif format == "csv":
|
elif format == "csv":
|
||||||
return scu.sendCSVFile(REQUEST, self.text(), filename + ".csv")
|
return scu.CSV_FORMAT.send_file(self.text(), filename, add_suffix=True, attached=True)
|
||||||
|
# return scu.sendCSVFile(REQUEST, self.text(), filename + ".csv")
|
||||||
elif format == "xml":
|
elif format == "xml":
|
||||||
xml = self.xml()
|
xml = self.xml()
|
||||||
if REQUEST and publish:
|
if publish:
|
||||||
REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
|
# REQUEST.RESPONSE.setHeader("content-type", scu.XML_MIMETYPE)
|
||||||
return xml
|
# return xml
|
||||||
|
return scu.XML_FORMAT.send_file(self.xml)
|
||||||
elif format == "json":
|
elif format == "json":
|
||||||
js = self.json()
|
js = self.json()
|
||||||
if REQUEST and publish:
|
if publish:
|
||||||
REQUEST.RESPONSE.setHeader("content-type", scu.JSON_MIMETYPE)
|
return scu.JSON_FORMAT.send_file(self.xml)
|
||||||
|
# REQUEST.RESPONSE.setHeader("content-type", scu.JSON_MIMETYPE)
|
||||||
return js
|
return js
|
||||||
else:
|
else:
|
||||||
log("make_page: format=%s" % format)
|
log("make_page: format=%s" % format)
|
||||||
|
@ -66,7 +66,7 @@ class COLORS(Enum):
|
|||||||
|
|
||||||
|
|
||||||
def send_from_flask(data, filename, mime=scu.XLSX_MIMETYPE):
|
def send_from_flask(data, filename, mime=scu.XLSX_MIMETYPE):
|
||||||
scu.make_filename(filename)
|
filename = scu.make_filename(filename)
|
||||||
response = make_response(data)
|
response = make_response(data)
|
||||||
response.headers['Content-Type'] = mime
|
response.headers['Content-Type'] = mime
|
||||||
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||||
|
@ -310,10 +310,7 @@ class PlacementRunner:
|
|||||||
return plan
|
return plan
|
||||||
|
|
||||||
def _production_xls(self):
|
def _production_xls(self):
|
||||||
filename = scu.make_filename(
|
filename = "placement_%s_%s%s" % (self.evalname, self.gr_title_filename, scu.XLSX_SUFFIX)
|
||||||
"placement_%s_%s%s"
|
|
||||||
% (self.evalname, self.gr_title_filename, scu.XLSX_SUFFIX)
|
|
||||||
)
|
|
||||||
xls = self._excel_feuille_placement()
|
xls = self._excel_feuille_placement()
|
||||||
return sco_excel.send_from_flask(xls, filename)
|
return sco_excel.send_from_flask(xls, filename)
|
||||||
|
|
||||||
@ -323,8 +320,8 @@ class PlacementRunner:
|
|||||||
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
|
"Date : %(jour)s - Horaire : %(heure_debut)s à %(heure_fin)s"
|
||||||
% self.eval_data
|
% self.eval_data
|
||||||
)
|
)
|
||||||
|
breakpoint()
|
||||||
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % self
|
filename = "placement_%(evalname)s_%(gr_title_filename)s.pdf" % self.__dict__
|
||||||
titles = {
|
titles = {
|
||||||
"nom": "Nom",
|
"nom": "Nom",
|
||||||
"prenom": "Prenom",
|
"prenom": "Prenom",
|
||||||
@ -339,7 +336,7 @@ class PlacementRunner:
|
|||||||
columns_ids = ["nom", "prenom", "place"]
|
columns_ids = ["nom", "prenom", "place"]
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
for etud in sorted(plan, key=lambda etud: etud[0][0]): # sort by name
|
for etud in sorted(self.plan, key=lambda item: item[0][0]): # sort by name
|
||||||
if self.etiquetage == COORD:
|
if self.etiquetage == COORD:
|
||||||
rows.append(
|
rows.append(
|
||||||
{
|
{
|
||||||
@ -362,7 +359,7 @@ class PlacementRunner:
|
|||||||
+ "",
|
+ "",
|
||||||
pdf_title=pdf_title,
|
pdf_title=pdf_title,
|
||||||
# pdf_shorttitle = '',
|
# pdf_shorttitle = '',
|
||||||
preferences=sco_preferences.SemPreferences(M["formsemestre_id"]),
|
preferences=sco_preferences.SemPreferences(self.moduleimpl_data["formsemestre_id"]),
|
||||||
# html_generate_cells=False # la derniere ligne (moyennes) est incomplete
|
# 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, REQUEST=REQUEST)
|
||||||
|
@ -49,7 +49,7 @@ import unicodedata
|
|||||||
import urllib
|
import urllib
|
||||||
from xml.etree import ElementTree
|
from xml.etree import ElementTree
|
||||||
|
|
||||||
from flask import g, current_app
|
from flask import g, current_app, make_response
|
||||||
|
|
||||||
from PIL import Image as PILImage
|
from PIL import Image as PILImage
|
||||||
|
|
||||||
@ -64,7 +64,6 @@ from app.scodoc import sco_exceptions
|
|||||||
from app.scodoc import sco_xml
|
from app.scodoc import sco_xml
|
||||||
import sco_version
|
import sco_version
|
||||||
|
|
||||||
|
|
||||||
# ----- CALCUL ET PRESENTATION DES NOTES
|
# ----- CALCUL ET PRESENTATION DES NOTES
|
||||||
NOTES_PRECISION = 1e-4 # evite eventuelles erreurs d'arrondis
|
NOTES_PRECISION = 1e-4 # evite eventuelles erreurs d'arrondis
|
||||||
NOTES_MIN = 0.0 # valeur minimale admise pour une note (sauf malus, dans [-20, 20])
|
NOTES_MIN = 0.0 # valeur minimale admise pour une note (sauf malus, dans [-20, 20])
|
||||||
@ -73,7 +72,6 @@ NOTES_NEUTRALISE = -1000.0 # notes non prises en comptes dans moyennes
|
|||||||
NOTES_SUPPRESS = -1001.0 # note a supprimer
|
NOTES_SUPPRESS = -1001.0 # note a supprimer
|
||||||
NOTES_ATTENTE = -1002.0 # note "en attente" (se calcule comme une note neutralisee)
|
NOTES_ATTENTE = -1002.0 # note "en attente" (se calcule comme une note neutralisee)
|
||||||
|
|
||||||
|
|
||||||
# Types de modules
|
# Types de modules
|
||||||
MODULE_STANDARD = 0
|
MODULE_STANDARD = 0
|
||||||
MODULE_MALUS = 1
|
MODULE_MALUS = 1
|
||||||
@ -88,7 +86,7 @@ IT_SITUATION_MISSING_STR = (
|
|||||||
"____" # shown on ficheEtud (devenir) in place of empty situation
|
"____" # shown on ficheEtud (devenir) in place of empty situation
|
||||||
)
|
)
|
||||||
|
|
||||||
RANG_ATTENTE_STR = "(attente)" # rang affiché sur bulletins quand notes en attente
|
RANG_ATTENTE_STR = "(attente)" # rang affiché sur bulletins quand notes en attente
|
||||||
|
|
||||||
# borne supérieure de chaque mention
|
# borne supérieure de chaque mention
|
||||||
NOTES_MENTIONS_TH = (
|
NOTES_MENTIONS_TH = (
|
||||||
@ -234,11 +232,9 @@ if not os.path.exists(SCO_TMP_DIR):
|
|||||||
SCODOC_LOGOS_DIR = os.path.join(SCODOC_CFG_DIR, "logos")
|
SCODOC_LOGOS_DIR = os.path.join(SCODOC_CFG_DIR, "logos")
|
||||||
LOGOS_IMAGES_ALLOWED_TYPES = ("jpg", "jpeg", "png") # remind that PIL does not read pdf
|
LOGOS_IMAGES_ALLOWED_TYPES = ("jpg", "jpeg", "png") # remind that PIL does not read pdf
|
||||||
|
|
||||||
|
|
||||||
# ----- Les outils distribués
|
# ----- Les outils distribués
|
||||||
SCO_TOOLS_DIR = os.path.join(Config.SCODOC_DIR, "tools")
|
SCO_TOOLS_DIR = os.path.join(Config.SCODOC_DIR, "tools")
|
||||||
|
|
||||||
|
|
||||||
# ----- Lecture du fichier de configuration
|
# ----- Lecture du fichier de configuration
|
||||||
from app.scodoc import sco_config
|
from app.scodoc import sco_config
|
||||||
from app.scodoc import sco_config_load
|
from app.scodoc import sco_config_load
|
||||||
@ -272,7 +268,6 @@ else:
|
|||||||
|
|
||||||
SCO_ENCODING = "utf-8" # used by Excel, XML, PDF, ...
|
SCO_ENCODING = "utf-8" # used by Excel, XML, PDF, ...
|
||||||
|
|
||||||
|
|
||||||
SCO_DEFAULT_SQL_USER = "scodoc" # should match Zope process UID
|
SCO_DEFAULT_SQL_USER = "scodoc" # should match Zope process UID
|
||||||
SCO_DEFAULT_SQL_PORT = "5432"
|
SCO_DEFAULT_SQL_PORT = "5432"
|
||||||
SCO_DEFAULT_SQL_USERS_CNX = "dbname=SCOUSERS port=%s" % SCO_DEFAULT_SQL_PORT
|
SCO_DEFAULT_SQL_USERS_CNX = "dbname=SCOUSERS port=%s" % SCO_DEFAULT_SQL_PORT
|
||||||
@ -304,8 +299,11 @@ XLS_MIMETYPE = "application/vnd.ms-excel"
|
|||||||
XLSX_MIMETYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
XLSX_MIMETYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
||||||
XLSX_SUFFIX = ".xlsx"
|
XLSX_SUFFIX = ".xlsx"
|
||||||
PDF_MIMETYPE = "application/pdf"
|
PDF_MIMETYPE = "application/pdf"
|
||||||
|
PDF_SUFFIX = ".pdf"
|
||||||
XML_MIMETYPE = "text/xml"
|
XML_MIMETYPE = "text/xml"
|
||||||
|
XML_SUFFIX = ".xml"
|
||||||
JSON_MIMETYPE = "application/json"
|
JSON_MIMETYPE = "application/json"
|
||||||
|
JSON_SUFFIX = ".json"
|
||||||
|
|
||||||
# Admissions des étudiants
|
# Admissions des étudiants
|
||||||
# Différents types de voies d'admission:
|
# Différents types de voies d'admission:
|
||||||
@ -315,6 +313,31 @@ TYPES_ADMISSION = (TYPE_ADMISSION_DEFAULT, "APB", "APB-PC", "CEF", "Direct")
|
|||||||
|
|
||||||
BULLETINS_VERSIONS = ("short", "selectedevals", "long")
|
BULLETINS_VERSIONS = ("short", "selectedevals", "long")
|
||||||
|
|
||||||
|
|
||||||
|
# File format management
|
||||||
|
class FileFormat:
|
||||||
|
def __init__(self, suffix, mime):
|
||||||
|
self._mime = mime
|
||||||
|
self._suffix = suffix
|
||||||
|
|
||||||
|
def send_file(self, data, filename, add_suffix=False, attached=False):
|
||||||
|
filename = make_filename(filename)
|
||||||
|
if add_suffix:
|
||||||
|
filename += self._suffix
|
||||||
|
response = make_response(data)
|
||||||
|
response.headers['Content-Type'] = self._mime
|
||||||
|
if attached:
|
||||||
|
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
CSV_FORMAT = FileFormat(CSV_SUFFIX, CSV_MIMETYPE)
|
||||||
|
XLSX_FORMAT = FileFormat(XLSX_SUFFIX, XLSX_MIMETYPE)
|
||||||
|
XLS_FORMAT = FileFormat(XLS_SUFFIX, XLS_MIMETYPE)
|
||||||
|
PDF_FORMAT = FileFormat(PDF_SUFFIX, PDF_MIMETYPE)
|
||||||
|
XML_FORMAT = FileFormat(XML_SUFFIX, XML_MIMETYPE)
|
||||||
|
JSON_FORMAT = FileFormat(JSON_SUFFIX, JSON_MIMETYPE)
|
||||||
|
|
||||||
# Support for ScoDoc7 compatibility
|
# Support for ScoDoc7 compatibility
|
||||||
|
|
||||||
|
|
||||||
@ -324,8 +347,8 @@ def ScoURL():
|
|||||||
= page accueil département
|
= page accueil département
|
||||||
"""
|
"""
|
||||||
return url_for("scolar.index_html", scodoc_dept=g.scodoc_dept)[
|
return url_for("scolar.index_html", scodoc_dept=g.scodoc_dept)[
|
||||||
: -len("/index_html")
|
: -len("/index_html")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def NotesURL():
|
def NotesURL():
|
||||||
@ -352,8 +375,8 @@ def EntreprisesURL():
|
|||||||
def AbsencesURL():
|
def AbsencesURL():
|
||||||
"""URL of Absences"""
|
"""URL of Absences"""
|
||||||
return url_for("absences.index_html", scodoc_dept=g.scodoc_dept)[
|
return url_for("absences.index_html", scodoc_dept=g.scodoc_dept)[
|
||||||
: -len("/index_html")
|
: -len("/index_html")
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def UsersURL():
|
def UsersURL():
|
||||||
@ -439,8 +462,8 @@ def suppress_accents(s):
|
|||||||
if isinstance(s, str):
|
if isinstance(s, str):
|
||||||
return (
|
return (
|
||||||
unicodedata.normalize("NFD", s)
|
unicodedata.normalize("NFD", s)
|
||||||
.encode("ascii", "ignore")
|
.encode("ascii", "ignore")
|
||||||
.decode(SCO_ENCODING)
|
.decode(SCO_ENCODING)
|
||||||
)
|
)
|
||||||
return s # may be int
|
return s # may be int
|
||||||
|
|
||||||
@ -504,6 +527,14 @@ def sendCSVFile(REQUEST, data, filename):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def flaskPDFResponse(data, filename, mime=PDF_MIMETYPE):
|
||||||
|
filename = make_filename(filename)
|
||||||
|
response = make_response(data)
|
||||||
|
response.headers['Content-Type'] = mime
|
||||||
|
response.headers['Content-Disposition'] = 'attachment; filename="%s"' % filename
|
||||||
|
return response
|
||||||
|
|
||||||
|
|
||||||
def sendPDFFile(REQUEST, data, filename):
|
def sendPDFFile(REQUEST, data, filename):
|
||||||
filename = (
|
filename = (
|
||||||
unescape_html(suppress_accents(filename)).replace("&", "").replace(" ", "_")
|
unescape_html(suppress_accents(filename)).replace("&", "").replace(" ", "_")
|
||||||
@ -641,7 +672,7 @@ def sem_decale_str(sem):
|
|||||||
if sem["semestre_id"] <= 0:
|
if sem["semestre_id"] <= 0:
|
||||||
return ""
|
return ""
|
||||||
if (sem["semestre_id"] % 2 and sem["mois_debut_ord"] <= 6) or (
|
if (sem["semestre_id"] % 2 and sem["mois_debut_ord"] <= 6) or (
|
||||||
not sem["semestre_id"] % 2 and sem["mois_debut_ord"] > 6
|
not sem["semestre_id"] % 2 and sem["mois_debut_ord"] > 6
|
||||||
):
|
):
|
||||||
return "D"
|
return "D"
|
||||||
else:
|
else:
|
||||||
@ -800,15 +831,15 @@ def return_text_if_published(val, REQUEST):
|
|||||||
|
|
||||||
|
|
||||||
def confirm_dialog(
|
def confirm_dialog(
|
||||||
message="<p>Confirmer ?</p>",
|
message="<p>Confirmer ?</p>",
|
||||||
OK="OK",
|
OK="OK",
|
||||||
Cancel="Annuler",
|
Cancel="Annuler",
|
||||||
dest_url="",
|
dest_url="",
|
||||||
cancel_url="",
|
cancel_url="",
|
||||||
target_variable="dialog_confirmed",
|
target_variable="dialog_confirmed",
|
||||||
parameters={},
|
parameters={},
|
||||||
add_headers=True, # complete page
|
add_headers=True, # complete page
|
||||||
helpmsg=None,
|
helpmsg=None,
|
||||||
):
|
):
|
||||||
from app.scodoc import html_sco_header
|
from app.scodoc import html_sco_header
|
||||||
|
|
||||||
@ -850,7 +881,7 @@ def confirm_dialog(
|
|||||||
H.append('<p class="help">' + helpmsg + "</p>")
|
H.append('<p class="help">' + helpmsg + "</p>")
|
||||||
if add_headers:
|
if add_headers:
|
||||||
return (
|
return (
|
||||||
html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
|
html_sco_header.sco_header() + "\n".join(H) + html_sco_header.sco_footer()
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return "\n".join(H)
|
return "\n".join(H)
|
||||||
|
Loading…
Reference in New Issue
Block a user