various fixes. Bulletins et saisie décision ok.

This commit is contained in:
Emmanuel Viennet 2021-08-15 15:01:13 +02:00
parent 3dc94775a1
commit f0c96e3e68
10 changed files with 62 additions and 56 deletions

View File

@ -31,17 +31,13 @@ Module main: essais divers
Emmanuel Viennet, 2021 Emmanuel Viennet, 2021
""" """
import io
import pprint import pprint
from pprint import pprint as pp from pprint import pprint as pp
import functools import functools
import six.moves._thread # essai import six.moves._thread # essai
from zipfile import ZipFile from zipfile import ZipFile
try:
from io import StringIO ## for Python 3
except ImportError:
from cStringIO import StringIO ## for Python 2
import flask import flask
from flask import request, render_template, redirect from flask import request, render_template, redirect
from flask_login import login_required from flask_login import login_required
@ -180,7 +176,7 @@ def getzip():
# REQUEST.RESPONSE.setHeader( # REQUEST.RESPONSE.setHeader(
# "content-disposition", 'attachement; filename="monzip.zip"' # "content-disposition", 'attachement; filename="monzip.zip"'
# ) # )
zipdata = StringIO() zipdata = io.StringIO()
zipfile = ZipFile(zipdata, "w") zipfile = ZipFile(zipdata, "w")
zipfile.writestr("fichier1", "un contenu") zipfile.writestr("fichier1", "un contenu")
zipfile.writestr("fichier2", "deux contenus") zipfile.writestr("fichier2", "deux contenus")

View File

@ -187,7 +187,7 @@ def bonus_iutr(notes_sport, coefs, infos=None):
# le bonus est le minimum entre 0.35 et la somme de toutes les bonifs # le bonus est le minimum entre 0.35 et la somme de toutes les bonifs
bonus = min(0.35, sum([x for x in notes_sport])) bonus = min(0.35, sum([x for x in notes_sport]))
for ue_id in infos["moy_ues"]: for ue_id in infos["moy_ues"]:
# open('/tmp/log','a').write( ue_id + infos['moy_ues'] + '\n\n' ) # open('/tmp/log','a').write( str(ue_id) + infos['moy_ues'] + '\n\n' )
ue_status = infos["moy_ues"][ue_id] ue_status = infos["moy_ues"][ue_id]
if ue_status["sum_coefs"] > 0: if ue_status["sum_coefs"] > 0:
# modifie moyenne UE dans semestre courant # modifie moyenne UE dans semestre courant

View File

@ -1,17 +1,13 @@
"""Simple image resize using PIL""" """Simple image resize using PIL"""
import io
from PIL import Image as PILImage from PIL import Image as PILImage
try:
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
def ImageScale(img_file, maxx, maxy): def ImageScale(img_file, maxx, maxy):
im = PILImage.open(img_file) im = PILImage.open(img_file)
im.thumbnail((maxx, maxy), PILImage.ANTIALIAS) im.thumbnail((maxx, maxy), PILImage.ANTIALIAS)
out_file_str = StringIO() out_file_str = io.BytesIO()
im.save(out_file_str, im.format) im.save(out_file_str, im.format)
out_file_str.seek(0) out_file_str.seek(0)
tmp = out_file_str.read() tmp = out_file_str.read()
@ -25,7 +21,7 @@ def ImageScaleH(img_file, W=None, H=90):
# keep aspect # keep aspect
W = int((im.size[0] * H) / float(im.size[1])) W = int((im.size[0] * H) / float(im.size[1]))
im.thumbnail((W, H), PILImage.ANTIALIAS) im.thumbnail((W, H), PILImage.ANTIALIAS)
out_file_str = StringIO() out_file_str = io.BytesIO()
im.save(out_file_str, im.format) im.save(out_file_str, im.format)
out_file_str.seek(0) out_file_str.seek(0)
tmp = out_file_str.read() tmp = out_file_str.read()

View File

