orgmode-to-gemini-blog/linking_articles_prev_next.py
2025-02-20 17:14:53 +01:00

222 lines
8.4 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/python3
# trouver les articles précédents et suivants
from utils import *
from website_config import configs_sites
import os
import json
import re
import argparse
import pypandoc
from jinja2 import Environment, FileSystemLoader
import time # Importer le module time
# Démarrer le chronomètre
start_time = time.time()
# pour tester
generate_linkings_json = True
generate_articles = True
run_pandoc = True # le plus long quand on a beaucoup d'articles
# Configurer argparse pour prendre le blog en argument
parser = argparse.ArgumentParser(description='Générer une liste des derniers articles de blog.')
parser.add_argument('blog', type=str, help='Nom du dossier du blog à traiter', default='tykayn_blog')
args = parser.parse_args()
# Fonction pour extraire le basename d'un fichier
def get_basename(file_name):
return os.path.splitext(file_name)[0]
# Chemin du dossier contenant les fichiers orgmode
directory = f'sources/{args.blog}/lang_fr'
destination_json = f'sources/{args.blog}/build'
destination_html = f'html-websites/{args.blog}/'
# Dictionnaire pour stocker les informations des fichiers
files_dict = {}
def get_first_picture_url(content):
# Utiliser une expression régulière pour trouver la première URL d'image dans le contenu
pattern = r'\[\[(.*?)\]\]'
match = re.search(pattern, content)
if match:
return match.group(1)
else:
return None
if generate_linkings_json :
# Parcourir les fichiers du dossier
for file_name in os.listdir(directory):
if file_name.endswith('.org'):
file_path = os.path.join(directory, file_name)
with open(file_path, "r", encoding="utf-8") as f:
content = f.read()
date_modified = time.ctime(os.path.getmtime(file_path))
basename = get_basename(file_name)
date_str, annee, slug = find_year_and_slug_on_filename(basename)
tags = extract_tags_from_file(file_path, global_config['excluded_tags'])
# Convertir les tags en liste si c'est un set
if isinstance(tags, set):
tags = list(tags)
boom = basename.split('__')
# Convertir le contenu Org en HTML
title = find_first_level1_title(content)
# Désactiver les warning d'identifiant dupliqué dans la conversion pandoc
content_without_h1 = re.sub(r'^\*.*?$', '', content, count=1, flags=re.MULTILINE)
if run_pandoc:
html_content = pypandoc.convert_text(content_without_h1, 'html', format='org')
else:
html_content = content_without_h1
# html_content = pypandoc.convert_text(content, 'html', format='org')
files_dict[f"{annee}/{slug}"] = {
'path': file_path,
'basename': basename,
'slug': f"{slug}/",
'slug_with_year': f"{annee}/{slug}",
'date': boom[0],
'date_modified' : date_modified,
'first_picture_url' : get_first_picture_url(content),
'date_formattee': datetime.strptime(date_str, '%Y%m%d%H%M%S').strftime('%d %B %Y à %H:%M:%S') if len(date_str) == 14 else datetime.strptime(date_str, '%Y%m%dT%H%M%S').strftime('%d %B %Y à %H:%M:%S') if len(date_str) == 15 else datetime.strptime(date_str, '%Y-%m-%d').strftime('%d %B %Y'),
'annee': annee,
'tags': tags,
'title': title,
'next': None,
'previous': None,
'org_content': content, # Contenu Org original
'html_content_without_h1': re.sub(r'<h1>.*?</h1>', '', html_content), # Contenu HTML converti sans le titre de premier niveau
'html_content': html_content # Contenu HTML converti
}
# Trier les basenames par ordre décroissant
sorted_basenames = sorted(files_dict.keys(), reverse=True)
print(len(sorted_basenames), 'articles trouvés')
# Ajouter les noms des articles suivant et précédent
for i in range(len(sorted_basenames)):
basename = sorted_basenames[i]
# print('basename', basename)
if i > 0:
files_dict[basename]['previous'] = sorted_basenames[i - 1]
if i < len(sorted_basenames) - 1:
# print('suivant',files_dict[sorted_basenames[i + 1]])
files_dict[basename]['next'] = sorted_basenames[i + 1]
with open(destination_json+'/articles_info.json', 'w', encoding='utf-8') as json_file:
files_dict_serialized = json.dumps(files_dict, ensure_ascii=False, indent=4)
json_file.write(files_dict_serialized)
print(f"Nombre d'articles trouvés : {len(sorted_basenames)}")
count_articles_updated = 0
for basename, info in files_dict.items():
date_str = info['date']
if date_str > '20240101':
count_articles_updated += 1
print(f"Nombre d'articles mis à jour après le 01 01 2024 : {count_articles_updated}")
def generate_blog_index(json_file, template_file, output_file):
"""
Génère la page d'index du blog à partir des informations JSON et d'un template Jinja2.
:param json_file: Chemin du fichier JSON contenant les informations des articles.
:param template_file: Chemin du fichier template Jinja2.
:param output_file: Chemin du fichier HTML de sortie.
"""
# Charger les données JSON
with open(json_file, 'r', encoding='utf-8') as f:
articles_info = json.load(f)
# Trier les articles par date (ou par slug) et prendre les 10 derniers
sorted_articles = sorted(articles_info.values(), key=lambda x: x['date'], reverse=True)[:global_config['posts_per_page']]
# Configurer Jinja2
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template(template_file)
articles_others = sorted(articles_info.values(), key=lambda x: x['date'], reverse=True)[10:]
# Rendre le template avec les données
output_html = template.render(
template_content=configs_sites[args.blog],
articles=sorted_articles[:global_config['posts_per_page']],
articles_others=articles_others
)
# Écrire le fichier de sortie
with open(output_file, 'w', encoding='utf-8') as f:
f.write(output_html)
print(f"Page d'index générée dans {output_file}")
# Appel de la fonction pour générer la page d'index
generate_blog_index(destination_json + '/articles_info.json', 'templates/html/index.html.jinja', destination_html + '/index.html')
def generate_article_pages(json_file, template_file, output_dir):
"""
Génère les pages HTML pour chaque article à partir des informations JSON et d'un template Jinja2.
:param json_file: Chemin du fichier JSON contenant les informations des articles.
:param template_file: Chemin du fichier template Jinja2.
:param output_dir: Répertoire de sortie pour les fichiers HTML.
"""
print('generate_article_pages: ouverture du json')
# Charger les données JSON
with open(json_file, 'r', encoding='utf-8') as f:
articles_info = json.load(f)
# Configurer Jinja2
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template(template_file)
# Générer les pages pour chaque article
for article in articles_info.values():
output_html = template.render(
template_content=configs_sites[args.blog],
article=article,
all_articles=articles_info
)
# Construire le chemin de sortie en fonction du slug avec l'année
output_subdir = os.path.join(output_dir, article['slug_with_year'])
# print('make subdir: ',output_subdir)
os.makedirs(output_subdir, exist_ok=True)
output_file = os.path.join(output_subdir ,"index.html")
# print(output_file)
# Écrire le fichier de sortie
with open(output_file, 'w', encoding='utf-8') as f:
f.write(output_html)
print('generate_article_pages: fin de génération de l index')
if generate_articles:
# Appel de la fonction pour générer les pages des articles
generate_article_pages(destination_json + '/articles_info.json', 'templates/html/article.html.jinja', destination_html)
# À la fin du script, calculer et afficher le temps d'exécution
execution_time = time.time() - start_time
print(f"Temps d'exécution : {execution_time:.2f} secondes")