diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..08063af
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+output/
+.venv/
+.envrc
diff --git a/2021-en-attendant-la-pycon-fr-packaging.md b/2021-en-attendant-la-pycon-fr-packaging.md
new file mode 100644
index 0000000..d0db593
--- /dev/null
+++ b/2021-en-attendant-la-pycon-fr-packaging.md
@@ -0,0 +1,273 @@
+# Faire ses paquets
+En respectant les standards.
+
+::: notes
+
+Se présenter, hackinscience, formations, ...
+
+
+## Donc on va parler de distutils ?
+
+PEP 632 (septembre 2020) : Deprecate distutils module.
+
+La doc dit de ne plus l'utiliser depuis ~2014…
+
+::: notes
+
+setuptools à commencé en étant du monkey-patch de distutils,
+maintenant setuptools intègre sa copie de distutils.
+
+
+## Donc on va parler de {buzzword} ?
+
+- pipenv : 304k lignes de code.
+- bento : 37k lignes de code.
+- poetry : 16k lignes de code.
+- flit : 4k lignes de code.
+- build : <1k lignes de code.
+
+::: notes
+
+Ils utilisent tous setuptools ^^
+
+
+## Non mais pourquoi pas {buzzword} ?
+
+- Ça demande du temps pour migrer d'un standard à un outil tiers.
+- Ça demande à une partie de l'équipe d'apprendre ce nouvel outil.
+- Puis ça demande du temps pour migrer à nouveau vers le standard quand l'outil est abandonné.
+
+::: notes
+
+On a mieux a faire de notre temps.
+
+
+## Mais les Pipfile ?
+
+En fait oui et non, Pipfile c'est une spec à part :
+
+=> https://github.com/pypa/pipfile
+
+Rien n'empêche d'un jour pouvoir faire un :
+```
+pip install --pipfile Pipfile.lock
+```
+
+::: notes
+
+Cherchez dans les issues de pypa/pip, la discussion est ouverte.
+
+Et puis pipenv c'est abandonné ?
+
+
+# OK, bon, comment on fait sans buzzwords ?
+
+## pyproject.toml
+
+Les PEP 517 et 518 normalisent la construction de paquets en déclarant son outil de build dans `pyproject.toml` :
+
+```toml
+[build-system]
+requires = ["setuptools", "wheel"]
+build-backend = "setuptools.build_meta"
+```
+
+Le backend étant `setuptools.build_meta`, on aura besoin d'un `setup.cfg`.
+
+::: notes
+
+C'est typiquement utilisé par pip lors d'un `pip install .`.
+
+## setup.py
+
+En 2020 il ne prenait plus qu'une ou deux lignes, bienvenu en 2021.
+
+::: notes
+
+`setuptools` autorise depuis la v40.0.9 de ne pas avoir de `setup.py`,
+à condition d'avoir un `pyproject.toml`.
+
+(La PEP517 ne gère pas encore les installations éditables, si vous les utilisez,
+vous aurez donc tout de même besoin d'un `setup.py`.)
+
+https://setuptools.readthedocs.io/en/latest/setuptools.html#setup-cfg-only-projects
+
+Bon c'est quand même pratique les installations éditables, et `pip-compile setup.py`.
+
+
+## setup.cfg
+
+```
+[metadata]
+name = oeis
+version = attr: oeis.__version__
+description = Implementation of a few integer sequences.
+long_description = file: README.md
+long_description_content_type = text/markdown; charset=UTF-8
+...
+```
+
+::: notes
+
+Voir mon setup.cfg sur le projet githup.com/JulienPalard/oeis.
+
+
+## Vous venez de 2020 ?
+
+Ne faites pas la conversion à la main !
+
+```text
+pip install setup-py-upgrade
+```
+
+
+## Comment je build ?
+
+On peut utiliser `build` de la PyPA, un outil qui ne fait qu'une chose mais qui le fait bien :
+
+```
+pip install build
+python -m build --sdist --wheel .
+```
+
+::: notes
+
+Les dépendances de build sont installées dans un environnement isolé (*isolated build*).
+Oui oui il crée vraiment un venv, avec le module venv de Python.
+
+Pas besoin de `pip install setuptools wheel`
+
+
+## Et comment j'upload ?
+
+On peut utiliser `twine` de la PyPA, un outil qui ne fait qu'une chose mais qui le fait bien :
+
+```text
+pip install twine
+twine upload -r test dist/*
+pip install --index-url https://test.pypi.org/simple/ oeis
+twine upload dist/*
+```
+
+
+# Et les dépendances !?
+
+Les dépendances « runtime » (`install_requires`) sont décrites dans le `setup.cfg`.
+
+
+## Épinglées ou pas ?
+
+Ça dépend de ce que vous faites, mais généralement on vise le plus large possible.
+
+::: notes
+
+Vous voulez que votre lib, ou votre programme puisse s'installer sans conflit avec une autre lib ou un autre programme.
+
+Et on ne va pas maintenir, à la main, dans le setup.cfg, des versions précisément.
+
+
+## Épingler saybien !
+
+Je n'ai pas dit que c'était mal, c'est très bien pour les développeurs, pour la CI, pour la prod…
+
+
+## Épingler saybien !
+
+J'utilise un outil qui ne fait qu'une chose mais qui le fait bien :
+
+`pip-compile` du paquet `pip-tools`, ça ne fait *que* geler les dépendances, et ça le fait bien.
+
+::: notes
+
+Oui on sent que je n'aime pas les projets qui essayent de tout résoudre d'un coup.
+
+
+## Épingler saybien !
+
+On peut donc "geler" les dépendances du projet via un :
+
+```
+pip-compile setup.py
+```
+
+::: notes
+
+https://github.com/jazzband/pip-tools/issues/1047
+
+
+## Épingler saybien !
+
+On peut ensuite documenter ses dépendances de dev dans un `requirements-dev.in` :
+
+```txt
+-r requirements.txt
+tox
+```
+
+## Épingler saybien !
+
+Et épingler aussi les requirements de dev, afin de les utiliser dans des tests reproductibles :
+
+```txt
+pip-compile requirements-dev.in
+```
+
+
+## Épingler saybien !
+
+On peut même hasher les dépendances pour les plus paranos :
+
+```txt
+pip-compile --generate-hashes setup.py
+```
+
+## Qu'est-ce que ça donne ?
+
+```
+pyproject.toml // 3 lignes
+setup.cfg
+requirements.txt // autogénéré par pip-compile
+requirements-dev.in
+requirements-dev.txt // autogénéré par pip-compile
+```
+
+## Mettre à jour
+
+```txt
+pip-compile --upgrade requirements-dev.in
+```
+
+# Installer
+
+Il existe un outil qui ne fait qu'une chose, mais qui le fait bien : `pip`.
+
+```
+pip install oeis
+```
+
+
+## Installer
+
+Vous connaissez alors je passe sur le plus gros, mais n'oubliez pas :
+
+```txt
+pip install git+https://github.com/org/project@branch
+```
+
+::: notes
+
+Typiquement pour tester la PR de quelqu'un (et oui ça déclenche la construction d'une wheel via les dépendances
+et le point d'entrée décrit dans pyproject.toml).
+
+
+# RTFM
+
+- https://setuptools.readthedocs.io/en/latest/build_meta.html
+- https://setuptools.readthedocs.io/en/latest/userguide/declarative_config.html
+- https://packaging.python.org/guides/using-testpypi/
+- https://setuptools.readthedocs.io/en/latest/setuptools.html#setup-cfg-only-projects
+
+
+# Questions
+
+?
\ No newline at end of file
diff --git a/2022-campus-du-libre-hackinscience.md b/2022-campus-du-libre-hackinscience.md
new file mode 100644
index 0000000..49e8732
--- /dev/null
+++ b/2022-campus-du-libre-hackinscience.md
@@ -0,0 +1,232 @@
+# HackInScience
+
+
+
+
+
+Julien Palard
+
+CPython core dev
+
+
+# Demo time !
+
+Parce que vous êtes là pour ça.
+
+::: notes
+
+Qui à dit « C'est moche ! » ? Je ne suis pas dev front !
+
+Ne pas oublier la démo C et Rust !
+
+Ceux pour qui la démo suffit, vous pouvez sortir ♥
+
+## Enseigner le Python
+
+J'ai l'habitude.
+
+Mais à des groupes de ~6 pendant ~3 jours.
+
+## C'est green
+
+![Ruby Rhod](static/ruby-rhod.jpg)
+
+## Enseigner le Python
+
+Un jour on nous a proposé un groupe de 50 pendant 7 jours.
+
+::: notes
+
+En fait il sont arrivés à 80.
+
+## C'est pas green
+
+![Ruby Rhod étranglé](static/pas-green.jpg)
+
+## Mais on est devs
+
+Alors on a automatisé tout ce qui pouvait l'être.
+
+::: notes
+
+Pour passer du temps avec ceux qui en ont besoin.
+
+
+# HackInScience.org
+
+C'est un petit Django, avec un peu de celery.
+
+::: notes
+
+Pour répartir les corrections sur des machines qui ne font que ça.
+
+
+## 181 lignes de Python
+
+Ça devrait loger dans quelques slides ;)
+
+::: notes
+
+Aujourd'hui c'est 2700 lignes de code…
+
+
+## Django models
+
+```python
+class Exercise(models.Model):
+ title = models.CharField(max_length=255)
+ wording = models.TextField()
+ check = models.TextField()
+```
+
+## Django view
+
+```python
+class ExerciseListView(LoginRequiredMixin, ListView):
+ model = Exercise
+ template_name = "hkis/exercises.html"
+
+class ExerciseView(LoginRequiredMixin, DetailView):
+ model = Exercise
+ template_name = "hkis/exercise.html"
+```
+
+::: notes
+
+Vous saviez que la MRO de Python garanti un héritage de gauche à droite ?
+
+Ici il est garanti que les méthodes surchargées par `LoginRequiredMixin`
+sont exécutées avant celles de `ListView`.
+
+
+## Une petite API
+
+```python
+class ExerciseSerializer(HyperlinkedModelSerializer):
+ class Meta:
+ model = Exercise
+ fields = '__all__'
+
+class ExerciseViewSet(viewsets.ModelViewSet):
+ queryset = Exercise.objects.all()
+ serializer_class = ExerciseSerializer
+
+router = routers.DefaultRouter()
+router.register('exercises', ExerciseViewSet)
+```
+
+::: notes
+
+Pourquoi un "Router" ? Parce que derrière cette ViewSet il y a plein
+de vues !
+
+Démo time !
+
+## Une interface d'admin
+
+```python
+from django.contrib import admin
+from website.models import Answer, Exercise
+
+admin.site.register(Answer)
+admin.site.register(Exercise)
+```
+
+::: notes
+
+Comme ça on a pu se concentrer sur les exercices et les moulinettes de correction.
+
+# C'est utilisé ?
+
+Je n'ai pas de « pisteur », mais j'ai une DB.
+
+En octobre 2022 : 730 personnes ont résolu 10_780 exercices
+
+La moulinette a corrigé près de 50k rendus.
+
+::: notes
+
+Google Analytics c'est illégal. Mais je sais écrire du SQL.
+
+Aucun tracker, aucune pub, aucun asset externe.
+
+10k c'est peu ou beaucoup, je ne sais pas.
+
+## Ça tient la charge ?
+
+Les exercices sont corrigés en environ 200ms.
+
+Deux serveurs se répartissent le travail.
+
+Les boucles infinies sont interrompues après 20s.
+
+::: notes
+
+Il est très facile d'ajouter un serveur de correction au besoin.
+
+
+## C'est rentable ?
+
+Ren…quoi ? Pardon ?
+
+J'ai pas de « business model », et non mon projet ne va pas « mourir demain » pour autant #sry.
+
+::: notes
+
+Afficher la page des sponsors, remercier les sponsors et Gandi.
+
+En fait c'était rentable jusqu'à ce que j'achète des billets de train pour venir ici :D
+
+
+# Côté sécu
+
+Les rendus sont exécutés côté serveur.
+
+C'est un challenge niveau sécurité.
+
+::: notes
+
+Python est réputé pour ne pas être sandboxable, du moins pas depuis l'intérieur de l'interpréteur.
+
+
+## seccomp
+
+\+ Linux namespaces
+
+\+ rlimit
+
+::: notes
+
+Pourquoi pas Docker ? Pas besoin d'un filesystem complet, juste d'un processus.
+
+# Vu d'un enseignant
+
+::: notes
+
+Vous êtes libres de quitter la salle.
+
+## L'interface d'admin
+
+## Un repo git
+
+Juste pour les exos.
+
+# L'hébergement d'instances locales
+
+Possible, évidement, j'ignore s'il y en a.
+
+# Mot de la fin
+
+Si vous aimez Python, n'oubliez pas la PyConFr !
+
+Du 16 au 19 février 2023 !
+
+# Questions
+
+- Mastodon : [@mdk@mamot.fr](https://mamot.fr/@mdk)
+- XMPP : mdk@chapril.org
+- HTTP : https://mdk.fr
+- SMTP : julien@python.org
+- Whatsapp : HAHAHA jamais.
+- Insta : Et puis quoi encore ?
+- TikTok : SSTTTTOOOOOOOOP !
diff --git a/sphinx-lint.md b/2023-pycon-fr-sphinx-lint.md
similarity index 100%
rename from sphinx-lint.md
rename to 2023-pycon-fr-sphinx-lint.md
diff --git a/Makefile b/Makefile
index fca6090..e6296db 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@ output/%.html: %.md
.PHONY: rsync
rsync: static
- rsync -vah --delete output/ mdk_fr@mdk.fr:/var/www/mdk.fr/$(DEST)/
+ rsync -vah --delete output/ mdk_fr@mdk.fr:/var/www/mdk.fr/talks/
.PHONY: clean
clean:
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..ba94d4b
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+mdtoreveal
diff --git a/static/pas-green.jpg b/static/pas-green.jpg
new file mode 100644
index 0000000..b240ddb
Binary files /dev/null and b/static/pas-green.jpg differ
diff --git a/static/ruby-rhod.jpg b/static/ruby-rhod.jpg
new file mode 100644
index 0000000..a52fc05
Binary files /dev/null and b/static/ruby-rhod.jpg differ