Enhanced UI & UX; Added New ISBN Plugin.

- Added the ability to display book cover for the category "Lectures" if ISBN cover is available.
- Moved author's name into a small tag for better hierarchy and readability.
- Implemented a feature to indicate link sizes depending on the number of articles associated with a given tag.
- Implemented a mini footer element displaying an RSS feed icon.
- Improved category display using description dictionary.
- Added a new plugin "isbn_downloader" to fetch ISBN information when needed.
- Included the count of articles for each category.
- Implemented changes for better layout and readability of tags and categories.
- Adjusted the layout of the webpage, improving the overall look of the page.
- Included "requests" in the requirements.txt for supplanting dependencies required by the new plugin and/or features.
This commit is contained in:
Alexis Métaireau 2023-09-29 18:30:09 +02:00
parent ab77690a91
commit 9df3b183b6
84 changed files with 222 additions and 21 deletions

View file

@ -3,6 +3,7 @@ author: Harrison Owen
tags: organisation, open-space
headline: A User's guide
read_on: Septembre 2019
isbn: 979-10-91772-19-8
## The invitation

View file

@ -3,7 +3,7 @@ author: John Stolenberg
tags: féminisme, masculinisme
headline: Pour en finir avec la virilité
read_on: Octobre 2019
image: https://www.syllepse.net/syllepse_images/produits/refuser_d_etre_un_homme.jpg
isbn: 978-2-84950-381-2
## Mise en situation historique et politique

View file

@ -2,6 +2,7 @@ title: Au delà de la pénétration
author: Martin Page
tags: sexualité, féminisme
read_on: Janvier 2020
isbn: 9782371000926
headline: Le livre est une ode aux plaisirs, une proposition de dépasser une sexualité étriquée, renfermée sur des pratiques traditionnelles qui ne sont pas forcement les meilleures en terme de plaisirs.
C'est un tout petit livre de 150 pages, découpé en trois parties : une introduction, un recueil de témoignages et enfin quelques remerciements.

View file

@ -3,5 +3,6 @@ author: Françoise Vergès
tags: sexisme, racisme
read_on: Janvier 2021
headline: Un livre qui vient questionner la posture colonialiste dans le féminisme
isbn: 9782358721974
> J'ai aussi appris très tôt que si l'État veut écraser un mouvement, il a recours à tous les moyens, à toutes les ressources qui sont à sa disposition d'une part pour réprimer, d'autre part pour diviser les opprimé·e·s. D'une main il frappe, de l'autre il cherche à assimiler. **La peur est une de ses armes favorites pour produire conformise et consentement**.

View file

@ -2,6 +2,7 @@
title: Crucial Conversations
author: Kerry Patterson, Stephen R. Covey, Joseph Grenny, Ron McMillan et Al Switzler
headline: Un livre qui vient questionner nos manières d'intéragir lors des discussions cruciales de nos vies. Des outils pratiques pour éviter de rentrer dans les conflits.
isbn: 9781260474183
---
*Résumé rapide du livre, pour s'y retrouver*.
@ -76,6 +77,7 @@ Concentrez-vous sur **ce que vous voulez réellement :
- Demandez-vous ce que vous devriez faire pour aller vers ce que vous souhaitez réellement ?
**Refusez le dualisme** :
- Alors que vous considérez ce que vous voulez, notez quand vous vous piégez vous-même dans un dualisme.
- Cherchez comment faire l'un **et** l'autre.
- Clarifiez ce que vous ne souhaitez pas, ajoutez le à ce que vous voulez et demandez à votre cerveau de chercher des solutions pour retourner sur un dialogue sain.
@ -87,6 +89,7 @@ Les histoires créent des émotions. Les émotions n'arrivent pas d'elles-mêmes
Il peut être utile de séparer les faits des histoires qu'on se raconte pour pouvoir repenser nos émotions.
Le schéma peut être le suivant :
1. Voir et entendre (les faits)
2. Se raconter une histoire
3. Ressentir
@ -109,6 +112,7 @@ Comment se rendre compte que la sécurité est mise en jeu ? Il faut apprendre
Pour sécuriser la conversation, il faut réussir à sortir du contenu de la conversation d'abord. L'idée étant de se rendre compte quand les gens deviennent violents ou silencieux, pour renouer le dialogue. Une fois que c'est fait on peut reprendre la discussion.
Comprendre ce qui crée un risque pour la sécurité :
- **Objectif commun** : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu'ils ont confiance dans mes motivations ?
- **Respect mutuel** : Est-ce que les autres pensent que vous les respectez ?
@ -119,6 +123,7 @@ Pour commencer la discussion, **partagez vos bonnes intentions** : qu'est-ce que
**Contrastez** pour régler les incompréhensions : Commencez par ce que vous ne voulez pas dire, puis expliquez ce que vous voulez dire.
Créez un objectif commun lorsque vous vous rendez compte que les choses sont compliquées :
- Dites que votre objectif est de trouver un but commun.
- Reconnaissez les buts derrière les stratégies
- Inventez un but commun

