From 2aad22376de4c701bea4621e6a046d2bf840992d Mon Sep 17 00:00:00 2001 From: ddenoncin Date: Sat, 12 Nov 2022 20:46:21 +0100 Subject: [PATCH] =?UTF-8?q?dev-python/documentex:=20On=20enl=C3=A8ve=20la?= =?UTF-8?q?=20d=C3=A9pendance=20=C3=A0=20libcurses?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Modification des scripts pour utiliser la bibliothèque click et non plus libcurses --- documentex/constantes_document_latex.py | 134 +++++++++++------- documentex/documentex.py | 119 +++++++++------- documentex/lib_annee_scolaire.py | 33 ++--- documentex/lib_nettoyage_argv.py | 39 ----- .../templates/Utils/02_config_paquets.tex | 2 +- setup.py | 16 ++- 6 files changed, 176 insertions(+), 167 deletions(-) delete mode 100644 documentex/lib_nettoyage_argv.py diff --git a/documentex/constantes_document_latex.py b/documentex/constantes_document_latex.py index 0d63562..0827146 100644 --- a/documentex/constantes_document_latex.py +++ b/documentex/constantes_document_latex.py @@ -1,99 +1,125 @@ -"""Ce fichier initialise les variables utilisées ailleurs dans le programme et en permet la personnalisation simple -""" +""" +Ce fichier initialise les variables utilisées ailleurs dans le programme +et en permet la personnalisation simple +""" + import os import jinja2 + +""" +Nom du programme +""" softname = 'documentex' -"""Nom du programme + """ -version = '1.7' -"""Version du programme +Version du programme """ +version = '2.0' -debug = False -"""Debug variable """ +Variable de debuggage +""" +debug = False +""" +Constantes customisant l'en-tête des fichiers LaTeX et remplies automatiquement +""" classe_appartenance = "PT" -promotion = "Fourier" lycee_appartenance = "Lycée Langevin Wallon" institution = "Lycée" nom_institution = "Langevin Wallon" lycee_adresse = "126 avenue Roger Salengro" lycee_complement_adresse = "Champigny-sur-Marne, 94240" -auteur = "D. Denoncin" #est mise d'office sur tout type de document +auteur = "D. Denoncin" # est mise d'office sur tout type de document auteur_lettre = "Dr. David Denoncin" auteur_titre = "Professeur Agrégé" auteur_adresse_mail = "math@denoncin.fr" -"""Constantes customisant l'en-tête des fichiers LaTeX et remplies automatiquement -""" - -dictionnaire_type_document = {'ds' : [False,'',True,True], - 'td' : [False,'',True,True], - 'dm' : [False,'*',True,True], - 'pb' : [False,'*',True,True], - 'te' : [False,'*',True,True], - 'kh' : [False,'',False,True], - 'cours' : [True,'*',True,True], - 'in' : [False,'*',True,True], - 'cr' : [False,'*',False,True], - 'ob' : [False,'*',False,True], - 'doc' : [False,'',False,False], - 'let' : [False,'',False,True] - } + """Dictionnaire paramétrant les types de documents de la façon suivante : - dictionnaire_type_document[type_document] = [contenu : affiche-t-on un contenu ? (True ou False), + dictionnaire_type_document[type_document] = [contenu : affiche-t-on un contenu ? (True ou False), td : numérote-t-on les exercices ? ('' ou '*'), fancyhead : doit-on afficher un header avec un titre court ? (True ou False), appartenance : doit-on afficher l'appartenance classe/lycée ? (True ou False), ] """ +dictionnaire_type_document = {'ds': [False, '', True, True], + 'td': [False, '', True, True], + 'dm': [False, '*', True, True], + 'pb': [False, '*', True, True], + 'te': [False, '*', True, True], + 'kh': [False, '', False, True], + 'cours': [True, '*', True, True], + 'in': [False, '*', True, True], + 'cr': [False, '*', False, True], + 'ob': [False, '*', False, True], + 'doc': [False, '', False, False], + 'let': [False, '', False, True], # Lettre de motivation + } + -type_document_correction = ['ds','dm','pb'] """ Types de documents pour lesquels il faut créer un sous-dossier pour la correction """ +type_document_correction = ['ds', 'dm', 'pb'] -dictionnaire_numero_ds = {'01' : 'Première', '02' : 'Deuxième','03' : 'Troisième', '04' : 'Quatrième', '05' : 'Cinquième', '06' : 'Sixième','07' : 'Septième','08' : 'Huitième','09' : 'Neuvième', '10' : 'Dixième' } -"""Dictionnaire paramétrant les abréviations pour les numéros de DS (limité à 10 DS) """ +Dictionnaire paramétrant les abréviations pour les numéros de DS (limité à 10 DS) +""" +dictionnaire_numero_ds = {'01': 'Première', + '02': 'Deuxième', + '03': 'Troisième', + '04': 'Quatrième', + '05': 'Cinquième', + '06': 'Sixième', + '07': 'Septième', + '08': 'Huitième', + '09': 'Neuvième', + '10': 'Dixième', + } +""" +Paramétrage des templates jinja +""" latex_jinja_env = jinja2.Environment( - block_start_string = '\BLOCK{', - block_end_string = '}', - variable_start_string = '\VAR{', - variable_end_string = '}', - comment_start_string = '\#{', - comment_end_string = '}', - line_statement_prefix = '%%', - line_comment_prefix = '%#', - trim_blocks = True, - autoescape = False, - loader = jinja2.FileSystemLoader('/') + block_start_string="\BLOCK{", + block_end_string="}", + variable_start_string="\VAR{", + variable_end_string="}", + comment_start_string="\#{", + comment_end_string="}", + line_statement_prefix="%%", + line_comment_prefix="%#", + trim_blocks=True, + autoescape=False, + loader=jinja2.FileSystemLoader("/") ) -jinja_template_dir = "templates" -tex_file = 'example.tex' -"""Paramétrage des templates jinja +jinja_template_dir = "templates" +tex_file = "example.tex" + + +""" +Pour mémoire : les variables à initialiser pour un compte rendu de colle """ def initialiser_variables(): title = '' semaine = '' - nom1= '' + nom1 = '' nom2 = '' nom3 = '' - return [title,semaine,nom1,nom2,nom3] -"""Pour mémoire : les variables à initialiser pour un compte rendu de colle -""" + return [title, semaine, nom1, nom2, nom3] -numeros_admissibles = [ '00', '01','02','03','04','05','06','07','08','09' ] + [str(i) for i in range(10,200)] -"""Numéro de fichiers admissibles (est-ce vraiment utile ??) """ +Numéro de fichiers admissibles (est-ce vraiment utile ??) +""" +numeros_admissibles = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09'] + [str(i) for i in range(10, 200)] -annee_scolaire = ['09','10','11','12','01','02','03','04','05'] #mois d'une année scolaire donnée -annee_scolaire_plus_un = ['01','02','03','04','05'] -annee_scolaire_en_cours = ['09','10','11','12'] -annees_valables = [str(i) for i in range(2018,2070)] -"""Ces variables permettent de déterminer quelle est l'année scolaire en cours pour lequel le fichier est généré, expire en 2070 (?) """ +Ces variables permettent de déterminer quelle est l'année scolaire en cours pour lequel le fichier est généré, expire en 2070 (?) +""" +annee_scolaire = ['09', '10', '11', '12', '01', '02', '03', '04', '05'] # mois d'une année scolaire donnée +annee_scolaire_plus_un = ['01', '02', '03', '04', '05'] +annee_scolaire_en_cours = ['09', '10', '11', '12'] +annees_valables = [str(i) for i in range(2018, 2070)] diff --git a/documentex/documentex.py b/documentex/documentex.py index 0e87502..2ed19f6 100644 --- a/documentex/documentex.py +++ b/documentex/documentex.py @@ -2,40 +2,69 @@ import os import sys from datetime import datetime import glob -from sys import argv from jinja2 import Template import shutil -import libcurses from . import constantes_document_latex as constantes -from . import lib_nettoyage_argv as nettoyage from . import lib_annee_scolaire as annee_scolaire +import click template_dir = constantes.jinja_template_dir -def documentex(): - """Script permettant de créer un dossier nommé numero_titre-dossier, numero ou titre dans lequel figurent les squelettes des fichiers latex correspondant au type de document demandé. - Exemple d'utilisation : - documentex 01_test td + +def validate_dossier(ctx, param, value): + if os.path.exists(value): + raise click.BadParameter("Le dossier existe déjà !") + + try: + if len(value.split("_")) == 2: + numero, nom = value.split("_") + int(numero) + return numero, f"{numero}_{nom}" + if len(value.split("_")) == 1: + try: + int(value) + return value, value + except: + return "", value + else: + raise click.BadParameter("Le dossion doit être au format numéro_nom ou nom") + + except ValueError: + raise click.BadParameter("Le dossier doit être au format nom ou numéro_nom") + +@click.command() +@click.argument("dossier", type=click.UNPROCESSED, callback=validate_dossier) +@click.argument("type_document", type=click.Choice([key for key in constantes.dictionnaire_type_document])) +def documentex(dossier: str, type_document: str): """ + Entrée: + ------- + + dossier : chaîne de caractère spécifiant le nom du dossier à créer + type_document : chaîne de caractère spécifiant le type de document à créer + + Sortie : + -------- - if len(argv) != 3: - print("usage : numero_nom-fichier type_document") - quit() - if nettoyage.arguments(argv[1]) is None: - print("Le format du premier argument doit être de la forme numero_titre-dossier, numero ou titre") - quit() + Aucune. On crée dans le dossier $dossier tous les fichiers d'en-tête LaTeX nécessaire en + fonction du type de document à créer. + + Exemple : + --------- + + documentex 01_algebre-lineaire td + """ # Initialisation des variables # contenu,tex_file,fancyhead,type_document,short_title,lycee,classe,title,auteur,semaine,liste_noms,td,ds_numero,annee date = datetime.now().strftime("%Y-%m-%d") - nom_fichier = argv[1] - numero,titre = nettoyage.arguments(nom_fichier) + + numero, nom_fichier = dossier tex_file = constantes.tex_file # nom du fichier dans lequel on écrit du LaTeX - type_document = argv[2] contenu,td,fancyhead,appartenance = constantes.dictionnaire_type_document[type_document] short_title = type_document.upper()+' '+numero title,semaine,nom1,nom2,nom3 = constantes.initialiser_variables() # c'est moche... auteur = constantes.auteur - annee = annee_scolaire.annee_scolaire(True) + annee = annee_scolaire.annee_scolaire() institution = constantes.institution nom_institution = constantes.nom_institution lycee_adresse = constantes.lycee_adresse @@ -43,7 +72,6 @@ def documentex(): auteur_lettre = constantes.auteur_lettre auteur_titre = constantes.auteur_titre auteur_adresse_mail = constantes.auteur_adresse_mail - promotion = constantes.promotion if appartenance: classe = constantes.classe_appartenance @@ -55,33 +83,24 @@ def documentex(): # Initialisation des variables suivant le type d'écrit if contenu: - title = libcurses.saisie_message_std('Quel titre long pour ce document ? ') - short_title = libcurses.saisie_message_std('Quel titre court pour ce document ? ') + title = click.prompt("Quel titre long pour ce document ? ") + short_title = click.prompt("Quel titre court pour ce document ? ") if type_document == 'dm': short_title += ' : à rendre pour le ' - short_title += libcurses.saisie_message_std('à rendre pour le : ? ') + short_title += click.prompt('à rendre pour le : ? ') if type_document == 'cr': - lycee = libcurses.saisie_message_std('Quel lycée ? ') - classe = libcurses.saisie_message_std('Quelle classe ? ') - semaine = libcurses.saisie_message_std('Quelle semaine ? ') - nom1 = libcurses.saisie_message_std('Premier candidat ? ') - nom2 = libcurses.saisie_message_std('Deuxième candidat ? ') - nom3 = libcurses.saisie_message_std('Troisième candidat ? ') + lycee = click.prompt('Quel lycée ? ') + classe = click.prompt('Quelle classe ? ') + semaine = click.prompt('Quelle semaine ? ') + nom1 = click.prompt('Premier candidat ? ') + nom2 = click.prompt('Deuxième candidat ? ') + nom3 = click.prompt('Troisième candidat ? ') if type_document == 'ob': - nom1 = libcurses.saisie_message_std('Nom du candidat ? ') + nom1 = click.prompt('Nom du candidat ? ') + + os.mkdir(nom_fichier) + os.mkdir(os.path.join(nom_fichier, "Utils")) - try: - os.makedirs(argv[1]) - except: - continuer = libcurses.saisie_message_std(' Le dossier existe déjà ! Continuer ? (o/n) ') - if continuer != 'o': - quit() - else: - pass #le dossier existe déjà, on va ré-écrire les fichiers qui s'y trouvent - try: - os.makedirs(os.path.join(argv[1],'Utils')) - except: - pass #le dossier existe déjà, on va ré-écrire les fichiers qui s'y trouvent liste_noms = [nom1, nom2, nom3, @@ -102,22 +121,22 @@ def documentex(): # Génération des fichiers de base for fichier in fichiers: - nom_fichier = os.path.basename(fichier) - with open(os.path.join(tex_file_path,nom_fichier),'w') as outfile: + nom_fichier_a_copier = os.path.basename(fichier) + with open(os.path.join(tex_file_path,nom_fichier_a_copier),'w') as outfile: template = constantes.latex_jinja_env.get_template(os.path.abspath(fichier)) - outfile.write(template.render(date=date,contenu=contenu,tex_file=tex_file,fancyhead=fancyhead,type_ecrit=type_document,short_title=short_title,lycee=lycee,classe=classe,title=title,auteur=auteur,semaine=semaine,liste_noms=liste_noms,td=td,ds_numero=ds_numero,annee=annee,institution=institution,nom_institution=nom_institution,lycee_adresse=lycee_adresse,lycee_complement_adresse=lycee_complement_adresse,auteur_lettre=auteur_lettre,auteur_titre=auteur_titre,auteur_adresse_mail=auteur_adresse_mail,promotion=promotion)) + outfile.write(template.render(date=date,contenu=contenu,tex_file=tex_file,fancyhead=fancyhead,type_ecrit=type_document,short_title=short_title,lycee=lycee,classe=classe,title=title,auteur=auteur,semaine=semaine,liste_noms=liste_noms,td=td,ds_numero=ds_numero,annee=annee,institution=institution,nom_institution=nom_institution,lycee_adresse=lycee_adresse,lycee_complement_adresse=lycee_complement_adresse,auteur_lettre=auteur_lettre,auteur_titre=auteur_titre,auteur_adresse_mail=auteur_adresse_mail)) # Génération des fichiers Utils for fichier in fichiers_utils: - nom_fichier = os.path.basename(fichier) - with open(os.path.join(os.path.join(tex_file_path,'Utils'),nom_fichier),'w') as outfile: + nom_fichier_a_copier = os.path.basename(fichier) + with open(os.path.join(os.path.join(tex_file_path,'Utils'),nom_fichier_a_copier),'w') as outfile: template = constantes.latex_jinja_env.get_template(os.path.abspath(fichier)) - outfile.write(template.render(date=date,contenu=contenu,tex_file=tex_file,fancyhead=fancyhead,type_ecrit=type_document,short_title=short_title,lycee=lycee,classe=classe,title=title,auteur=auteur,semaine=semaine,liste_noms=liste_noms,td=td,ds_numero=ds_numero,annee=annee,institution=institution,nom_institution=nom_institution,lycee_adresse=lycee_adresse,lycee_complement_adresse=lycee_complement_adresse,auteur_lettre=auteur_lettre,auteur_titre=auteur_titre,auteur_adresse_mail=auteur_adresse_mail,promotion=promotion)) + outfile.write(template.render(date=date,contenu=contenu,tex_file=tex_file,fancyhead=fancyhead,type_ecrit=type_document,short_title=short_title,lycee=lycee,classe=classe,title=title,auteur=auteur,semaine=semaine,liste_noms=liste_noms,td=td,ds_numero=ds_numero,annee=annee,institution=institution,nom_institution=nom_institution,lycee_adresse=lycee_adresse,lycee_complement_adresse=lycee_complement_adresse,auteur_lettre=auteur_lettre,auteur_titre=auteur_titre,auteur_adresse_mail=auteur_adresse_mail)) # Création du dossier de correction avec les fichiers pré-remplis - fichiers = glob.glob(os.path.join(argv[1],'*')) + fichiers = glob.glob(os.path.join(nom_fichier,'*')) fichiers = [fichier for fichier in fichiers if 'Utils' not in fichier ] if type_document in constantes.type_document_correction: - os.makedirs(os.path.join(argv[1],'Correction')) - shutil.copytree(os.path.join(argv[1],'Utils'),os.path.join(os.path.join(argv[1],'Correction'),'Utils')) + os.makedirs(os.path.join(nom_fichier,'Correction')) + shutil.copytree(os.path.join(nom_fichier,'Utils'),os.path.join(os.path.join(nom_fichier,'Correction'),'Utils')) for fichier in fichiers: - shutil.copy(fichier,os.path.join(argv[1],'Correction')) + shutil.copy(fichier,os.path.join(nom_fichier,'Correction')) diff --git a/documentex/lib_annee_scolaire.py b/documentex/lib_annee_scolaire.py index f21ba9d..615e1f1 100644 --- a/documentex/lib_annee_scolaire.py +++ b/documentex/lib_annee_scolaire.py @@ -1,29 +1,30 @@ import datetime -import libcurses as curses from . import constantes_document_latex as constantes -def annee_scolaire_admissible(annee_scolaire): - """Revoie True si la chaîne de caractère annee_scolaire est au format aaaa-aaaa+1 avec aaaa une année admissible, et False sinon +def annee_scolaire_admissible(annee_scolaire: str) -> bool: + """ + Entrée : + -------- + annee_scolaire : chaîne de caractère + + Sortie : + -------- + bool : booléen décrivant si la chaîne de caractère est au format aaaa-aaaa+1 avec aaaa une année admissible, et False sinon """ if len(annee_scolaire.split('-')) != 2: return False else: - annee_n,annee_n_plus_un = annee_scolaire.split('-') + annee_n, annee_n_plus_un = annee_scolaire.split('-') return (int(annee_n) == (int(annee_n_plus_un)-1)) and (annee_n in constantes.annees_valables) -def annee_scolaire(sans_std = False): - """Retourne l'année scolaire en cours, si l'argument est True alors on renvoie toujours l'année scolaire en cours sauf à partir de juin où on renvoie l'année suivante +def annee_scolaire() -> str: + """ + Sortie : + -------- + str : Retourne l'année scolaire en cours, si l'argument est True alors on renvoie toujours l'année scolaire en cours sauf à partir de juin où on renvoie l'année suivante """ year, month = [element for element in datetime.datetime.now().strftime("%Y-%m").split('-')] if month in constantes.annee_scolaire_en_cours: - return year+'-'+str(int(year)+1) + return f"{year}-{int(year)+1}" if month in constantes.annee_scolaire_plus_un: - return str(int(year)-1)+'-'+year - if sans_std: - return year+'-'+str(int(year)+1) - while True: - annee_scolaire = curses.saisie_message_std("Quelle est l'année scolaire en cours ? ") - if not(annee_scolaire_admissible(annee_scolaire)): - curses.afficher_message_std("L'année saisie doit être au format aaaa-aaaa+1 et aaaa doit être inférieure à 2070 !") - else: - return annee_scolaire + return f"{int(year)-1}-{year}" diff --git a/documentex/lib_nettoyage_argv.py b/documentex/lib_nettoyage_argv.py deleted file mode 100644 index fbd245c..0000000 --- a/documentex/lib_nettoyage_argv.py +++ /dev/null @@ -1,39 +0,0 @@ -from . import constantes_document_latex as constantes - -""" Ces fonction permettent d'analyser l'argument donné en ligne de commande. Celui-ci doit être de la forme numero ou bien numero_titre ou bien titre, et numero doit être dans l'intervalle des numéros admissibles (voir constantes_document_latex) -""" - -def format(argv): - """ Formattage de l'argument - """ - arguments = argv.split('_') - if len(arguments) == 1: - arguments.append('') # garantit qu'il y a toujours au moins deux arguments, le second éventuellement vide - if constantes.debug: - print("fonction format") - print(f"La variable arguments est {arguments}") - return arguments - -def bon_format(argv): - """Booléen déterminant si la chaîne de caractère argv est un argument admissible pour le script document latex - """ - arguments = format(argv) - if len(arguments) != 2: # c'est impossible ? - return False - numero,titre = arguments - if constantes.debug: - print("fonction bon_format") - print(f"Les variables numero,titre sont {numero} et {titre}") - try: - int(numero) #si le numéro est bien un numéro - return numero in constantes.numeros_admissibles - except: - return True #si non, c'est un titre - else: - return [False] # Qu'est-ce que c'est que ce délire ?? - -def arguments(argv): - """Renvoie la liste des arguments s'ils sont admissibles, et None autrement - """ - if bon_format(argv): - return format(argv) diff --git a/documentex/templates/Utils/02_config_paquets.tex b/documentex/templates/Utils/02_config_paquets.tex index e38a870..4746f4d 100644 --- a/documentex/templates/Utils/02_config_paquets.tex +++ b/documentex/templates/Utils/02_config_paquets.tex @@ -53,7 +53,7 @@ % paquet fancyhdr \pagestyle{fancy} \BLOCK{ if fancyhead } -\fancyhead[L]{\VAR{ classe } - \VAR{ short_title } - \VAR{ lycee } \VAR{ annee } } %promotion \VAR{ promotion } +\fancyhead[L]{\VAR{ classe } - \VAR{ short_title } - \VAR{ lycee } \VAR{ annee } } \BLOCK{ else } \fancyhead[L]{\VAR{ classe } - \VAR{ lycee } \VAR{ annee } } \BLOCK{ endif } diff --git a/setup.py b/setup.py index 8e9007a..0f0b3cb 100644 --- a/setup.py +++ b/setup.py @@ -6,20 +6,22 @@ setup( version=version, packages=find_packages(), include_package_data=True, + py_modules=['documentex'], entry_points={ 'console_scripts': [ 'documentex = documentex.documentex:documentex', ] }, - install_requires=["jinja2","libcurses"], + install_requires=[ + "jinja2", + "Click", + ], - author="David Denoncin", - author_email="math@denoncin.fr", - url="math.denoncin.fr", - description="Un utilitaire pour créer des arborescence de dossiers LaTeX", + author = "David Denoncin", + author_email = "math@denoncin.fr", + url = "math.denoncin.fr", + description = "Utilitaire pour créer des arborescence de dossiers LaTeX", classifiers=[ "Licence :: WTFPL" ] ) - -