@ -1289,7 +1289,18 @@ class NotesTable(object):
cnx = ndb.GetDBConnexion() cnx = ndb.GetDBConnexion()
cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor)
cursor.execute( cursor.execute(
"select n.* from notes_notes n, notes_evaluation e, notes_moduleimpl m, notes_moduleimpl_inscription i where n.etudid = %(etudid)s and n.value = %(code_attente)s and n.evaluation_id=e.evaluation_id and e.moduleimpl_id=m.moduleimpl_id and m.formsemestre_id=%(formsemestre_id)s and e.coefficient != 0 and m.moduleimpl_id=i.moduleimpl_id and i.etudid=%(etudid)s", """SELECT n.*
FROM notes_notes n, notes_evaluation e, notes_moduleimpl m,
notes_moduleimpl_inscription i
WHERE n.etudid = %(etudid)s
and n.value = %(code_attente)s
and n.evaluation_id = e.id
and e.moduleimpl_id = m.id
and m.formsemestre_id = %(formsemestre_id)s
and e.coefficient != 0
and m.id = i.moduleimpl_id
and i.etudid=%(etudid)s
""",
{ {
"formsemestre_id": self.formsemestre_id, "formsemestre_id": self.formsemestre_id,
"etudid": etudid, "etudid": etudid,

View File

@ -81,15 +81,12 @@ XXX A vérifier:
""" """
import collections import collections
import datetime
import io
import os
import re import re
import time import time
import datetime
import os
try:
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
from zipfile import ZipFile from zipfile import ZipFile
import pprint import pprint
from functools import reduce from functools import reduce
@ -203,7 +200,7 @@ def fix_data_encoding(
class StringIOFileLineWrapper(object): class StringIOFileLineWrapper(object):
def __init__(self, data): def __init__(self, data):
self.f = StringIO(data) self.f = io.StringIO(data)
self.lineno = 0 self.lineno = 0
def close(self): def close(self):
@ -1223,7 +1220,7 @@ def export_csv_to_apogee(
e.associate_sco(context, apo_data) e.associate_sco(context, apo_data)
# Ré-écrit le fichier Apogée # Ré-écrit le fichier Apogée
f = StringIO() f = io.StringIO()
apo_data.write_header(f) apo_data.write_header(f)
apo_data.write_etuds(f) apo_data.write_etuds(f)
@ -1245,7 +1242,7 @@ def export_csv_to_apogee(
# Create ZIP # Create ZIP
if not dest_zip: if not dest_zip:
data = StringIO() data = io.StringIO()
dest_zip = ZipFile(data, "w") dest_zip = ZipFile(data, "w")
my_zip = True my_zip = True
else: else:
@ -1269,7 +1266,7 @@ def export_csv_to_apogee(
nar_filename = basename + "-nar" + scu.XLSX_SUFFIX nar_filename = basename + "-nar" + scu.XLSX_SUFFIX
cr_filename = basename + "-decisions" + scu.XLSX_SUFFIX cr_filename = basename + "-decisions" + scu.XLSX_SUFFIX
logf = StringIO() logf = io.StringIO()
logf.write("export_to_apogee du %s\n\n" % time.ctime()) logf.write("export_to_apogee du %s\n\n" % time.ctime())
logf.write("Semestres ScoDoc sources:\n") logf.write("Semestres ScoDoc sources:\n")
for sem in apo_data.sems_etape: for sem in apo_data.sems_etape:

View File

@ -50,15 +50,12 @@ Pour définir un nouveau type de bulletin:
Chaque semestre peut si nécessaire utiliser un type de bulletin différent. Chaque semestre peut si nécessaire utiliser un type de bulletin différent.
""" """
import io
import os
import re
import time import time
import traceback import traceback
import re
import os
try:
from io import StringIO # for Python 3
except ImportError:
from cStringIO import StringIO # for Python 2
from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate from reportlab.platypus.doctemplate import PageTemplate, BaseDocTemplate
from app.scodoc import VERSION from app.scodoc import VERSION
@ -92,7 +89,7 @@ def pdfassemblebulletins(
sco_preferences.get_preference("bottom_margin", formsemestre_id), sco_preferences.get_preference("bottom_margin", formsemestre_id),
) )
report = StringIO.StringIO() # in-memory document, no disk file report = io.BytesIO() # in-memory document, no disk file
document = BaseDocTemplate(report) document = BaseDocTemplate(report)
document.addPageTemplates( document.addPageTemplates(
sco_pdf.ScolarsPageTemplate( sco_pdf.ScolarsPageTemplate(
@ -149,16 +146,21 @@ def process_field(
image_dir = scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id() + "/" image_dir = scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id() + "/"
if not os.path.exists(image_dir): if not os.path.exists(image_dir):
image_dir = scu.SCODOC_LOGOS_DIR + "/" # use global logos image_dir = scu.SCODOC_LOGOS_DIR + "/" # use global logos
if not os.path.exists(image_dir):
log(f"Warning: missing global logo directory ({image_dir})")
image_dir = None
text = re.sub( text = re.sub(
r"<(\s*)logo(.*?)src\s*=\s*(.*?)>", r"<\1logo\2\3>", text r"<(\s*)logo(.*?)src\s*=\s*(.*?)>", r"<\1logo\2\3>", text
) # remove forbidden src attribute ) # remove forbidden src attribute
text = re.sub( if image_dir is not None:
r'<\s*logo(.*?)name\s*=\s*"(\w*?)"(.*?)/?>', text = re.sub(
r'<img\1src="%s/logo_\2.jpg"\3/>' % image_dir, r'<\s*logo(.*?)name\s*=\s*"(\w*?)"(.*?)/?>',
text, r'<img\1src="%s/logo_\2.jpg"\3/>' % image_dir,
) text,
# nota: le match sur \w*? donne le nom du logo et interdit les .. et autres )
# tentatives d'acceder à d'autres fichiers ! # nota: le match sur \w*? donne le nom du logo et interdit les .. et autres
# tentatives d'acceder à d'autres fichiers !
# log('field: %s' % (text)) # log('field: %s' % (text))
return sco_pdf.makeParas(text, style, suppress_empty=suppress_empty_pars) return sco_pdf.makeParas(text, style, suppress_empty=suppress_empty_pars)
@ -170,7 +172,7 @@ def get_formsemestre_bulletins_pdf(
"document pdf et filename" "document pdf et filename"
from app.scodoc import sco_bulletins from app.scodoc import sco_bulletins
cached = sco_cache.SemBulletinsPDFCache.get(formsemestre_id + "_" + version) cached = sco_cache.SemBulletinsPDFCache.get(str(formsemestre_id) + "_" + version)
if cached: if cached:
return cached[1], cached[0] return cached[1], cached[0]
fragments = [] fragments = []
@ -219,7 +221,7 @@ def get_formsemestre_bulletins_pdf(
filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "") filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "")
# fill cache # fill cache
sco_cache.SemBulletinsPDFCache.set( sco_cache.SemBulletinsPDFCache.set(
formsemestre_id + "_" + version, (filename, pdfdoc) str(formsemestre_id) + "_" + version, (filename, pdfdoc)
) )
return pdfdoc, filename return pdfdoc, filename

View File

@ -86,15 +86,18 @@ class DecisionSem(object):
self.devenir = devenir self.devenir = devenir
self.assiduite = assiduite self.assiduite = assiduite
self.rule_id = rule_id self.rule_id = rule_id
# code unique utilise pour la gestion du formulaire # code unique (string) utilise pour la gestion du formulaire
self.codechoice = str( self.codechoice = (
hash( "C" # prefix pour éviter que Flask le considère comme int
( + str(
code_etat, hash(
new_code_prev, (
formsemestre_id_utilise_pour_compenser, code_etat,
devenir, new_code_prev,
assiduite, formsemestre_id_utilise_pour_compenser,
devenir,
assiduite,
)
) )
) )
) )

View File

@ -126,6 +126,7 @@ def makeParas(txt, style, suppress_empty=False):
paras = r paras = r
return [Paragraph(SU(s), style) for s in paras] return [Paragraph(SU(s), style) for s in paras]
except Exception as e: except Exception as e:
raise
detail = " " + str(e) detail = " " + str(e)
log(traceback.format_exc()) log(traceback.format_exc())
log("Invalid pdf para format: %s" % txt) log("Invalid pdf para format: %s" % txt)

View File

@ -201,8 +201,8 @@ class CourrierIndividuelTemplate(PageTemplate):
self.logo_header = None self.logo_header = None
# Search logos in dept specific dir, then in global scu.CONFIG dir # Search logos in dept specific dir, then in global scu.CONFIG dir
for image_dir in ( for image_dir in (
scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id() + "/", scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id(),
scu.SCODOC_LOGOS_DIR + "/", # global logos scu.SCODOC_LOGOS_DIR, # global logos
): ):
for suffix in scu.LOGOS_IMAGES_ALLOWED_TYPES: for suffix in scu.LOGOS_IMAGES_ALLOWED_TYPES:
if template_name == "PVJuryTemplate": if template_name == "PVJuryTemplate":
@ -222,6 +222,7 @@ class CourrierIndividuelTemplate(PageTemplate):
fn = image_dir + "/logo_header" + "." + suffix fn = image_dir + "/logo_header" + "." + suffix
if not self.logo_header and os.path.exists(fn): if not self.logo_header and os.path.exists(fn):
log("XXX XXX : logo_header " + fn)
self.logo_header = Image( self.logo_header = Image(
fn, fn,
height=LOGO_HEADER_HEIGHT, height=LOGO_HEADER_HEIGHT,

View File

@ -64,10 +64,10 @@ ATTRIBUTES_MAPPING = {
} }
def setup_log(dept_id: str): def setup_log(dept_acronym: str):
"""log to console (stderr) and /opt/scodoc-data/log/migration78.log""" """log to console (stderr) and /opt/scodoc-data/log/migration78.log"""
log_formatter = logging.Formatter( log_formatter = logging.Formatter(
"%(asctime)s %(levelname)s (" + dept_id + ") %(message)s" "%(asctime)s %(levelname)s (" + dept_acronym + ") %(message)s"
) )
# Log to file: # Log to file:
logger = logging.getLogger() logger = logging.getLogger()
@ -117,8 +117,7 @@ def import_scodoc7_dept(dept_id: str, dept_db_uri=None):
logging.info(f"All table imported: clearing app caches...") logging.info(f"All table imported: clearing app caches...")
clear_scodoc_cache() clear_scodoc_cache()
logging.info(f"Done.") logging.info(f"Done.")
logging.warning(f"Un redémarrage du serveur postgresql est conseillé") logging.warning(f"Un redémarrage du serveur postgresql est conseillé.")
logging.warning(f"systemctl restart postgresql"
def get_class_for_table(table): def get_class_for_table(table):