"""
Ce script permet de construire les menus et certains éléments
variables (date,...) de ma (Élie Gouzien) page web.
La philosophie est de stoker les parties des fichiers html dans différents
fichiers et les assembler lors d'une compilation. Pour chaque fichier htmlc,
on charge le prototype trouvé dans le dossier parent le plus proche.
Puis on insère l'entête spécifique, les menus (trouvés dans le plus proche
dossier parent) et le contenu principal. Ensuite on inclut des fichiers
arbitraires supplémentaires puis on remplace les variables spéciales.
Extensions de fichiers réservées :
htmlc : contenu des pages (sans entetes ni menus, ...) ;
htmle : entête spécifique a la page htmlc de même nom ;
htmls : fichiers spéciaux : prototype.htmls est le prototype du site,
menu1.htmls contient le menu principal, menu2.htmls contient un menu
secondaire. Tout autre fichier htmls sert à être inséré à la balise
correspondante sous forme <!--&nom_fichier&--> (insère nom_fichier.htmls)
Les fichiers .html et .htaccess sont traités en remplaçant simplement les
balises.
Balise pseudo-html :
Toute balise de type <!--€ €--> sont réservées. Il y a :
<!--€entete€--> : le fichier htmle de même nom que le fichier htmlc traite
(et dans le même répertoire y est inséré).
<!--€menu1€--> : le fichier menu1.htmls trouve en remontant les répertoires
est insère. Il est modifie pour ajouter class="actuel" au lien menant vers
le fichier traite.
<!--€menu1€--> : idem menu1 mais pour le menu2
<!--€contenu€--> : insère le contenu du fichier actuellement traite.
Ces balises sont en principe utilisées uniquement dans prototype.htmls. Il y a
aussi :
<!--€date€--> : insère la date
<!--€racine€--> : insère la racine du site vue par le serveur http (en fait la
varible python RACINE et rien d'autre).
Toute balise de type <!--&nom&--> se voit remplacée par le contenu du fichier
nom.htmls trouve en premier dans la remontée des répertoires.
Attention à ce que le fichier existe (aucune protection).
Attention au contenu des fichiers menu, le script n'est pas très fin et sera
vite perdu.
Numéro de version : 3.0
Crée le dimanche 8 décembre 2013
Mis à jour en mars 2019
@auteur: Élie Gouzien
Export vers html : dans vim ":TOhtml" puis séparation à la main du contenu et
des entêtes. Remplacement de "body" par "#contenu" et agrandissement de
"max-width".
"""
import os
import shutil
import datetime
import locale
RACINE = "/~gouzien"
ORIGINAL = os.path.abspath("conception_semiauto")
COPIE = os.path.abspath("site_semiauto")
def tester_fichiers_necessaires():
"""Vérifie la présence des fichiers essentiels, ne fait rien s'ils y sont.
Test la présence de menu1.htmls, menu2.htmls et prototype.htmls
dans RACINE. Déclenche des erreurs en cas d'absence.
A priori le site est non vide donc ils doivent exister !
Cela prévient les recherches vaines de ces fichiers.
L'utilité de cette fonction dépend des choix faits sur
plus_proches_parents. Elle ne peut pas faire de mal.
"""
os.chdir(ORIGINAL)
if not os.access("prototype.htmls", os.R_OK):
raise IOError("Erreur il manque le fichier prototype.htmls")
if not os.access("menu1.htmls", os.R_OK):
raise IOError("Erreur il manque le fichier menu1.htmls")
if not os.access("menu2.htmls", os.R_OK):
raise IOError("Erreur il manque le fichier menu2.htmls")
def plus_proche_parent(chemin_absolu, fichier_cherche):
"""Trouve le fichier_cherche dans le plus proche parent de l'emplacement.
Les arguments et la valeur renvoyée sont de type str.
Renvoie le chemin complet de fichier_cherche solution du problème.
"""
fichier_cherche = os.path.basename(fichier_cherche)
if not os.path.isdir(chemin_absolu):
chemin_absolu = os.path.dirname(chemin_absolu)
os.chdir(chemin_absolu)
while True:
if os.access(fichier_cherche, os.R_OK):
return os.path.abspath(fichier_cherche)
os.chdir("..")
def etendre_chemin_dans_menu(menu, chemin):
"""Étend la variable <!--€racine€--> et repère la position de la page.
menu : chaine contenant tout le menu avec RACINE non étendue
chemin : chemin du fichier relatif (a la racine du site) dans lequel on
insère le menu
sortie : chaine contenant le menu directement utilisable.
La fonction remplace <!--€racine€--> par RACINE et ajoute class="actuel"
dans l'entre de menu permettant d'accéder a la page en question.
"""
position = menu.find("<!--€racine€-->/") + 16
while position != 15:
addresse = menu[position:position + menu[position:].find("/\"")]
if os.path.normpath(chemin).startswith(os.path.normpath(addresse)):
menu = menu.replace("href=\"<!--€racine€-->",
"class=\"actuel\" href=\"<!--€racine€-->", 1)
menu = menu.replace("<!--€racine€-->", RACINE, 1)
position = menu.find("<!--€racine€-->") + 16
return menu
tester_fichiers_necessaires()
if os.access(COPIE, os.F_OK):
shutil.rmtree(COPIE)
for emplacement, dossiers, fichiers in os.walk(ORIGINAL):
emplacement = os.path.relpath(emplacement, ORIGINAL)
for dossier in dossiers:
os.makedirs(os.path.join(COPIE, emplacement, dossier))
for fichier in fichiers:
nom_nu, extension = os.path.splitext(fichier)
if extension in [".htmls", ".htmle"] or fichier[-1] in ['~', '#']:
continue
elif extension not in [".htmlc", ".html"] and fichier != ".htaccess":
shutil.copyfile(os.path.join(ORIGINAL, emplacement, fichier),
os.path.join(COPIE, emplacement, fichier))
continue
elif extension == ".htmlc":
nom_sortie = nom_nu + '.html'
with open(plus_proche_parent(os.path.join(ORIGINAL, emplacement),
"prototype.htmls")) as source:
texte_html = source.read()
with open(os.path.join(ORIGINAL, emplacement,
nom_nu + ".htmle")) as source:
contenu = source.read()
texte_html = texte_html.replace("<!--€entete€-->", contenu)
with open(os.path.join(ORIGINAL, emplacement, fichier)) as source:
contenu = source.read()
texte_html = texte_html.replace("<!--€contenu€-->", contenu)
elif extension == ".html" or fichier == ".htaccess":
nom_sortie = fichier
with open(os.path.join(ORIGINAL, emplacement, fichier)) as source:
texte_html = source.read()
else:
raise RuntimeError(
"Le fichier {}/{} n'est rien de connu.".format(emplacement,
fichier))
with open(plus_proche_parent(os.path.join(ORIGINAL, emplacement),
"menu1.htmls"), 'r') as source:
contenu = source.read()
contenu = etendre_chemin_dans_menu(contenu, emplacement)
texte_html = texte_html.replace("<!--€menu1€-->", contenu)
with open(plus_proche_parent(os.path.join(ORIGINAL, emplacement),
"menu2.htmls")) as source:
contenu = source.read()
contenu = etendre_chemin_dans_menu(contenu, emplacement)
texte_html = texte_html.replace("<!--€menu2€-->", contenu)
while -1 not in [texte_html.find("<!--&"), texte_html.find("&-->")]:
nom_a_charger = texte_html[texte_html.find("<!--&") + 5:
texte_html.find("&-->")]
with open(plus_proche_parent(os.path.join(ORIGINAL, emplacement),
nom_a_charger + ".htmls")) as source:
contenu = source.read()
texte_html = texte_html.replace("<!--&" + nom_a_charger + "&-->",
contenu)
locale.setlocale(locale.LC_TIME, '')
date = datetime.date.today().strftime("%A %d %B %Y")
texte_html = texte_html.replace("<!--€date€-->", date)
texte_html = texte_html.replace("<!--€racine€-->", RACINE)
with open(os.path.join(COPIE, emplacement, nom_sortie), 'w') as sortie:
sortie.write(texte_html)
os.chdir(COPIE)
with open('index.html', 'a'):
pass