forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -31,7 +31,7 @@ from flask import render_template, url_for
|
||||
from flask import g, request
|
||||
|
||||
from app.but.bulletin_but import BulletinBUT
|
||||
from app.but import cursus_but, validations_view
|
||||
from app.but import bulletin_but_court_pdf, cursus_but, validations_view
|
||||
from app.decorators import (
|
||||
scodoc,
|
||||
permission_required,
|
||||
@ -40,14 +40,18 @@ from app.models import FormSemestre, FormSemestreInscription, Identite
|
||||
from app.scodoc.sco_exceptions import ScoNoReferentielCompetences
|
||||
from app.scodoc.sco_logos import find_logo
|
||||
from app.scodoc.sco_permissions import Permission
|
||||
import app.scodoc.sco_utils as scu
|
||||
from app.views import notes_bp as bp
|
||||
from app.views import ScoData
|
||||
|
||||
|
||||
@bp.route("/bulletin_but/<int:formsemestre_id>/<int:etudid>")
|
||||
@bp.route(
|
||||
"/bulletin_but/<int:formsemestre_id>/<int:etudid>/pdf", defaults={"fmt": "pdf"}
|
||||
)
|
||||
@scodoc
|
||||
@permission_required(Permission.ScoView)
|
||||
def bulletin_but(formsemestre_id: int, etudid: int = None):
|
||||
def bulletin_but(formsemestre_id: int, etudid: int = None, fmt="html"):
|
||||
"""Page HTML affichant le bulletin BUT simplifié"""
|
||||
etud: Identite = Identite.query.get_or_404(etudid)
|
||||
formsemestre: FormSemestre = (
|
||||
@ -70,19 +74,27 @@ def bulletin_but(formsemestre_id: int, etudid: int = None):
|
||||
|
||||
logo = find_logo(logoname="header", dept_id=g.scodoc_dept_id)
|
||||
|
||||
args = {
|
||||
"bul": bul,
|
||||
"cursus": cursus,
|
||||
"decision_ues": decision_ues,
|
||||
"ects_total": ects_total,
|
||||
"etud": etud,
|
||||
"formsemestre": formsemestre,
|
||||
"logo": logo,
|
||||
"title": f"Bul. {etud.nom_disp()} BUT (court)",
|
||||
"ue_validation_by_niveau": ue_validation_by_niveau,
|
||||
}
|
||||
|
||||
if fmt == "pdf":
|
||||
filename = scu.bul_filename(formsemestre, etud, prefix="bul-but")
|
||||
bul_pdf = bulletin_but_court_pdf.make_bulletin_but_court_pdf(**args)
|
||||
return scu.sendPDFFile(bul_pdf, filename)
|
||||
|
||||
return render_template(
|
||||
"but/bulletin_court_page.j2",
|
||||
bul=bul,
|
||||
bulletins_sem=bulletins_sem,
|
||||
cursus=cursus,
|
||||
datetime=datetime,
|
||||
decision_ues=decision_ues,
|
||||
ects_total=ects_total,
|
||||
etud=etud,
|
||||
formsemestre=formsemestre,
|
||||
logo=logo,
|
||||
sco=ScoData(formsemestre=formsemestre, etud=etud),
|
||||
time=time,
|
||||
title=f"Bul. {etud.nom_disp()} BUT (court)",
|
||||
ue_validation_by_niveau=ue_validation_by_niveau,
|
||||
**args,
|
||||
)
|
||||
|
122
app/but/bulletin_but_court_pdf.py
Normal file
122
app/but/bulletin_but_court_pdf.py
Normal file
@ -0,0 +1,122 @@
|
||||
##############################################################################
|
||||
# ScoDoc
|
||||
# Copyright (c) 1999 - 2023 Emmanuel Viennet. All rights reserved.
|
||||
# See LICENSE
|
||||
##############################################################################
|
||||
|
||||
"""Génération bulletin BUT PDF synthétique en une page
|
||||
|
||||
On génère du PDF avec reportLab en utilisant les classes
|
||||
ScoDoc BulletinGenerator et GenTable.
|
||||
|
||||
"""
|
||||
from flask_login import current_user
|
||||
|
||||
from reportlab.lib.colors import blue
|
||||
from reportlab.lib.units import cm, mm
|
||||
from reportlab.platypus import Paragraph, Spacer
|
||||
|
||||
from app.but import cursus_but
|
||||
from app.models import FormSemestre, Identite, ScolarFormSemestreValidation
|
||||
|
||||
from app.scodoc.sco_bulletins_standard import BulletinGeneratorStandard
|
||||
from app.scodoc.sco_logos import Logo
|
||||
from app.scodoc import gen_tables, sco_pdf, sco_preferences
|
||||
from app.scodoc.sco_pdf import PDFLOCK
|
||||
|
||||
|
||||
def make_bulletin_but_court_pdf(
|
||||
bul: dict = None,
|
||||
cursus: cursus_but.EtudCursusBUT = None,
|
||||
decision_ues: dict = None,
|
||||
ects_total: float = 0.0,
|
||||
etud: Identite = None,
|
||||
formsemestre: FormSemestre = None,
|
||||
logo: Logo = None,
|
||||
title: str = "",
|
||||
ue_validation_by_niveau: dict[tuple[int, str], ScolarFormSemestreValidation] = None,
|
||||
) -> bytes:
|
||||
# A priori ce verrou n'est plus nécessaire avec Flask (multi-process)
|
||||
# mais...
|
||||
try:
|
||||
PDFLOCK.acquire()
|
||||
bul_generator = BulletinGeneratorBUTCourt(**locals())
|
||||
bul_pdf = bul_generator.generate(format="pdf")
|
||||
finally:
|
||||
PDFLOCK.release()
|
||||
return bul_pdf
|
||||
|
||||
|
||||
class BulletinGeneratorBUTCourt(BulletinGeneratorStandard):
|
||||
"""Ce générateur de bulletin BUT court est assez différent des autres bulletins.
|
||||
Ne génére que du PDF.
|
||||
Il reprend la mise en page et certains éléments (pied de page, signature).
|
||||
"""
|
||||
|
||||
# spécialisation du BulletinGeneratorStandard, ne pas présenter à l'utilisateur:
|
||||
list_in_menu = False
|
||||
scale_table_in_page = True # pas de mise à l'échelle pleine page auto
|
||||
multi_pages = False # une page par bulletin
|
||||
small_fontsize = "8"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
bul: dict = None,
|
||||
cursus: cursus_but.EtudCursusBUT = None,
|
||||
decision_ues: dict = None,
|
||||
ects_total: float = 0.0,
|
||||
etud: Identite = None,
|
||||
formsemestre: FormSemestre = None,
|
||||
logo: Logo = None,
|
||||
title: str = "",
|
||||
ue_validation_by_niveau: dict[
|
||||
tuple[int, str], ScolarFormSemestreValidation
|
||||
] = None,
|
||||
):
|
||||
# données pour anciens codes bulletins... à moderniser
|
||||
infos = {
|
||||
"etud": etud.to_dict_bul(),
|
||||
"filigranne": None,
|
||||
"formsemestre_id": formsemestre.id,
|
||||
"nbabs": 0,
|
||||
"nbabsjust": 0,
|
||||
}
|
||||
super().__init__(infos, authuser=current_user)
|
||||
self.bul = bul
|
||||
self.cursus = cursus
|
||||
self.decision_ues = decision_ues
|
||||
self.ects_total = ects_total
|
||||
self.etud = etud
|
||||
self.formsemestre = formsemestre
|
||||
self.logo = logo
|
||||
self.title = title
|
||||
self.ue_validation_by_niveau = ue_validation_by_niveau
|
||||
|
||||
def bul_table(self, fmt=None):
|
||||
"""Génère la table centrale du bulletin de notes
|
||||
Renvoie: une liste d'objets PLATYPUS (eg instance de Table).
|
||||
L'argument fmt est ici ignoré (toujours en PDF)
|
||||
"""
|
||||
ue_table = self.build_ue_table()
|
||||
|
||||
return ue_table.gen(format="pdf")
|
||||
|
||||
def build_ue_table(self) -> gen_tables.GenTable:
|
||||
"""Table avec les résultats d'UE du semestre courant"""
|
||||
columns_ids = ("titre", "UE1", "UE2")
|
||||
rows = [
|
||||
{"titre": "ligne 1", "UE1": "12.", "UE2": "13"},
|
||||
{"titre": "ligne 2", "UE1": "14.", "UE2": "15"},
|
||||
]
|
||||
pdf_style = [
|
||||
("VALIGN", (0, 0), (-1, -1), "TOP"),
|
||||
("BOX", (0, 0), (-1, -1), 0.4, blue), # ajoute cadre extérieur bleu
|
||||
]
|
||||
col_widths = {"titre": 3 * cm, "UE1": 1 * cm, "UE2": 1 * cm}
|
||||
return gen_tables.GenTable(
|
||||
rows=rows,
|
||||
columns_ids=columns_ids,
|
||||
pdf_table_style=pdf_style,
|
||||
pdf_col_widths=[col_widths[k] for k in columns_ids],
|
||||
preferences=sco_preferences.SemPreferences(self.formsemestre.id),
|
||||
)
|
@ -887,10 +887,10 @@ def bul_filename_old(sem: dict, etud: dict, format):
|
||||
return filename
|
||||
|
||||
|
||||
def bul_filename(formsemestre, etud):
|
||||
def bul_filename(formsemestre, etud, prefix="bul"):
|
||||
"""Build a filename for this bulletin (without suffix)"""
|
||||
dt = time.strftime("%Y-%m-%d")
|
||||
filename = f"bul-{formsemestre.titre_num()}-{dt}-{etud.nom}"
|
||||
filename = f"{prefix}-{formsemestre.titre_num()}-{dt}-{etud.nom}"
|
||||
filename = make_filename(filename)
|
||||
return filename
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user