diff --git a/app/scodoc/sco_archives.py b/app/scodoc/sco_archives.py index 8d91bbcf..5fb9aa56 100644 --- a/app/scodoc/sco_archives.py +++ b/app/scodoc/sco_archives.py @@ -49,7 +49,6 @@ """ import datetime import glob -import json import mimetypes import os import re @@ -58,29 +57,17 @@ import time import chardet -import flask -from flask import flash, g, request, url_for +from flask import g import app.scodoc.sco_utils as scu from config import Config -from app import log, ScoDocJSONEncoder -from app.but import jury_but_pv -from app.comp import res_sem -from app.comp.res_compat import NotesTableCompat -from app.models import FormSemestre -from app.scodoc.TrivialFormulator import TrivialFormulator -from app.scodoc.sco_exceptions import ScoException, ScoPermissionDenied -from app.scodoc import html_sco_header -from app.scodoc import sco_bulletins_pdf -from app.scodoc import sco_groups -from app.scodoc import sco_groups_view -from app.scodoc import sco_pv_forms -from app.scodoc import sco_pv_lettres_inviduelles -from app.scodoc import sco_pv_pdf +from app import log from app.scodoc.sco_exceptions import ScoValueError class BaseArchiver: + """Classe de base pour tous les archivers""" + def __init__(self, archive_type=""): self.archive_type = archive_type self.initialized = False @@ -306,400 +293,3 @@ class BaseArchiver: mime = "application/octet-stream" return scu.send_file(data, filename, mime=mime) - - -class SemsArchiver(BaseArchiver): - def __init__(self): - BaseArchiver.__init__(self, archive_type="") - - -PV_ARCHIVER = SemsArchiver() - - -# ---------------------------------------------------------------------------- - - -def do_formsemestre_archive( - formsemestre_id, - group_ids: list[int] = None, # si indiqué, ne prend que ces groupes - description="", - date_jury="", - signature=None, # pour lettres indiv - date_commission=None, - numero_arrete=None, - code_vdi=None, - show_title=False, - pv_title=None, - pv_title_session=None, - with_paragraph_nom=False, - anonymous=False, - bul_version="long", -): - """Make and store new archive for this formsemestre. - Store: - - tableau recap (xls), pv jury (xls et pdf), bulletins (xml et pdf), lettres individuelles (pdf) - """ - from app.scodoc.sco_recapcomplet import ( - gen_formsemestre_recapcomplet_excel, - gen_formsemestre_recapcomplet_html_table, - gen_formsemestre_recapcomplet_json, - ) - - if bul_version not in scu.BULLETINS_VERSIONS: - raise ScoValueError( - "do_formsemestre_archive: version de bulletin demandée invalide" - ) - formsemestre = FormSemestre.get_formsemestre(formsemestre_id) - res: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre) - sem_archive_id = formsemestre_id - archive_id = PV_ARCHIVER.create_obj_archive( - sem_archive_id, description, formsemestre.dept_id - ) - date = PV_ARCHIVER.get_archive_date(archive_id).strftime("%d/%m/%Y à %H:%M") - - if not group_ids: - # tous les inscrits du semestre - group_ids = [sco_groups.get_default_group(formsemestre_id)] - groups_infos = sco_groups_view.DisplayedGroupsInfos( - group_ids, formsemestre_id=formsemestre_id - ) - groups_filename = "-" + groups_infos.groups_filename - etudids = [m["etudid"] for m in groups_infos.members] - - # Tableau recap notes en XLS (pour tous les etudiants, n'utilise pas les groupes) - data, _ = gen_formsemestre_recapcomplet_excel(res, include_evaluations=True) - if data: - PV_ARCHIVER.store( - archive_id, - "Tableau_moyennes" + scu.XLSX_SUFFIX, - data, - dept_id=formsemestre.dept_id, - ) - # Tableau recap notes en HTML (pour tous les etudiants, n'utilise pas les groupes) - table_html, _, _ = gen_formsemestre_recapcomplet_html_table( - formsemestre, res, include_evaluations=True - ) - if table_html: - flash(f"Moyennes archivées le {date}", category="info") - data = "\n".join( - [ - html_sco_header.sco_header( - page_title=f"Moyennes archivées le {date}", - no_side_bar=True, - ), - f'

Valeurs archivées le {date}

', - """""", - table_html, - html_sco_header.sco_footer(), - ] - ) - PV_ARCHIVER.store( - archive_id, "Tableau_moyennes.html", data, dept_id=formsemestre.dept_id - ) - - # Bulletins en JSON - data = gen_formsemestre_recapcomplet_json(formsemestre_id, xml_with_decisions=True) - data_js = json.dumps(data, indent=1, cls=ScoDocJSONEncoder) - if data: - PV_ARCHIVER.store( - archive_id, "Bulletins.json", data_js, dept_id=formsemestre.dept_id - ) - # Décisions de jury, en XLS - if formsemestre.formation.is_apc(): - response = jury_but_pv.pvjury_page_but(formsemestre_id, fmt="xls") - data = response.get_data() - else: # formations classiques - data = sco_pv_forms.formsemestre_pvjury( - formsemestre_id, fmt="xls", publish=False - ) - if data: - PV_ARCHIVER.store( - archive_id, - "Decisions_Jury" + scu.XLSX_SUFFIX, - data, - dept_id=formsemestre.dept_id, - ) - # Classeur bulletins (PDF) - data, _ = sco_bulletins_pdf.get_formsemestre_bulletins_pdf( - formsemestre_id, version=bul_version - ) - if data: - PV_ARCHIVER.store( - archive_id, - "Bulletins.pdf", - data, - dept_id=formsemestre.dept_id, - ) - # Lettres individuelles (PDF): - data = sco_pv_lettres_inviduelles.pdf_lettres_individuelles( - formsemestre_id, - etudids=etudids, - date_jury=date_jury, - date_commission=date_commission, - signature=signature, - ) - if data: - PV_ARCHIVER.store( - archive_id, - f"CourriersDecisions{groups_filename}.pdf", - data, - dept_id=formsemestre.dept_id, - ) - - # PV de jury (PDF): - data = sco_pv_pdf.pvjury_pdf( - formsemestre, - etudids=etudids, - date_commission=date_commission, - date_jury=date_jury, - numero_arrete=numero_arrete, - code_vdi=code_vdi, - show_title=show_title, - pv_title_session=pv_title_session, - pv_title=pv_title, - with_paragraph_nom=with_paragraph_nom, - anonymous=anonymous, - ) - if data: - PV_ARCHIVER.store( - archive_id, - f"PV_Jury{groups_filename}.pdf", - data, - dept_id=formsemestre.dept_id, - ) - - -def formsemestre_archive(formsemestre_id, group_ids: list[int] = None): - """Make and store new archive for this formsemestre. - (all students or only selected groups) - """ - formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) - if not formsemestre.can_edit_pv(): - raise ScoPermissionDenied( - dest_url=url_for( - "notes.formsemestre_status", - scodoc_dept=g.scodoc_dept, - formsemestre_id=formsemestre_id, - ) - ) - if not group_ids: - # tous les inscrits du semestre - group_ids = [sco_groups.get_default_group(formsemestre_id)] - groups_infos = sco_groups_view.DisplayedGroupsInfos( - group_ids, formsemestre_id=formsemestre_id - ) - - H = [ - html_sco_header.html_sem_header( - "Archiver les PV et résultats du semestre", - javascripts=sco_groups_view.JAVASCRIPTS, - cssstyles=sco_groups_view.CSSSTYLES, - init_qtip=True, - ), - """

