From f0c96e3e685e0c340348ef1b5311fe994ab7ab8e Mon Sep 17 00:00:00 2001 From: Emmanuel Viennet Date: Sun, 15 Aug 2021 15:01:13 +0200 Subject: [PATCH] =?UTF-8?q?various=20fixes.=20Bulletins=20et=20saisie=20d?= =?UTF-8?q?=C3=A9cision=20ok.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main/routes.py | 8 ++------ app/scodoc/bonus_sport.py | 2 +- app/scodoc/imageresize.py | 10 +++------- app/scodoc/notes_table.py | 13 ++++++++++++- app/scodoc/sco_apogee_csv.py | 17 +++++++---------- app/scodoc/sco_bulletins_pdf.py | 34 +++++++++++++++++---------------- app/scodoc/sco_parcours_dut.py | 21 +++++++++++--------- app/scodoc/sco_pdf.py | 1 + app/scodoc/sco_pvpdf.py | 5 +++-- tools/import_scodoc7_dept.py | 7 +++---- 10 files changed, 62 insertions(+), 56 deletions(-) diff --git a/app/main/routes.py b/app/main/routes.py index 89264112cc..8323ef2da1 100644 --- a/app/main/routes.py +++ b/app/main/routes.py @@ -31,17 +31,13 @@ Module main: essais divers Emmanuel Viennet, 2021 """ +import io import pprint from pprint import pprint as pp import functools import six.moves._thread # essai from zipfile import ZipFile -try: - from io import StringIO ## for Python 3 -except ImportError: - from cStringIO import StringIO ## for Python 2 - import flask from flask import request, render_template, redirect from flask_login import login_required @@ -180,7 +176,7 @@ def getzip(): # REQUEST.RESPONSE.setHeader( # "content-disposition", 'attachement; filename="monzip.zip"' # ) - zipdata = StringIO() + zipdata = io.StringIO() zipfile = ZipFile(zipdata, "w") zipfile.writestr("fichier1", "un contenu") zipfile.writestr("fichier2", "deux contenus") diff --git a/app/scodoc/bonus_sport.py b/app/scodoc/bonus_sport.py index 625d471938..4a3a83e61a 100644 --- a/app/scodoc/bonus_sport.py +++ b/app/scodoc/bonus_sport.py @@ -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 bonus = min(0.35, sum([x for x in notes_sport])) 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] if ue_status["sum_coefs"] > 0: # modifie moyenne UE dans semestre courant diff --git a/app/scodoc/imageresize.py b/app/scodoc/imageresize.py index f33dd624ac..5a5af483b4 100644 --- a/app/scodoc/imageresize.py +++ b/app/scodoc/imageresize.py @@ -1,17 +1,13 @@ """Simple image resize using PIL""" +import io 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): im = PILImage.open(img_file) im.thumbnail((maxx, maxy), PILImage.ANTIALIAS) - out_file_str = StringIO() + out_file_str = io.BytesIO() im.save(out_file_str, im.format) out_file_str.seek(0) tmp = out_file_str.read() @@ -25,7 +21,7 @@ def ImageScaleH(img_file, W=None, H=90): # keep aspect W = int((im.size[0] * H) / float(im.size[1])) im.thumbnail((W, H), PILImage.ANTIALIAS) - out_file_str = StringIO() + out_file_str = io.BytesIO() im.save(out_file_str, im.format) out_file_str.seek(0) tmp = out_file_str.read() diff --git a/app/scodoc/notes_table.py b/app/scodoc/notes_table.py index f96dfec332..daf87666ac 100644 --- a/app/scodoc/notes_table.py +++ b/app/scodoc/notes_table.py @@ -1289,7 +1289,18 @@ class NotesTable(object): cnx = ndb.GetDBConnexion() cursor = cnx.cursor(cursor_factory=ndb.ScoDocCursor) 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, "etudid": etudid, diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py index 3b905502fb..4af15204a8 100644 --- a/app/scodoc/sco_apogee_csv.py +++ b/app/scodoc/sco_apogee_csv.py @@ -81,15 +81,12 @@ XXX A vérifier: """ import collections +import datetime +import io +import os import re 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 import pprint from functools import reduce @@ -203,7 +200,7 @@ def fix_data_encoding( class StringIOFileLineWrapper(object): def __init__(self, data): - self.f = StringIO(data) + self.f = io.StringIO(data) self.lineno = 0 def close(self): @@ -1223,7 +1220,7 @@ def export_csv_to_apogee( e.associate_sco(context, apo_data) # Ré-écrit le fichier Apogée - f = StringIO() + f = io.StringIO() apo_data.write_header(f) apo_data.write_etuds(f) @@ -1245,7 +1242,7 @@ def export_csv_to_apogee( # Create ZIP if not dest_zip: - data = StringIO() + data = io.StringIO() dest_zip = ZipFile(data, "w") my_zip = True else: @@ -1269,7 +1266,7 @@ def export_csv_to_apogee( nar_filename = basename + "-nar" + 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("Semestres ScoDoc sources:\n") for sem in apo_data.sems_etape: diff --git a/app/scodoc/sco_bulletins_pdf.py b/app/scodoc/sco_bulletins_pdf.py index 07e1a88cef..0bf79273f8 100644 --- a/app/scodoc/sco_bulletins_pdf.py +++ b/app/scodoc/sco_bulletins_pdf.py @@ -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. """ +import io +import os +import re import time 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 app.scodoc import VERSION @@ -92,7 +89,7 @@ def pdfassemblebulletins( 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.addPageTemplates( sco_pdf.ScolarsPageTemplate( @@ -149,16 +146,21 @@ def process_field( image_dir = scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id() + "/" if not os.path.exists(image_dir): 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( r"<(\s*)logo(.*?)src\s*=\s*(.*?)>", r"<\1logo\2\3>", text ) # remove forbidden src attribute - text = re.sub( - r'<\s*logo(.*?)name\s*=\s*"(\w*?)"(.*?)/?>', - r'' % image_dir, - text, - ) - # nota: le match sur \w*? donne le nom du logo et interdit les .. et autres - # tentatives d'acceder à d'autres fichiers ! + if image_dir is not None: + text = re.sub( + r'<\s*logo(.*?)name\s*=\s*"(\w*?)"(.*?)/?>', + r'' % image_dir, + text, + ) + # 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)) return sco_pdf.makeParas(text, style, suppress_empty=suppress_empty_pars) @@ -170,7 +172,7 @@ def get_formsemestre_bulletins_pdf( "document pdf et filename" 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: return cached[1], cached[0] fragments = [] @@ -219,7 +221,7 @@ def get_formsemestre_bulletins_pdf( filename = scu.unescape_html(filename).replace(" ", "_").replace("&", "") # fill cache sco_cache.SemBulletinsPDFCache.set( - formsemestre_id + "_" + version, (filename, pdfdoc) + str(formsemestre_id) + "_" + version, (filename, pdfdoc) ) return pdfdoc, filename diff --git a/app/scodoc/sco_parcours_dut.py b/app/scodoc/sco_parcours_dut.py index 09d2ed66e8..c9ee7a4ae3 100644 --- a/app/scodoc/sco_parcours_dut.py +++ b/app/scodoc/sco_parcours_dut.py @@ -86,15 +86,18 @@ class DecisionSem(object): self.devenir = devenir self.assiduite = assiduite self.rule_id = rule_id - # code unique utilise pour la gestion du formulaire - self.codechoice = str( - hash( - ( - code_etat, - new_code_prev, - formsemestre_id_utilise_pour_compenser, - devenir, - assiduite, + # code unique (string) utilise pour la gestion du formulaire + self.codechoice = ( + "C" # prefix pour éviter que Flask le considère comme int + + str( + hash( + ( + code_etat, + new_code_prev, + formsemestre_id_utilise_pour_compenser, + devenir, + assiduite, + ) ) ) ) diff --git a/app/scodoc/sco_pdf.py b/app/scodoc/sco_pdf.py index 2721f91921..f90fed8cf8 100755 --- a/app/scodoc/sco_pdf.py +++ b/app/scodoc/sco_pdf.py @@ -126,6 +126,7 @@ def makeParas(txt, style, suppress_empty=False): paras = r return [Paragraph(SU(s), style) for s in paras] except Exception as e: + raise detail = " " + str(e) log(traceback.format_exc()) log("Invalid pdf para format: %s" % txt) diff --git a/app/scodoc/sco_pvpdf.py b/app/scodoc/sco_pvpdf.py index 7947a2a311..9351c578ff 100644 --- a/app/scodoc/sco_pvpdf.py +++ b/app/scodoc/sco_pvpdf.py @@ -201,8 +201,8 @@ class CourrierIndividuelTemplate(PageTemplate): self.logo_header = None # Search logos in dept specific dir, then in global scu.CONFIG dir for image_dir in ( - scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id() + "/", - scu.SCODOC_LOGOS_DIR + "/", # global logos + scu.SCODOC_LOGOS_DIR + "/logos_" + scu.get_dept_id(), + scu.SCODOC_LOGOS_DIR, # global logos ): for suffix in scu.LOGOS_IMAGES_ALLOWED_TYPES: if template_name == "PVJuryTemplate": @@ -222,6 +222,7 @@ class CourrierIndividuelTemplate(PageTemplate): fn = image_dir + "/logo_header" + "." + suffix if not self.logo_header and os.path.exists(fn): + log("XXX XXX : logo_header " + fn) self.logo_header = Image( fn, height=LOGO_HEADER_HEIGHT, diff --git a/tools/import_scodoc7_dept.py b/tools/import_scodoc7_dept.py index 96c4083768..feeaa217ad 100644 --- a/tools/import_scodoc7_dept.py +++ b/tools/import_scodoc7_dept.py @@ -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_formatter = logging.Formatter( - "%(asctime)s %(levelname)s (" + dept_id + ") %(message)s" + "%(asctime)s %(levelname)s (" + dept_acronym + ") %(message)s" ) # Log to file: 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...") clear_scodoc_cache() logging.info(f"Done.") - logging.warning(f"Un redémarrage du serveur postgresql est conseillé") - logging.warning(f"systemctl restart postgresql" + logging.warning(f"Un redémarrage du serveur postgresql est conseillé.") def get_class_for_table(table):