dev-python/documentex: On enlève la dépendance à libcurses

Modification des scripts pour utiliser la bibliothèque click et non plus
libcurses
ddenoncin 3 years ago
parent d9a622ae47
commit 2aad22376d

@ -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 os
import jinja2 import jinja2
"""
Nom du programme
"""
softname = 'documentex' 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" classe_appartenance = "PT"
promotion = "Fourier"
lycee_appartenance = "Lycée Langevin Wallon" lycee_appartenance = "Lycée Langevin Wallon"
institution = "Lycée" institution = "Lycée"
nom_institution = "Langevin Wallon" nom_institution = "Langevin Wallon"
lycee_adresse = "126 avenue Roger Salengro" lycee_adresse = "126 avenue Roger Salengro"
lycee_complement_adresse = "Champigny-sur-Marne, 94240" 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_lettre = "Dr. David Denoncin"
auteur_titre = "Professeur Agrégé" auteur_titre = "Professeur Agrégé"
auteur_adresse_mail = "math@denoncin.fr" 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 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 '*'), td : numérote-t-on les exercices ? ('' ou '*'),
fancyhead : doit-on afficher un header avec un titre court ? (True ou False), 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), 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 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( latex_jinja_env = jinja2.Environment(
block_start_string = '\BLOCK{', block_start_string="\BLOCK{",
block_end_string = '}', block_end_string="}",
variable_start_string = '\VAR{', variable_start_string="\VAR{",
variable_end_string = '}', variable_end_string="}",
comment_start_string = '\#{', comment_start_string="\#{",
comment_end_string = '}', comment_end_string="}",
line_statement_prefix = '%%', line_statement_prefix="%%",
line_comment_prefix = '%#', line_comment_prefix="%#",
trim_blocks = True, trim_blocks=True,
autoescape = False, autoescape=False,
loader = jinja2.FileSystemLoader('/') loader=jinja2.FileSystemLoader("/")
) )
jinja_template_dir = "templates" jinja_template_dir = "templates"
tex_file = 'example.tex' tex_file = "example.tex"
"""Paramétrage des templates jinja
"""
Pour mémoire : les variables à initialiser pour un compte rendu de colle
""" """
def initialiser_variables(): def initialiser_variables():
title = '' title = ''
semaine = '' semaine = ''
nom1= '' nom1 = ''
nom2 = '' nom2 = ''
nom3 = '' nom3 = ''
return [title,semaine,nom1,nom2,nom3] return [title, semaine, nom1, nom2, nom3]
"""Pour mémoire : les variables à initialiser pour un compte rendu de colle
"""
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)]