View file

@ -2,6 +2,7 @@
title: Micropolitiques des groupes
author: David Vercauteren
headline: Une livre qui vise à créer une culture des précédents dans les collectifs (militants). Plusieurs chapitres et un découpage par sujets. A relire au fur et à mesure des expériences.
isbn: 9782354801786
---
## Artifices

View file

@ -3,9 +3,9 @@ title: Éloge de l'amitié
author: Geoffroy de Lagasnerie
headline: Livre où il est question d'amitié, de ce qu'elle signifie dans un monde où le devenir-parent, les sociabilités familiales et le volontaire désintérêt dans les relations est la norme.
tags: relations, amitié
isbn: 9782080420015
---
## Citations
> Lorsqu'elle devient un mode de vie, qu'elle devient l'objet d'une culture spécifique qui occupe le cœur de l'existence, le lien d'investissement des intérêts psychiques et non ce qui reste après la famille, le travail, les voisins, etc., **l'amitié pourrait être interprétée comme la recherche d'un dehors**.

View file

@ -5,7 +5,7 @@ hésitons à continuer à nous entêter avec notre propre solution de
stockage/synchronisation.**
Comme nous l'écrivions [dans l'article
précédent]({filename}/technologie/2015-04-01-service-de-nuages.rst), nous
précédent]({filename}/code/2015-04-01-service-de-nuages.rst), nous
souhaitons construire une solution de stockage générique. On refait
[Daybed](http://daybed.readthedocs.org) chez Mozilla \!

View file

@ -63,7 +63,7 @@ Obtenir la liste des "principals" d'un ACE
d'une ACL (e.g. *modifier un enregistrement*).
Avec le `système de permissions choisi
<{filename}/technologie/2015-05-01-cliquet-permissions.rst>`_, les permissions d'un
<{filename}/code/2015-05-01-cliquet-permissions.rst>`_, les permissions d'un
objet héritent de celle de l'objet parent.
Par exemple, avoir le droit d'écriture sur un *bucket* permet la

View file

@ -18,7 +18,7 @@ Les origines
============
L'objectif pour le premier trimestre 2015 était de construire un service de
stockage et de `synchronisation de listes de lecture <{filename}/technologie/2015-04-01-service-de-nuages.rst>`_.
stockage et de `synchronisation de listes de lecture <{filename}/code/2015-04-01-service-de-nuages.rst>`_.
Au démarrage du projet, nous avons tenté de rassembler toutes les bonnes pratiques
et recommandations, venant de différentes équipes et surtout des derniers projets déployés.
@ -142,10 +142,10 @@ de *Firefox Sync* pour la gestion de la concurrence et de l'«offline-first».
Il est `documenté en détail <http://cliquet.readthedocs.org/en/latest/api/index.html>`_.
Dans un monde idéal, ce protocole serait versionné, et formalisé dans une RFC.
En rêve, il existerait même plusieurs implémentations avec des technologies différentes
En rêve, il existerait même plusieurs implémentations avec des codes différentes
(Python, Go, Node, etc.). [#]_
.. [#] Voir notre `article dédié sur les permissions <{filename}/technologie/2015-05-01-cliquet-permissions.rst>`_
.. [#] Voir notre `article dédié sur les permissions <{filename}/code/2015-05-01-cliquet-permissions.rst>`_
.. [#] Rappel: nous sommes une toute petite équipe !
@ -220,7 +220,7 @@ mais rien n'empêcherait d'implémenter le stockage dans un modèle relationnel.
Comme les composants peuvent être remplacés depuis la configuration, il est
tout à fait possible d'étendre *Cliquet* avec des notions métiers ou des
technologies exotiques ! Nous avons posé quelques idées dans `la documentation
codes exotiques ! Nous avons posé quelques idées dans `la documentation
de l'éco-système <http://cliquet.readthedocs.org/en/latest/ecosystem.html>`_.
Dans les prochaines semaines, nous allons introduire la notion d'«évènements» (ou signaux),
@ -426,7 +426,7 @@ Quelques questions courantes
Pourquoi Python ?
On prend beaucoup de plaisir à écrire du Python, et le calendrier annoncé
initialement était très serré: pas question de tituber avec une technologie
initialement était très serré: pas question de tituber avec une code
mal maitrisée !
Et puis, après avoir passé près d'un an sur un projet Node.js, l'équipe avait

View file

@ -112,7 +112,7 @@ est de chiffrer les messages avec la clé du destinataire et de le mettre dans
un *pot commun*. Tout le monde essaye de déchiffrer tous les messages, mais ne
peut déchiffrer que les siens.
Cela permet de ne **pas** fuiter de méta-données, [à l'inverse de PGP]({filename}/technologie/2015-05-25-pgp-problemes.md).
Cela permet de ne **pas** fuiter de méta-données, [à l'inverse de PGP]({filename}/code/2015-05-25-pgp-problemes.md).
Je n'ai en fait pas de réponse claire à donner à cette question: l'auteur de
ZeroNet me disait que 10MB (la limite de taille d'un site, par défaut)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View file

@ -119,3 +119,4 @@ même. La maintenance des serveurs fait donc partie du lot :-)
- Master's degree in Software Engineering, University of Oxford Brookes.
- BTS Informatique et Réseau, Angers.

View file

@ -0,0 +1,36 @@
---
date: 2023-09-29
headline: Une semaine mi-statique, mi mobile. Difficile de trouver un rythme de travail qui me convienne.
---
# 2023, Semaine 39
## Ce qui s'est passé
Framasoft
: J'ai commencé à travailler sur l'outil de supervision, en partant bille en tête sur une solution qui s'est avérée ne pas être la plus simple à mettre en place. J'ai passé pas mal de temps à questionner mes choix techniques, pour finalement en changer et me questionner sur la partie **metier**, ce qui me semblait plus intéressant. A partir du moment où j'ai arrêté d'essayer d'appliquer une solution « déjà faite » j'ai pu me questionner sur le modèle de données et aller de l'avant. Étrangement c'est quand j'ai produit le moins de code que j'ai trouvé que j'étais le plus productif.
Notmyidea
: Je n'ai pas trop avancé sur la partie structure juridique, mais les choses décantent et me paraissent plus clair que la semaine passée. Je penche en ce moment pour une solution en auto-entreprise pour les quelques premières missions, quitte à remettre en question ce choix par la suite si je trouve de nouveaux·elles client·es. Je me laisse le temps pour décider.
: J'ai <del>procrastiné</del> passé beaucoup plus de temps que prévu sur la mise en place d'outils utiles pour moi, et à peaufiné mon site web. J'ai maintenant un bouncer ZNC et un VPN fait maison qui me permettent de travailler dans de meilleures conditions. Je suis à la fois content d'avoir pris le temps de mettre en place des outils, et en même temps j'ai une impression de procrastination.
## Des joies
- Avoir pris le temps d'aller « à la ville » pour passer du temps avec des amis et sociabiliser.
- M'écouter et décider de dormir sur place pour travailler aussi sur Rennes le lendemain.
- Aller à l'espace de coworkig à côté de chez moi.
- Prendre le temps de faire des choses peu importantes entassées dans ma todolist depuis trop longtemps.
- Récolter des fruits de discussions passées lors d'une soirée. Vive les todo-list !
- Voir qu'une demande de modifications que j'ai faite soit appréciée et intégrée rapidement.
- Dépanner le serveur de [copanier](https://github.com/almet/copanier), trouver le problème rapidement et le régler facilement.
## Des peines
- Je suis retombé malade en fin de semaine, et donc bien fatigué. Ca impacte mon moral et ma capacité de concentration.
- Des discussions compliquées dans mon collectif de vie. Je suis content de poser des limites, mais je sens que je cherche toujours la validation des autres.
- Sentir que ma posture dans les conversations est plus ferme que par le passé. Je suis à la fois content de ne pas **toujours** me remettre en question, mais j'aimerai réussir à faire preuve de plus d'ouverture. Il faut trouver l'équilibre
- Triste de voir des conflits escalader alors que ça pourrait être autrement.
## Vu, lu, écouté
- 🎮 J'ai continué [Baba is you](https://fr.wikipedia.org/wiki/Baba_Is_You) avec Arthur. C'était sympa de se faire les reflexions à deux cerveaux.
- ▶︎ [Vu une présentation sur DuckDB](https://www.youtube.com/watch?app=desktop&v=dVzfNZN9NKI&list=PL8uoeex94UhFcwvAfWHybD7SfNgIUBRo-&index=128), une base de données locale et minimaliste qui semble adaptée pour de la visualisation de données à grande échelle.

57
isbn_downloader.py Normal file
View file

@ -0,0 +1,57 @@
import logging
import os
from pathlib import Path
import requests
from pelican import log, signals
log = logging.getLogger(__name__)
def check_or_download_image(isbn, output_dir):
log.info(f"Downloading cover for {isbn=}")
output_dir = Path(output_dir)
# remote_url = f"https://images.isbndb.com/covers/41/83/{isbn}.jpg"
image_relative_path = f"images/isbn-covers/{isbn}.jpg"
image_path = output_dir / image_relative_path
if image_path.exists():
return image_relative_path
else:
try:
remote_url = f"https://www.googleapis.com/books/v1/volumes?q=isbn:{isbn}"
api_resp = requests.get(remote_url)
api_resp.raise_for_status()
returned = api_resp.json()
if returned["totalItems"] > 0:
thumbnail_url = returned["items"][0]["volumeInfo"]["imageLinks"][
"thumbnail"
]
response = requests.get(thumbnail_url, stream=True)
os.makedirs(os.path.dirname(image_path), exist_ok=True)
with open(image_path, "wb") as fp:
for chunk in response.iter_content(chunk_size=8192):
fp.write(chunk)
return image_relative_path
except:
log.error(
f"No ISBN cover found for {isbn=}. Look at https://isbnsearch.org/isbn/{isbn}"
)
return
def run_for_each_article(generator):
for article in generator.articles:
isbn = getattr(article, "isbn", None)
if isbn:
isbn = isbn.replace("-", "")
article.isbn_cover = check_or_download_image(isbn, generator.path)
def register():
signals.article_generator_finalized.connect(run_for_each_article)

View file

@ -67,6 +67,10 @@ h1 {
text-decoration-style: unset;
}
h1 small {
font-size: 0.7em;
}
h2 {
font-size: 1.3em;
}
@ -385,4 +389,39 @@ hr::after {
#links ul {
padding: 0;
}
a[data-size]::after {
content: attr(data-size);
vertical-align: super;
font-style: italic;
font-size: 10px;
}
a[data-size='2'] {
font-size: 1.3em;
}
a[data-size='3'] {
font-size: 1.6em;
}
a[data-size='4'] {
font-size: 1.8em;
}
a[data-size='5'] {
font-size: 2.2em;
}
#feed img {
weight: 25px;
width: 25px;
}
.book-cover {
float: right;
padding-right: 1em;
max-width: 128px;
max-height: 192px;
}

38
mnmlist/static/rss.svg Normal file
View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
x="0px"
y="0px"
viewBox="0 0 132 130.5"
enable-background="new 0 0 216 146"
xml:space="preserve"
id="svg1"
sodipodi:docname="noun-rss-3933798.svg"
width="132"
height="130.5"
inkscape:version="1.3 (0e150ed, 2023-07-21)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1" /><sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
showguides="false"
inkscape:zoom="1.2931507"
inkscape:cx="108.26271"
inkscape:cy="91.25"
inkscape:window-width="1280"
inkscape:window-height="449"
inkscape:window-x="0"
inkscape:window-y="25"
inkscape:window-maximized="0"
inkscape:current-layer="svg1" /><path
d="m 121.92752,9.5799492 c -4.588,-4.589 -10.115,-6.884 -16.578,-6.884 H 27.134526 c -6.463,0 -11.99,2.295 -16.58,6.884 C 5.9655255,14.169949 3.6705255,19.696949 3.6705255,26.159949 v 78.214001 c 0,6.463 2.295,11.99 6.8840005,16.58 4.59,4.59 10.117,6.885 16.58,6.885 h 78.213994 c 6.463,0 11.99,-2.295 16.578,-6.885 4.59,-4.59 6.885,-10.117 6.885,-16.58 V 26.159949 c 0,-6.463 -2.295,-11.991 -6.884,-16.5799998 z M 42.329526,103.92595 c -2.038,2.036 -4.495,3.055 -7.374,3.055 -2.878,0 -5.336,-1.019 -7.373,-3.055 -2.037,-2.037 -3.056,-4.495001 -3.056,-7.374001 0,-2.878 1.019,-5.336 3.056,-7.373 2.037,-2.037 4.495,-3.055 7.373,-3.055 2.879,0 5.337,1.018 7.374,3.055 2.036,2.037 3.055,4.495 3.055,7.373 0,2.879 -1.018,5.337001 -3.055,7.374001 z m 30.916996,2.239 c -0.543,0.543 -1.168,0.813 -1.874,0.813 H 60.944526 c -0.706,0 -1.303,-0.229 -1.792,-0.692 -0.489,-0.461 -0.761,-1.045 -0.815,-1.752 -0.597,-8.363001 -3.883,-15.533001 -9.858,-21.509001 -5.975,-5.974 -13.144,-9.26 -21.509,-9.858 -0.706,-0.053 -1.29,-0.324 -1.751,-0.813 -0.462,-0.488 -0.693,-1.086 -0.693,-1.792 v -10.429 c 0,-0.706 0.272,-1.331 0.815,-1.874 0.543,-0.543 1.195,-0.787 1.956,-0.733 12.601,0.706 23.355,5.514 32.263,14.421 8.907996,8.909 13.714996,19.662 14.420996,32.264001 0.055,0.76 -0.192,1.411 -0.735,1.954 z m 31.285998,0 c -0.543,0.543 -1.167,0.814 -1.873,0.814 H 92.230522 c -0.706,0 -1.304,-0.244 -1.792,-0.732 -0.489,-0.488 -0.76,-1.086 -0.815,-1.793 -0.38,-11.080001 -3.409,-21.346001 -9.084,-30.797001 -5.675,-9.451 -13.238996,-17.014 -22.689996,-22.689 -9.451,-5.676 -19.716,-8.704 -30.797,-9.084 -0.706,-0.054 -1.303,-0.326 -1.792,-0.814 -0.488,-0.489 -0.733,-1.087 -0.733,-1.793 v -10.429 c 0,-0.706 0.272,-1.33 0.815,-1.874 0.489,-0.543 1.113,-0.787 1.874,-0.732 8.364,0.271 16.444,1.791 24.238,4.562 7.794,2.769 14.855,6.558 21.183996,11.365 6.328,4.806 11.895,10.374 16.701,16.702 4.806,6.328 8.596,13.389 11.365998,21.183 2.769,7.795 4.291,15.874 4.562,24.238001 0.108,0.761 -0.135,1.385 -0.735,1.873 z"
id="path1" /></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -4,7 +4,12 @@
<header>
{% if article.category == "Lectures" %}
<h1 class="post-title">« {{ article.title }} » par {{ article.author }}</h1>
{% if article.category == "Lectures" and article.isbn_cover %}
<div class="book-cover">
<img src="{{SITEURL}}/{{article.isbn_cover}}" />
</div>
{% endif %}
<h1 class="post-title">{{ article.title }}<small><br />par {{ article.author }}</small></h1>
{% if article.headline %}
<p><em>{{ article.headline }}</em></p>
{% endif %}

View file

@ -33,6 +33,9 @@
{% include 'github.html' %}
{% block content %}
{% endblock %}
<footer>
<a id="feed" href="/feeds/all.atom.xml"><img src="/theme/rss.svg" /></a>
</footer>
</body>

View file

@ -1,8 +1,14 @@
{% extends "base.html" %}
{% block content %}
<ul>
<dl id="categories">
{% for category, articles in categories %}
<li><a href="{{ SITEURL }}/{{ category.url }}">{{ category }}</a></li>
{% if category in CATEGORIES_DESCRIPTION.keys() %}
<dt><h2><a href="/{{category.slug}}/">{{ CATEGORIES_DESCRIPTION[category][0] }}</a></h2></dt>
<dd>{{ CATEGORIES_DESCRIPTION[category][1] }}. {{ articles | length }} articles.</dd>
{% endif %}
{% endfor %}
</ul>
</dl>
{% endblock %}

View file

@ -1,7 +1,9 @@
{% extends "base.html" %}
{% block content %}
{% if category in CATEGORIES_DESCRIPTION.keys() %}
<h1>{{ CATEGORIES_DESCRIPTION[category][0] }}</h1>
<h1>{{ CATEGORIES_DESCRIPTION[category][0] }}
<a id="feed" href="{{ SITEURL }}/feeds/{{ category.slug }}.atom.xml"><img src="{{ SITEURL }}/theme/rss.svg" /></a>
</h1>
<p>{{ CATEGORIES_DESCRIPTION[category][1] }}</p>
{% else %}

View file

@ -1,3 +1,3 @@
{% extends "index.html" %}
{% block title %}{{ tag }} - {{ super() }}{% endblock %}
{% block pagetitle %}Posts with #{{ tag }} tag{% endblock %}
{% block pagetitle %}Tag « {{ tag }} »{% endblock %}

View file

@ -1,8 +1,10 @@
{% extends "base.html" %}
{% block content %}
<p>Voici une liste de tous les tags utilisés sur ce site :</p>
<ul>
{% for tag, articles in tags %}
<li><a href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a></li>
{% for tag, articles in tags|sort(attribute='articles|length', reverse=true) %}
<a data-size="{% if articles | length > 1 %}{{articles | length }}{% endif %}" href="{{ SITEURL }}/{{ tag.url }}">{{ tag }}</a>
{% endfor %}
</ul>
{% endblock %}

View file

@ -18,9 +18,7 @@ DEFAULT_DATE_FORMAT = "%d %B %Y"
LINKS = []
PLUGIN_PATHS = ["."]
PLUGINS = [
"simplereader",
]
PLUGINS = ["simplereader", "isbn_downloader"]
CACHE_OUTPUT_DIRECTORY = "cache"
CACHE_DOMAIN = "/cache/"
@ -54,4 +52,8 @@ CATEGORIES_DESCRIPTION = {
"Journal",
"Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.",
),
"notes": (
"Carnet de notes",
"Prises bien souvent en regardant une vidéo ou un article en ligne. Je les mets ici pour pouvoir les retrouver quand le besoin se fait sentir.",
),
}

View file

@ -3,3 +3,4 @@ markdown
datefinder
typogrify
ghp-import
requests