Cette page permet de générer et d'archiver tous -les documents résultant de ce semestre: PV de jury, lettres individuelles, -tableaux récapitulatifs.

Les documents archivés sont -enregistrés et non modifiables, on peut les retrouver ultérieurement. -

On peut archiver plusieurs versions des documents -(avant et après le jury par exemple). -

- """, - ] - F = [ - f"""

Note: les documents sont aussi affectés par les réglages sur la page - "Paramétrage" - (accessible à l'administrateur du département). -

""", - html_sco_header.sco_footer(), - ] - - descr = [ - ( - "description", - {"input_type": "textarea", "rows": 4, "cols": 77, "title": "Description"}, - ), - ("sep", {"input_type": "separator", "title": "Informations sur PV de jury"}), - ] - descr += sco_pv_forms.descrform_pvjury(formsemestre) - descr += [ - ( - "signature", - { - "input_type": "file", - "size": 30, - "explanation": "optionnel: image scannée de la signature pour les lettres individuelles", - }, - ), - ( - "bul_version", - { - "input_type": "menu", - "title": "Version des bulletins archivés", - "labels": [ - "Version courte", - "Version intermédiaire", - "Version complète", - ], - "allowed_values": scu.BULLETINS_VERSIONS.keys(), - "default": "long", - }, - ), - ] - menu_choix_groupe = ( - """
Groupes d'étudiants à lister: """ - + sco_groups_view.menu_groups_choice(groups_infos) - + """(pour les PV et lettres)
""" - ) - - tf = TrivialFormulator( - request.base_url, - scu.get_request_args(), - descr, - cancelbutton="Annuler", - submitlabel="Générer et archiver les documents", - name="tf", - formid="group_selector", - html_foot_markup=menu_choix_groupe, - ) - if tf[0] == 0: - return "\n".join(H) + "\n" + tf[1] + "\n".join(F) - elif tf[0] == -1: - msg = "Opération annulée" - else: - # submit - sf = tf[2]["signature"] - signature = sf.read() # image of signature - if tf[2]["anonymous"]: - tf[2]["anonymous"] = True - else: - tf[2]["anonymous"] = False - do_formsemestre_archive( - formsemestre_id, - group_ids=group_ids, - description=tf[2]["description"], - date_jury=tf[2]["date_jury"], - date_commission=tf[2]["date_commission"], - signature=signature, - numero_arrete=tf[2]["numero_arrete"], - code_vdi=tf[2]["code_vdi"], - pv_title_session=tf[2]["pv_title_session"], - pv_title=tf[2]["pv_title"], - show_title=tf[2]["show_title"], - with_paragraph_nom=tf[2]["with_paragraph_nom"], - anonymous=tf[2]["anonymous"], - bul_version=tf[2]["bul_version"], - ) - msg = "Nouvelle archive créée" - - # submitted or cancelled: - flash(msg) - return flask.redirect( - url_for( - "notes.formsemestre_list_archives", - scodoc_dept=g.scodoc_dept, - formsemestre_id=formsemestre_id, - ) - ) - - -def formsemestre_list_archives(formsemestre_id): - """Page listing archives""" - formsemestre = FormSemestre.get_formsemestre(formsemestre_id) - sem_archive_id = formsemestre_id - L = [] - for archive_id in PV_ARCHIVER.list_obj_archives( - sem_archive_id, dept_id=formsemestre.dept_id - ): - a = { - "archive_id": archive_id, - "description": PV_ARCHIVER.get_archive_description( - archive_id, dept_id=formsemestre.dept_id - ), - "date": PV_ARCHIVER.get_archive_date(archive_id), - "content": PV_ARCHIVER.list_archive( - archive_id, dept_id=formsemestre.dept_id - ), - } - L.append(a) - - H = [html_sco_header.html_sem_header("Archive des PV et résultats ")] - if not L: - H.append("

aucune archive enregistrée

") - else: - H.append("") - - return "\n".join(H) + html_sco_header.sco_footer() - - -def formsemestre_get_archived_file(formsemestre_id, archive_name, filename): - """Send file to client.""" - formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) - sem_archive_id = formsemestre.id - return PV_ARCHIVER.get_archived_file( - sem_archive_id, archive_name, filename, dept_id=formsemestre.dept_id - ) - - -def formsemestre_delete_archive(formsemestre_id, archive_name, dialog_confirmed=False): - """Delete an archive""" - formsemestre: FormSemestre = FormSemestre.query.get_or_404(formsemestre_id) - if not formsemestre.can_edit_pv(): - raise ScoPermissionDenied( - dest_url=url_for( - "notes.formsemestre_status", - scodoc_dept=g.scodoc_dept, - formsemestre_id=formsemestre_id, - ) - ) - sem_archive_id = formsemestre_id - archive_id = PV_ARCHIVER.get_id_from_name( - sem_archive_id, archive_name, dept_id=formsemestre.dept_id - ) - - dest_url = url_for( - "notes.formsemestre_list_archives", - scodoc_dept=g.scodoc_dept, - formsemestre_id=formsemestre_id, - ) - - if not dialog_confirmed: - return scu.confirm_dialog( - f"""

Confirmer la suppression de l'archive du { - PV_ARCHIVER.get_archive_date(archive_id).strftime("%d/%m/%Y %H:%M") - } ?

-

La suppression sera définitive.

- """, - dest_url="", - cancel_url=dest_url, - parameters={ - "formsemestre_id": formsemestre_id, - "archive_name": archive_name, - }, - ) - - PV_ARCHIVER.delete_archive(archive_id, dept_id=formsemestre.dept_id) - flash("Archive supprimée") - return flask.redirect(dest_url)