up
This commit is contained in:
parent
672f61f2bb
commit
6d77de4696
@ -102,12 +102,12 @@ https://forge.chapril.org/tykayn/org-report-stats
|
||||
- conversion des liens avec nom de domaine si relatifs
|
||||
- détection des ID org-roam pour réécrire les liens html
|
||||
- réécriture des url des images vers le dossier courant
|
||||
- gestion des séries d'articles avec un tag orgmode #+serie
|
||||
- gestion des séries d'articles avec un tag orgmode #+serie, ce qui crée des indexes de séries et précise les autres posts de la série en fin d'article
|
||||
- page pour un tag listant les articles, trier par date décroissante
|
||||
- les gains de performance pour ne pas régénérer les pages déjà faites alors qu'elles n'ont pas été modifiée, et un rendu statique un peu plus joli
|
||||
- mettre un lien vers le fichier Org d'origine en fin d'article, disponible sur une forge en ligne si on l'a mis en config du site web.
|
||||
- en fin d'article, mettre le texte incitant au soutien de l'auteur
|
||||
- faire la conversion en page gemini dans `linking_articles_prev_next.py`
|
||||
|
||||
|
||||
- vérifier que les pages non articles sont bien générées
|
||||
- vérifier que les flux Atom sont valides
|
||||
- documenter les scripts
|
||||
@ -119,7 +119,8 @@ https://forge.chapril.org/tykayn/org-report-stats
|
||||
|
||||
|
||||
# Fait
|
||||
|
||||
- en fin d'article, mettre le texte incitant au soutien de l'auteur
|
||||
- faire la conversion en page gemini dans `linking_articles_prev_next.py`
|
||||
- liste de N derniers articles développés sur l'accueil, 10 par défaut
|
||||
- template footer article: gestion article suivant et précédent
|
||||
- sérendipité, navigation
|
||||
|
@ -10,12 +10,12 @@ from website_config import configs_sites
|
||||
|
||||
# Configuration des arguments de la ligne de commande
|
||||
parser = argparse.ArgumentParser(description="Générer un nouvel article en mode orgmode.")
|
||||
parser.add_argument("blog_dir", help="Le nom du dossier de blog.")
|
||||
parser.add_argument("blog", help="Le nom du dossier de blog.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
website_ndd = configs_sites[args.blog_dir]['NDD']
|
||||
blog_dir = 'sources/'+args.blog_dir+'/lang_fr/'
|
||||
website_ndd = configs_sites[args.blog]['NDD']
|
||||
blog = 'sources/'+args.blog+'/lang_fr/'
|
||||
|
||||
# Expression régulière pour extraire la date du contenu de l'article
|
||||
date_regex = re.compile(r"\b(\d{14})\b")
|
||||
@ -26,17 +26,12 @@ org_files = []
|
||||
|
||||
limit_articles_feed=1000
|
||||
count_articles=0
|
||||
# print('atom generate: fichiers dans le dossier: ',len((blog_dir)))
|
||||
|
||||
# Parcourt le dossier source à la recherche de fichiers org-mode
|
||||
for root, dirs, files in os.walk(blog_dir):
|
||||
# print('fichiers fr dans le dossier source',len(files))
|
||||
# print(files)
|
||||
for root, dirs, files in os.walk(blog):
|
||||
for file in files:
|
||||
if file.endswith(".org"):
|
||||
# print("org: ",file)
|
||||
date_str, annee, slug = find_year_and_slug_on_filename(file)
|
||||
# Ouvre le fichier et recherche la première date dans le contenu de l'article
|
||||
with open(os.path.join(root, file), "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
extract = find_extract_in_content_org(content)
|
||||
@ -44,23 +39,18 @@ for root, dirs, files in os.walk(blog_dir):
|
||||
match = date_regex_org.search(date_str)
|
||||
if match:
|
||||
date = datetime.strptime(match.group(1), "%Y-%m-%d")
|
||||
# Ajoute le fichier à la liste avec sa date correspondante
|
||||
org_files.append((date, os.path.join(root, file), annee, slug,extract))
|
||||
|
||||
if count_articles > limit_articles_feed:
|
||||
break
|
||||
if count_articles > limit_articles_feed:
|
||||
break
|
||||
# Tri des fichiers par ordre décroissant de date
|
||||
# print(org_files)
|
||||
|
||||
org_files.sort(reverse=True)
|
||||
# print(org_files)
|
||||
# print("org_files:",org_files)
|
||||
|
||||
# Génération du flux Atom
|
||||
atom_feed = {"title": "Flux Atom des articles de "+args.blog_dir,
|
||||
atom_feed = {"title": "Flux Atom des articles de "+args.blog,
|
||||
"link": f"{website_ndd}/feed",
|
||||
# "updated": org_files[0][0].strftime("%Y-%m-%dT%H:%M:%SZ"),
|
||||
# "updated": org_files[0][0],
|
||||
"updated": org_files[0][0],
|
||||
"entries": []}
|
||||
|
||||
@ -78,8 +68,6 @@ for date, file, annee, slug, extract in org_files:
|
||||
"published": date
|
||||
}
|
||||
atom_feed["entries"].append(atom_entry)
|
||||
# if published > atom_feed["updated"]:
|
||||
# atom_feed["updated"] = published
|
||||
|
||||
# Enregistrement du flux Atom dans un fichier XML
|
||||
# Le flux Atom doit contenir:
|
||||
@ -87,7 +75,7 @@ for date, file, annee, slug, extract in org_files:
|
||||
# - Une balise author avec name et email
|
||||
# - Les dates au format ISO 8601 avec timezone
|
||||
# - Un lien self vers le fichier XML
|
||||
with open(f"index_{args.blog_dir}.xml", "w", encoding="utf-8") as f:
|
||||
with open(f"index_{args.blog}.xml", "w", encoding="utf-8") as f:
|
||||
f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
|
||||
f.write('<feed xmlns="http://www.w3.org/2005/Atom">\n')
|
||||
f.write(f' <title>{atom_feed["title"]}</title>\n')
|
||||
@ -102,7 +90,6 @@ with open(f"index_{args.blog_dir}.xml", "w", encoding="utf-8") as f:
|
||||
|
||||
for entry in atom_feed["entries"]:
|
||||
slug_id = entry["title"].lower().replace(" ", "-").replace("'", "-").replace("--", "-")
|
||||
# Lire le contenu complet du fichier
|
||||
with open(file, "r", encoding="utf-8") as article_file:
|
||||
article_content = article_file.read()
|
||||
|
||||
@ -117,8 +104,8 @@ with open(f"index_{args.blog_dir}.xml", "w", encoding="utf-8") as f:
|
||||
f.write(f' <published>{entry["published"].strftime("%Y-%m-%dT%H:%M:%S+00:00")}</published>\n')
|
||||
f.write(f' <updated>{entry["published"].strftime("%Y-%m-%dT%H:%M:%S+00:00")}</updated>\n')
|
||||
f.write(' <author>\n')
|
||||
f.write(f" <name>{configs_sites[args.blog_dir]['AUTHOR']}</name>\n")
|
||||
f.write(f" <email>{configs_sites[args.blog_dir]['EMAIL']}</email>\n")
|
||||
f.write(f" <name>{configs_sites[args.blog]['AUTHOR']}</name>\n")
|
||||
f.write(f" <email>{configs_sites[args.blog]['EMAIL']}</email>\n")
|
||||
f.write(' </author>\n')
|
||||
f.write(' </entry>\n')
|
||||
f.write('</feed>')
|
||||
|
@ -10,6 +10,8 @@ source_file_extension="org"
|
||||
style_file="templates/styles/style_general.css"
|
||||
destination_gemini="gemini-capsules/$website_name/"
|
||||
|
||||
remove_all_previous_generated_files=false
|
||||
|
||||
# Boucle à travers tous les arguments passés en entrée
|
||||
for arg in "$@"; do
|
||||
# Si l'argument est connu, ajouter le nom de blog correspondant à la liste
|
||||
@ -30,24 +32,6 @@ is_directory_empty() {
|
||||
fi
|
||||
}
|
||||
|
||||
# convertir les fichiers org d'un dossier vers html
|
||||
convert_sources() {
|
||||
|
||||
# echo "argument : $1"
|
||||
source_file_extension="org"
|
||||
website_full_path=$1
|
||||
|
||||
echo "----------- convert_sources : $website_full_path"
|
||||
mkdir -p "${website_full_path}/converted/"
|
||||
cd "${website_full_path}"
|
||||
pwd
|
||||
|
||||
ls $website_full_path/*.org
|
||||
|
||||
cd $first_wd
|
||||
|
||||
}
|
||||
|
||||
# Définition de la fonction generate_website
|
||||
generate_website() {
|
||||
website_name=$1
|
||||
@ -55,44 +39,35 @@ generate_website() {
|
||||
cp $style_file html-websites/$website_name/style.css
|
||||
|
||||
if [ ! -d "sources/$website_name" ]; then
|
||||
mkdir -p sources/$website_name/img
|
||||
mkdir -p sources/$website_name/lang_fr
|
||||
mkdir -p sources/$website_name/lang_en
|
||||
mkdir -p sources/$website_name/templates
|
||||
mkdir -p sources/$website_name/build
|
||||
mkdir -p sources/$website_name/converted
|
||||
|
||||
cp templates/$website_name/$source_file_extension/* sources/$website_name/templates
|
||||
echo "Le dossier source n'existe pas pour le site $website_name"
|
||||
read -p "Voulez-vous créer le dossier source pour le nouveau site $website_name? (o/n) [n] " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Oo]$ ]]; then
|
||||
echo "Arrêt de la génération pour $website_name"
|
||||
return 1
|
||||
fi
|
||||
if [[ $REPLY =~ ^[Oo]$ ]]; then
|
||||
mkdir -p sources/$website_name/img
|
||||
mkdir -p sources/$website_name/lang_fr
|
||||
mkdir -p sources/$website_name/lang_en
|
||||
mkdir -p sources/$website_name/templates
|
||||
mkdir -p sources/$website_name/build
|
||||
mkdir -p sources/$website_name/converted
|
||||
cp templates/$website_name/$source_file_extension/* sources/$website_name/templates
|
||||
fi
|
||||
fi
|
||||
|
||||
rm -rf html-websites/$website_name/*
|
||||
mkdir -p html-websites/$website_name
|
||||
mkdir -p html-websites/$website_name/feed
|
||||
if [ "$remove_all_previous_generated_files" = true ]; then
|
||||
rm -rf html-websites/$website_name/*
|
||||
fi
|
||||
|
||||
mkdir -p html-websites/$website_name/lang_fr
|
||||
mkdir -p html-websites/$website_name/lang_fr
|
||||
|
||||
# conversion des pages statiques
|
||||
|
||||
# echo "----------- convert_sources : $root_folder/sources/$website_name"
|
||||
convert_sources "$root_folder/sources/$website_name"
|
||||
|
||||
# echo "----------- convert_sources : $root_folder/sources/$website_name/templates"
|
||||
convert_sources "$root_folder/sources/$website_name/templates"
|
||||
# echo "----------- convert_sources : pages template $website_name converties"
|
||||
|
||||
#
|
||||
# traduction fr
|
||||
convert_sources "$root_folder/sources/$website_name/lang_fr"
|
||||
# echo "----------- convert_sources :pages en français du site web $website_name converties"
|
||||
|
||||
# traduction en
|
||||
convert_sources "$root_folder/sources/$website_name/lang_en"
|
||||
# echo "----------- pages en anglais du site web $website_name converties"
|
||||
|
||||
ls -l "$root_folder/sources/$website_name/converted"
|
||||
|
||||
# bash concat_list_billets.sh $website_name
|
||||
mkdir -p "html-websites/$website_name"
|
||||
mkdir -p "html-websites/$website_name/feed"
|
||||
mkdir -p "html-websites/$website_name/tags"
|
||||
mkdir -p "html-websites/$website_name/tag"
|
||||
mkdir -p "html-websites/$website_name/lang_fr"
|
||||
mkdir -p "html-websites/$website_name/lang_en"
|
||||
|
||||
}
|
||||
|
||||
@ -104,21 +79,15 @@ for website_name in "${blogs_folders[@]}"; do
|
||||
|
||||
export website_name=$website_name
|
||||
generate_website $website_name
|
||||
# TODO reenable markdown to gemini when checks are done
|
||||
# convert_markdown_to_gmi $website_name
|
||||
|
||||
# création de l'index listant les articles pour le html et la capsule gemini:
|
||||
# prendre les fichiers markdown du dossier md/ ,
|
||||
# et créer un index des fichiers situés dedans, rangés par nom de fichier décroissant,
|
||||
# générer l'index montrant les posts les plus récents à la suite
|
||||
bash concat_list_billets.sh $website_name
|
||||
# sauver le tout dans un fichier index.gmi
|
||||
# python3 build_indexes.py $website_name
|
||||
|
||||
# créer les pages de tags
|
||||
mkdir -p "html-websites/$website_name/tags"
|
||||
mkdir -p "html-websites/$website_name/tag"
|
||||
# conversion des pages statiques
|
||||
python3 linking_articles_prev_next.py $website_name
|
||||
# créer les pages de tags à partir des infos de tag trouvées dans les fichiers org
|
||||
python3 gather_tags_in_json.py $website_name
|
||||
|
||||
# copier le style dans le dossier html
|
||||
@ -131,8 +100,7 @@ for website_name in "${blogs_folders[@]}"; do
|
||||
|
||||
# régénérer le flux Atom du blog
|
||||
mkdir -p "html-websites/$website_name/feed"
|
||||
# python3 atom_generate.py $website_name
|
||||
mv index_$website_name.xml html-websites/$website_name/feed/index.xml
|
||||
python3 atom_generate.py $website_name
|
||||
|
||||
echo "génération faite dans html-websites/$website_name"
|
||||
done
|
||||
|
@ -76,22 +76,19 @@ def save_to_json(tag_to_files, output_file):
|
||||
with open(output_file, 'w', encoding='utf-8') as json_file:
|
||||
json.dump({tag: list(files) for tag, files in tag_to_files.items()}, json_file, ensure_ascii=False, indent=4)
|
||||
|
||||
|
||||
|
||||
def generate_html_pages_for_all_tags(tag_to_files, html_output_folder):
|
||||
if not os.path.exists(html_output_folder):
|
||||
os.makedirs(html_output_folder)
|
||||
|
||||
|
||||
template_content = configs_sites[args.blog]
|
||||
|
||||
# Charger le template Jinja2
|
||||
env = Environment(loader=FileSystemLoader('.'))
|
||||
template = env.get_template('templates/html/tag.html.jinja')
|
||||
sorted_tags = sorted(tag_to_files.items())
|
||||
|
||||
tags_count = {tag: len(files) for tag, files in sorted_tags}
|
||||
|
||||
print(tags_count)
|
||||
# tags_count = {tag: len(files) for tag, files in sorted_tags}
|
||||
|
||||
|
||||
for tag, files in tag_to_files.items():
|
||||
|
||||
@ -102,7 +99,7 @@ def generate_html_pages_for_all_tags(tag_to_files, html_output_folder):
|
||||
'articles_info': articles_info,
|
||||
'files' : files,
|
||||
'tag' : tag,
|
||||
'template_content' : template_content,
|
||||
'template_content' : get_blog_template_conf(args.blog),
|
||||
'html_output_folder': html_output_folder
|
||||
}
|
||||
|
||||
@ -120,7 +117,6 @@ def generate_html_pages_for_all_tags(tag_to_files, html_output_folder):
|
||||
def generate_index_page(tag_to_files, html_output_folder):
|
||||
|
||||
|
||||
template_content = configs_sites[args.blog]
|
||||
|
||||
# Charger le template Jinja2
|
||||
env = Environment(loader=FileSystemLoader('.'))
|
||||
@ -129,12 +125,12 @@ def generate_index_page(tag_to_files, html_output_folder):
|
||||
|
||||
tags_count = {tag: len(files) for tag, files in sorted_tags}
|
||||
|
||||
print(tags_count)
|
||||
# print(tags_count)
|
||||
|
||||
# Préparer les données pour le template
|
||||
data = {
|
||||
'tags': tags_count,
|
||||
'template_content' : template_content,
|
||||
'template_content' : get_blog_template_conf(args.blog),
|
||||
'html_output_folder': html_output_folder
|
||||
}
|
||||
|
||||
|
@ -136,6 +136,7 @@ if generate_linkings_json :
|
||||
files_dict[f"{annee}/{slug}"] = {
|
||||
'path': file_path,
|
||||
'basename': basename,
|
||||
'roam_id': find_org_roam_id(content),
|
||||
'slug': f"{slug}/",
|
||||
'slug_with_year': f"{annee}/{slug}",
|
||||
'date': boom[0],
|
||||
@ -156,17 +157,36 @@ if generate_linkings_json :
|
||||
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
|
||||
template_content = get_blog_template_conf(args.blog)
|
||||
|
||||
# Dictionnaire des identifiants roam qui mène à un slug d'article pour réécrire les références
|
||||
articles_roam_id_to_slugs = {info['roam_id']: slug for slug, info in files_dict.items()}
|
||||
|
||||
# Parcourir les articles de files_dict et ajouter une clé rewritten_roam_links_html là où un lien vers un identifiant roam est trouvé dans le html_content
|
||||
for slug, info in files_dict.items():
|
||||
html_content = info['html_content']
|
||||
rewritten_html_content = html_content
|
||||
for roam_id, slug in articles_roam_id_to_slugs.items():
|
||||
if roam_id in rewritten_html_content:
|
||||
print(f'{roam_id} -> {slug}')
|
||||
rewritten_html_content = rewritten_html_content.replace(f'href="#{roam_id}"', f'href="{template_content["NDD"]}/{slug}"')
|
||||
|
||||
info['rewritten_roam_links_html'] = rewritten_html_content
|
||||
|
||||
|
||||
# Ajouter les infos des articles suivant et précédent dans la liste des articles
|
||||
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:
|
||||
os.makedirs(destination_json, exist_ok=True)
|
||||
|
||||
json_file=destination_json+'/articles_info.json'
|
||||
with open( json_file, '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)
|
||||
|
||||
@ -204,9 +224,12 @@ def generate_blog_index(json_file, template_file, output_file):
|
||||
template = env.get_template(template_file)
|
||||
|
||||
articles_others = sorted(articles_info.values(), key=lambda x: x['date'], reverse=True)[10:]
|
||||
|
||||
template_content = get_blog_template_conf(args.blog)
|
||||
|
||||
# Rendre le template avec les données
|
||||
output_index_html = template.render(
|
||||
template_content=configs_sites[args.blog],
|
||||
template_content=template_content,
|
||||
articles=sorted_articles[:global_config['posts_per_page']],
|
||||
articles_others=articles_others
|
||||
)
|
||||
@ -214,26 +237,22 @@ def generate_blog_index(json_file, template_file, output_file):
|
||||
gmi_list_articles = ''
|
||||
|
||||
for basename, article in files_dict.items():
|
||||
|
||||
# gmi_list_articles += f"\n=> article.gmi"
|
||||
gmi_list_articles += f"\n=> {article['slug']}.gmi "
|
||||
# {article.date_formatee} {article.title}"
|
||||
|
||||
print('global_config[args.blog]', configs_sites[args.blog])
|
||||
|
||||
output_index_gmi = f"""
|
||||
# {configs_sites[args.blog]['BLOG_TITLE']}
|
||||
# {template_content['BLOG_TITLE']}
|
||||
===============================================
|
||||
|
||||
{configs_sites[args.blog]['BANNIERE_ENTETE']}
|
||||
Par {configs_sites[args.blog]['AUTHOR']}
|
||||
{template_content['BANNIERE_ENTETE']}
|
||||
Par {template_content['AUTHOR']}
|
||||
Dernière mise à jour: {datetime.now()}
|
||||
***********************************************
|
||||
|
||||
{configs_sites[args.blog]['DESCRIPTION']}
|
||||
{template_content['DESCRIPTION']}
|
||||
|
||||
**************************************************************
|
||||
|
||||
{configs_sites[args.blog]['SITE_ICON']}
|
||||
{template_content['SITE_ICON']}
|
||||
|
||||
|
||||
|
||||
@ -282,7 +301,7 @@ def generate_article_pages(json_file, template_file, output_dir):
|
||||
# Générer les pages pour chaque article
|
||||
for article in articles_info.values():
|
||||
output_html = template.render(
|
||||
template_content=configs_sites[args.blog],
|
||||
template_content=get_blog_template_conf(args.blog),
|
||||
article=article,
|
||||
all_articles=articles_info
|
||||
)
|
||||
|
@ -91,6 +91,7 @@ with open(filename, "w") as f:
|
||||
#+post_url: https://www.ciperbliss.com/{now.year}/{slug}
|
||||
#+post_title: {args.title}
|
||||
#+post_tags:
|
||||
#+post_series:
|
||||
#+post_type: post
|
||||
#+post_status: publish
|
||||
#+post_date_published: <{date_string_full}>
|
||||
|
@ -1,37 +1,3 @@
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241109_221755.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241109_221813.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241114_150147.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241114_150727.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241109_221755.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241109_221813.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241114_150147.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/_small.jpg][20241114_150727.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241109_221755.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241109_221813.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241114_150147.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241114_150727.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241109_221755.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241109_221813.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241114_150147.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/pictures_inbox/20241114_150727.jpg][_small.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/('20241109_221813', '.jpg')_small.jpg][20241109_221813.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/('20241109_221755', '.jpg')_small.jpg][20241109_221755.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/('20241114_150727', '.jpg')_small.jpg][20241114_150727.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/('20241114_150147', '.jpg')_small.jpg][20241114_150147.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241109_221813_small.jpg][20241109_221813.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241109_221755_small.jpg][20241109_221755.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241114_150727_small.jpg][20241114_150727.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241114_150147_small.jpg][20241114_150147.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241109_221813_small.jpg][20241109_221813.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241109_221755_small.jpg][20241109_221755.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241114_150727_small.jpg][20241114_150727.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241114_150147_small.jpg][20241114_150147.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241109_221813_small.jpg][20241109_221813.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241109_221755_small.jpg][20241109_221755.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241114_150727_small.jpg][20241114_150727.jpg]]
|
||||
[[file:wp-uploads/content/i/2024/20241114_150147_small.jpg][20241114_150147.jpg]]
|
||||
|
||||
|
||||
[[file:wp-uploads/content/i/2024/20241109_221813_small.jpg][20241109_221813.jpg]]
|
||||
|
||||
|
||||
|
@ -1,174 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>cipherbliss_blog</title>
|
||||
<style>
|
||||
html {
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 12px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
html {
|
||||
background-color: white;
|
||||
}
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
hyphens: manual;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
/* The extra [class] is a hack that increases specificity enough to
|
||||
override a similar rule in reveal.js */
|
||||
ul.task-list[class]{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
font-size: inherit;
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1.6em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">cipherbliss_blog</h1>
|
||||
</header>
|
||||
<h1 id="creation-of-a-gemini-blog-1">Creation of a gemini blog</h1>
|
||||
<p>[2024-11-03]</p>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,32 @@
|
||||
|
||||
#+title: critères-de-qualité-de-votre-plan-de-sauvegarde
|
||||
#+post_ID:
|
||||
#+post_slug: organisation-de-taches-orgmode
|
||||
#+post_url: https://www.ciperbliss.com/2025/critères-de-qualité-de-votre-plan-de-sauvegarde
|
||||
#+post_title: Critères de qualité de votre plan de sauvegarde
|
||||
#+post_tags: backup, chiffrement
|
||||
#+post_type: post
|
||||
#+post_status: publish
|
||||
#+post_date_published: <2025-02-23 15:20:09>
|
||||
#+post_date_modified: <2025-02-23 15:20:09>
|
||||
#+post_index_page_roam_id:
|
||||
#+BLOG: cipherbliss_blog cipherbliss_blog
|
||||
|
||||
* Critères de qualité de votre plan de sauvegarde
|
||||
|
||||
Petite check liste pour vérifier la qualité de vos sauvegardes:
|
||||
|
||||
- [ ] Je dispose d’une seule source pour mon organisation d’archives
|
||||
- [ ] J’ai plusieurs destinations de sauvegarde
|
||||
- [ ] J’ai du chiffrement sur la source
|
||||
- [ ] J’ai un ensemble varié de lieux de sauvegarde où sont mes supports
|
||||
- [ ] J’ai au moins un espace de sauvegarde en dehors de chez moi
|
||||
- [ ] J’ai au moins 2 sauvegardes hors ligne
|
||||
- [ ] J’ai au moins 3 espaces de sauvegarde différents
|
||||
- [ ] J’ai mis en place de la sauvegarde automatique
|
||||
- [ ] J’ai mis dans mon agenda un rappel mensuel pour vérifier que mes sauvegardes sont bien réalisées et que leur contenu est récupérable
|
||||
- [ ] J’ai une sauvegarde résistante aux pannes de disques durs (pas facile celle-ci, bande magnétique, disque dans un conteneur résistant aux impulsions électromagnétiques?)
|
||||
- [ ] Ma source est chiffrée avec une phrase unique de plus de 25 caractères (keepass, bitwarden, autre)
|
||||
- [ ] Ma source est chiffrée avec une phrase unique de plus de 25 caractères et stockée dans un coffre fort numérique lui aussi verrouillé par une clé unique de plus de 25 caractères
|
||||
|
||||
Enjaillez!
|
@ -0,0 +1,42 @@
|
||||
|
||||
#+title: Contribuer à un projet libre
|
||||
#+post_ID:
|
||||
#+post_slug: contribuer-a-un-projet-libre
|
||||
#+post_url: https://www.ciperbliss.com/2025/contribuer-à-un-projet-libre
|
||||
#+post_title: Contribuer à un projet libre
|
||||
#+post_tags:
|
||||
#+post_type: post
|
||||
#+post_status: publish
|
||||
#+post_date_published: <2025-02-23 15:24:07>
|
||||
#+post_date_modified: <2025-02-23 15:24:07>
|
||||
#+post_index_page_roam_id:
|
||||
#+BLOG: cipherbliss_blog cipherbliss_blog
|
||||
|
||||
* Contribuer à un projet libre
|
||||
|
||||
|
||||
Trouver des gens autour du projet.
|
||||
Savoir comment ils s'organisent, piocher les infos, comprendre de quoi le projet à besoin. Pas forcément du dev, beaucoup de projets libres ont besoin d'amour dans leur interface visuelle, de traduction, ou juste de texte lisible pour que l'on comprenne bien de quoi il s'agit, à aquoi et à qui ça sert.
|
||||
Cibler ce qui nous motive le plus parmi les besoins.
|
||||
Définir le temps que l'on souhaite consacrer.
|
||||
|
||||
Causer avec les autres contributeurs **avant** de se lancer dans le moindre travail, c'est super important si on veut éviter les frustrations.
|
||||
Ne surtout pas se lancer dans douze fonctionnalités à la fois.
|
||||
|
||||
Plan d'action
|
||||
|
||||
* Proposer de faire un truc
|
||||
* Le réviser
|
||||
* Voir sa contribution approuvée par l'équipe, ou pas
|
||||
* ???
|
||||
* profit (heu lol)
|
||||
|
||||
Liens:
|
||||
|
||||
https://digitalprinciples.org/
|
||||
https://cakebaby.dev/a-beginners-guide-to-open-source?guid=none&deviceId=18f51939-894a-4996-b27b-4d19f26d18e3
|
||||
https://contribulle.org
|
||||
https://wiki.openstreetmap.org/wiki/FR:Projet_du_mois
|
||||
https://wiki.openstreetmap.org/wiki/FR:Project_of_the_month/Mod%C3%A8le
|
||||
https://learnwithnie.hashnode.dev/user-interface-a-seamless-communication
|
||||
|
@ -1,165 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="generator" content="pandoc" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
||||
<title>dragonfeu_blog</title>
|
||||
<style>
|
||||
html {
|
||||
line-height: 1.5;
|
||||
font-family: Georgia, serif;
|
||||
font-size: 20px;
|
||||
color: #1a1a1a;
|
||||
background-color: #fdfdfd;
|
||||
}
|
||||
body {
|
||||
margin: 0 auto;
|
||||
max-width: 36em;
|
||||
padding-left: 50px;
|
||||
padding-right: 50px;
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
hyphens: auto;
|
||||
overflow-wrap: break-word;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-kerning: normal;
|
||||
}
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
font-size: 0.9em;
|
||||
padding: 1em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.8em;
|
||||
}
|
||||
}
|
||||
@media print {
|
||||
body {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
font-size: 12pt;
|
||||
}
|
||||
p, h2, h3 {
|
||||
orphans: 3;
|
||||
widows: 3;
|
||||
}
|
||||
h2, h3, h4 {
|
||||
page-break-after: avoid;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin: 1em 0;
|
||||
}
|
||||
a {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
a:visited {
|
||||
color: #1a1a1a;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
margin-top: 1.4em;
|
||||
}
|
||||
h5, h6 {
|
||||
font-size: 1em;
|
||||
font-style: italic;
|
||||
}
|
||||
h6 {
|
||||
font-weight: normal;
|
||||
}
|
||||
ol, ul {
|
||||
padding-left: 1.7em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
li > ol, li > ul {
|
||||
margin-top: 0;
|
||||
}
|
||||
blockquote {
|
||||
margin: 1em 0 1em 1.7em;
|
||||
padding-left: 1em;
|
||||
border-left: 2px solid #e6e6e6;
|
||||
color: #606060;
|
||||
}
|
||||
code {
|
||||
font-family: Menlo, Monaco, 'Lucida Console', Consolas, monospace;
|
||||
font-size: 85%;
|
||||
margin: 0;
|
||||
}
|
||||
pre {
|
||||
margin: 1em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
pre code {
|
||||
padding: 0;
|
||||
overflow: visible;
|
||||
overflow-wrap: normal;
|
||||
}
|
||||
.sourceCode {
|
||||
background-color: transparent;
|
||||
overflow: visible;
|
||||
}
|
||||
hr {
|
||||
background-color: #1a1a1a;
|
||||
border: none;
|
||||
height: 1px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
table {
|
||||
margin: 1em 0;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
font-variant-numeric: lining-nums tabular-nums;
|
||||
}
|
||||
table caption {
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
tbody {
|
||||
margin-top: 0.5em;
|
||||
border-top: 1px solid #1a1a1a;
|
||||
border-bottom: 1px solid #1a1a1a;
|
||||
}
|
||||
th {
|
||||
border-top: 1px solid #1a1a1a;
|
||||
padding: 0.25em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
td {
|
||||
padding: 0.125em 0.5em 0.25em 0.5em;
|
||||
}
|
||||
header {
|
||||
margin-bottom: 4em;
|
||||
text-align: center;
|
||||
}
|
||||
#TOC li {
|
||||
list-style: none;
|
||||
}
|
||||
#TOC ul {
|
||||
padding-left: 1.3em;
|
||||
}
|
||||
#TOC > ul {
|
||||
padding-left: 0;
|
||||
}
|
||||
#TOC a:not(:hover) {
|
||||
text-decoration: none;
|
||||
}
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
span.underline{text-decoration: underline;}
|
||||
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header id="title-block-header">
|
||||
<h1 class="title">dragonfeu_blog</h1>
|
||||
</header>
|
||||
<h1 id="hi-giminiciens">Hi, giminiciens</h1>
|
||||
<p>hop hop hello in English</p>
|
||||
</body>
|
||||
</html>
|
@ -28,6 +28,7 @@
|
||||
|
||||
--------------
|
||||
|
||||
[[https://qzine.fr/wp-content/uploads/2014/03/mimika_diet_fail.jpg][https://qzine.fr/wp-content/uploads/2014/03/mimika_diet_fail.jpg]]strip
|
||||
par [[https://mimikablog.blogspot.fr/][MiMiKa]]
|
||||
[[https://qzine.fr/wp-content/uploads/2014/03/mimika_diet_fail.jpg][https://qzine.fr/wp-content/uploads/2014/03/mimika_diet_fail.jpg]]
|
||||
|
||||
strip par [[https://mimikablog.blogspot.fr/][MiMiKa]]
|
||||
|
||||
|
@ -31,17 +31,17 @@ licence CC-BY [[https://cloud.tykayn.fr/index.php/s/dessins_partage_blog]]
|
||||
|
||||
Vous pouvez aussi récupérer les contenus des fanzines plein de CULture de
|
||||
Qzine par ici:
|
||||
[[https://qzine.fr/telechargez-les-fanzines-qzine/]]
|
||||
[[https://www.qzine.fr/2021/telechargez-les-fanzines-qzine/]]
|
||||
|
||||
Le but de cette license étant de permettre beaucoup de choses, je vous
|
||||
encourage également à publier vos oeuvres avec une licence Creative
|
||||
Commons qui va bien, [[https://creativecommons.org/choose/][vous avez le
|
||||
choix]].
|
||||
Commons qui va bien, [[https://creativecommons.org/choose/][vous avez le choix]].
|
||||
|
||||
|
||||
#+begin_quote
|
||||
[[https://creativecommons.org/licenses/by/4.0/][https://i.creativecommons.org/l/by/4.0/80x15.png]]Ce(tte) œuvre est mise à disposition selon les termes de la [[https://creativecommons.org/licenses/by/4.0/][Licence Creative Commons
|
||||
Attribution 4.0 International]].
|
||||
[[https://creativecommons.org/licenses/by/4.0/][https://i.creativecommons.org/l/by/4.0/80x15.png]]
|
||||
|
||||
Ce(tte) œuvre est mise à disposition selon les termes de la [[https://creativecommons.org/licenses/by/4.0/][Licence Creative Commons Attribution 4.0 International]].
|
||||
|
||||
#+end_quote
|
||||
|
||||
|
25
utils.py
25
utils.py
@ -64,27 +64,38 @@ def trouver_nom_article(fichier_org, blog_name, format="html"):
|
||||
|
||||
return nom_article.replace(blog_name + '_', '').replace('_', ' ')
|
||||
|
||||
def find_org_roam_id(content):
|
||||
match = re.search(pattern_roam_id_search, content)
|
||||
if match:
|
||||
return match.group(1)
|
||||
return None
|
||||
|
||||
def get_blog_template_conf(blogname) -> dict:
|
||||
"""
|
||||
Retourne la configuration du blog spécifié.
|
||||
|
||||
:param blogname: Nom du blog (str).
|
||||
:return: Configuration du blog (dict).
|
||||
"""
|
||||
if blogname not in configs_sites:
|
||||
return default_config
|
||||
else:
|
||||
return configs_sites[blogname]
|
||||
|
||||
def find_year_and_slug_on_filename(fichier):
|
||||
fichier = fichier.replace('..', '.')
|
||||
# mylog(f" ------------ find_year_and_slug in {fichier} -------------")
|
||||
fichier = fichier.replace('..', '.')
|
||||
slug = ''
|
||||
annee = datetime.now().year
|
||||
date_str = f'{annee}-00-00'
|
||||
date = f'{annee}-00-00'
|
||||
boom = fichier.split('__')
|
||||
# print(boom)
|
||||
|
||||
if boom :
|
||||
date_str = boom[0]
|
||||
annee = date_str[:4]
|
||||
slug = boom[1].replace('.org', '')
|
||||
|
||||
# Convertir la date en objet datetime
|
||||
if "-" in date_str:
|
||||
slug = enlever_premier_tiret_ou_underscore(slug)
|
||||
|
||||
# mylog(f" find_year_and_slug : chemin: {annee}/{slug}/")
|
||||
return [date_str, annee, slug]
|
||||
return [date_str, annee, fichier.replace(' ', '-').replace('.org', '')]
|
||||
|
||||
|
@ -221,9 +221,10 @@ default_config = {
|
||||
"AUTHOR": "Auteur par défaut",
|
||||
"LOCALE": "fr_FR",
|
||||
"DESCRIPTION": "Description par défaut",
|
||||
"NDD": "https://example.com",
|
||||
"EMAIL": "contact@example.com",
|
||||
"SITE_ICON": "https://example.com/icon.png",
|
||||
"STYLE": "style_general.css", # issu au choix des styles du dossier templates/styles
|
||||
"NDD": "https://demo.cipherbliss.fr",
|
||||
"EMAIL": "contact@demo.cipherbliss.fr",
|
||||
"SITE_ICON": "https://www.cipherbliss.com/icon.png",
|
||||
"SITE_ICON_TYPE": "image/png",
|
||||
"NAVIGATION": """
|
||||
<nav>
|
||||
@ -232,8 +233,19 @@ default_config = {
|
||||
<a href="/contact">Contact</a>
|
||||
</nav>
|
||||
""",
|
||||
"BANNIERE_ENTETE": "https://example.com/banner.jpg",
|
||||
"BANNIERE_ENTETE": "https://www.cipherbliss.com/banner.jpg",
|
||||
"BANNIERE_ENTETE_ALT": "Bannière par défaut",
|
||||
"SERIES" : {
|
||||
"SERIE_1" : {
|
||||
"TITLE" : "Série 1",
|
||||
"ARTICLES" : [
|
||||
"2024/article-1" : {
|
||||
"TITLE" : "Article 1",
|
||||
"slug" : "2024/article-1",
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"SOUTIEN": "Si vous aimez ce que nous faisons, soutenez nous et partagez nos écrits. Vous pouvez nous faire un don sur <a href='https://liberapay.com/cipherbliss'>liberapay.com/cipherbliss</a>."
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user