@ -2,40 +2,69 @@ import os
import sys import sys
from datetime import datetime from datetime import datetime
import glob import glob
from sys import argv
from jinja2 import Template from jinja2 import Template
import shutil import shutil
import libcurses
from . import constantes_document_latex as constantes from . import constantes_document_latex as constantes
from . import lib_nettoyage_argv as nettoyage
from . import lib_annee_scolaire as annee_scolaire from . import lib_annee_scolaire as annee_scolaire
import click
template_dir = constantes.jinja_template_dir 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é. def validate_dossier(ctx, param, value):
Exemple d'utilisation : if os.path.exists(value):
documentex 01_test td 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: Aucune. On crée dans le dossier $dossier tous les fichiers d'en-tête LaTeX nécessaire en
print("usage : numero_nom-fichier type_document") fonction du type de document à créer.
quit()
if nettoyage.arguments(argv[1]) is None: Exemple :
print("Le format du premier argument doit être de la forme numero_titre-dossier, numero ou titre") ---------
quit()
documentex 01_algebre-lineaire td
"""
# Initialisation des variables # Initialisation des variables
# contenu,tex_file,fancyhead,type_document,short_title,lycee,classe,title,auteur,semaine,liste_noms,td,ds_numero,annee # 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") 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 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] contenu,td,fancyhead,appartenance = constantes.dictionnaire_type_document[type_document]
short_title = type_document.upper()+' '+numero short_title = type_document.upper()+' '+numero
title,semaine,nom1,nom2,nom3 = constantes.initialiser_variables() # c'est moche... title,semaine,nom1,nom2,nom3 = constantes.initialiser_variables() # c'est moche...
auteur = constantes.auteur auteur = constantes.auteur
annee = annee_scolaire.annee_scolaire(True) annee = annee_scolaire.annee_scolaire()
institution = constantes.institution institution = constantes.institution
nom_institution = constantes.nom_institution nom_institution = constantes.nom_institution
lycee_adresse = constantes.lycee_adresse lycee_adresse = constantes.lycee_adresse
@ -43,7 +72,6 @@ def documentex():
auteur_lettre = constantes.auteur_lettre auteur_lettre = constantes.auteur_lettre
auteur_titre = constantes.auteur_titre auteur_titre = constantes.auteur_titre
auteur_adresse_mail = constantes.auteur_adresse_mail auteur_adresse_mail = constantes.auteur_adresse_mail
promotion = constantes.promotion
if appartenance: if appartenance:
classe = constantes.classe_appartenance classe = constantes.classe_appartenance
@ -55,33 +83,24 @@ def documentex():
# Initialisation des variables suivant le type d'écrit # Initialisation des variables suivant le type d'écrit
if contenu: if contenu:
title = libcurses.saisie_message_std('Quel titre long pour ce document ? ') title = click.prompt("Quel titre long pour ce document ? ")
short_title = libcurses.saisie_message_std('Quel titre court pour ce document ? ') short_title = click.prompt("Quel titre court pour ce document ? ")
if type_document == 'dm': if type_document == 'dm':
short_title += ' : à rendre pour le ' 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': if type_document == 'cr':
lycee = libcurses.saisie_message_std('Quel lycée ? ') lycee = click.prompt('Quel lycée ? ')
classe = libcurses.saisie_message_std('Quelle classe ? ') classe = click.prompt('Quelle classe ? ')
semaine = libcurses.saisie_message_std('Quelle semaine ? ') semaine = click.prompt('Quelle semaine ? ')
nom1 = libcurses.saisie_message_std('Premier candidat ? ') nom1 = click.prompt('Premier candidat ? ')
nom2 = libcurses.saisie_message_std('Deuxième candidat ? ') nom2 = click.prompt('Deuxième candidat ? ')
nom3 = libcurses.saisie_message_std('Troisième candidat ? ') nom3 = click.prompt('Troisième candidat ? ')
if type_document == 'ob': 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, liste_noms = [nom1,
nom2, nom2,
nom3, nom3,
@ -102,22 +121,22 @@ def documentex():
# Génération des fichiers de base # Génération des fichiers de base
for fichier in fichiers: for fichier in fichiers:
nom_fichier = os.path.basename(fichier) nom_fichier_a_copier = os.path.basename(fichier)
with open(os.path.join(tex_file_path,nom_fichier),'w') as outfile: 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)) 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 # Génération des fichiers Utils
for fichier in fichiers_utils: for fichier in fichiers_utils:
nom_fichier = os.path.basename(fichier) nom_fichier_a_copier = os.path.basename(fichier)
with open(os.path.join(os.path.join(tex_file_path,'Utils'),nom_fichier),'w') as outfile: 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)) 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 # 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 ] fichiers = [fichier for fichier in fichiers if 'Utils' not in fichier ]
if type_document in constantes.type_document_correction: if type_document in constantes.type_document_correction:
os.makedirs(os.path.join(argv[1],'Correction')) os.makedirs(os.path.join(nom_fichier,'Correction'))
shutil.copytree(os.path.join(argv[1],'Utils'),os.path.join(os.path.join(argv[1],'Correction'),'Utils')) shutil.copytree(os.path.join(nom_fichier,'Utils'),os.path.join(os.path.join(nom_fichier,'Correction'),'Utils'))
for fichier in fichiers: for fichier in fichiers:
shutil.copy(fichier,os.path.join(argv[1],'Correction')) shutil.copy(fichier,os.path.join(nom_fichier,'Correction'))

@ -1,29 +1,30 @@
import datetime import datetime
import libcurses as curses
from . import constantes_document_latex as constantes from . import constantes_document_latex as constantes
def annee_scolaire_admissible(annee_scolaire): def annee_scolaire_admissible(annee_scolaire: str) -> bool:
"""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 """
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: if len(annee_scolaire.split('-')) != 2:
return False return False
else: 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) return (int(annee_n) == (int(annee_n_plus_un)-1)) and (annee_n in constantes.annees_valables)
def annee_scolaire(sans_std = False): def annee_scolaire() -> 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 """
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('-')] year, month = [element for element in datetime.datetime.now().strftime("%Y-%m").split('-')]
if month in constantes.annee_scolaire_en_cours: 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: if month in constantes.annee_scolaire_plus_un:
return str(int(year)-1)+'-'+year return f"{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

@ -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)

@ -53,7 +53,7 @@
% paquet fancyhdr % paquet fancyhdr
\pagestyle{fancy} \pagestyle{fancy}
\BLOCK{ if fancyhead } \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 } \BLOCK{ else }
\fancyhead[L]{\VAR{ classe } - \VAR{ lycee } \VAR{ annee } } \fancyhead[L]{\VAR{ classe } - \VAR{ lycee } \VAR{ annee } }
\BLOCK{ endif } \BLOCK{ endif }

@ -6,20 +6,22 @@ setup(
version=version, version=version,
packages=find_packages(), packages=find_packages(),
include_package_data=True, include_package_data=True,
py_modules=['documentex'],
entry_points={ entry_points={
'console_scripts': [ 'console_scripts': [
'documentex = documentex.documentex:documentex', 'documentex = documentex.documentex:documentex',
] ]
}, },
install_requires=["jinja2","libcurses"], install_requires=[
"jinja2",
"Click",
],
author="David Denoncin", author = "David Denoncin",
author_email="math@denoncin.fr", author_email = "math@denoncin.fr",
url="math.denoncin.fr", url = "math.denoncin.fr",
description="Un utilitaire pour créer des arborescence de dossiers LaTeX", description = "Utilitaire pour créer des arborescence de dossiers LaTeX",
classifiers=[ classifiers=[
"Licence :: WTFPL" "Licence :: WTFPL"
] ]
) )

Loading…
Cancel
Save