This commit is contained in:
Tykayn 2025-02-23 15:50:56 +01:00 committed by tykayn
parent 672f61f2bb
commit 6d77de4696
15 changed files with 203 additions and 506 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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 dune seule source pour mon organisation darchives
- [ ] Jai plusieurs destinations de sauvegarde
- [ ] Jai du chiffrement sur la source
- [ ] Jai un ensemble varié de lieux de sauvegarde où sont mes supports
- [ ] Jai au moins un espace de sauvegarde en dehors de chez moi
- [ ] Jai au moins 2 sauvegardes hors ligne
- [ ] Jai au moins 3 espaces de sauvegarde différents
- [ ] Jai mis en place de la sauvegarde automatique
- [ ] Jai 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
- [ ] Jai 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!

View File

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

View File

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

View File

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

View File

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

View File

@ -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', '')]

View File

@ -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>."
}