Compare commits
10 Commits
5643df184f
...
c45632067b
Author | SHA1 | Date | |
---|---|---|---|
c45632067b | |||
caf3ee3017 | |||
cad60f2f32 | |||
da952acb46 | |||
482c6741de | |||
e4b78d02ba | |||
56a0c0dc9a | |||
017f782d49 | |||
440452a8fc | |||
86aebaa08c |
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -2,3 +2,6 @@
|
||||||
.venv/
|
.venv/
|
||||||
output/
|
output/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
|
Flex/
|
||||||
|
pelican-plugins/
|
||||||
|
.envrc
|
||||||
|
|
17
Makefile
17
Makefile
|
@ -8,9 +8,9 @@ OUTPUTDIR=$(BASEDIR)/output
|
||||||
CONFFILE=$(BASEDIR)/pelicanconf.py
|
CONFFILE=$(BASEDIR)/pelicanconf.py
|
||||||
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
PUBLISHCONF=$(BASEDIR)/publishconf.py
|
||||||
|
|
||||||
SSH_HOST=51.15.187.166
|
SSH_HOST=mdk.fr
|
||||||
SSH_PORT=22
|
SSH_PORT=22
|
||||||
SSH_USER=mdk_fr
|
SSH_USER=mdk
|
||||||
SSH_TARGET_DIR=/var/www/mdk.fr/
|
SSH_TARGET_DIR=/var/www/mdk.fr/
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,6 @@ help:
|
||||||
@echo ' make serve [PORT=8000] serve site at http://localhost:8000'
|
@echo ' make serve [PORT=8000] serve site at http://localhost:8000'
|
||||||
@echo ' make serve-global [SERVER=0.0.0.0] serve (as root) to $(SERVER):80 '
|
@echo ' make serve-global [SERVER=0.0.0.0] serve (as root) to $(SERVER):80 '
|
||||||
@echo ' make devserver [PORT=8000] serve and regenerate together '
|
@echo ' make devserver [PORT=8000] serve and regenerate together '
|
||||||
@echo ' make ssh_upload upload the web site via SSH '
|
|
||||||
@echo ' make rsync_upload upload the web site via rsync+ssh '
|
@echo ' make rsync_upload upload the web site via rsync+ssh '
|
||||||
@echo ' '
|
@echo ' '
|
||||||
@echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html '
|
@echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html '
|
||||||
|
@ -45,13 +44,16 @@ help:
|
||||||
Flex/.git/config:
|
Flex/.git/config:
|
||||||
git clone --depth 1 https://github.com/alexandrevicenzi/Flex
|
git clone --depth 1 https://github.com/alexandrevicenzi/Flex
|
||||||
|
|
||||||
html: Flex/.git/config
|
pelican-plugins/.git/config:
|
||||||
|
git clone --depth 1 https://github.com/getpelican/pelican-plugins
|
||||||
|
|
||||||
|
html: Flex/.git/config pelican-plugins/.git/config
|
||||||
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
[ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR)
|
[ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR)
|
||||||
|
|
||||||
regenerate: Flex/.git/config
|
regenerate: Flex/.git/config pelican-plugins/.git/config
|
||||||
$(PELICAN) -r $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
$(PELICAN) -r $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||||
|
|
||||||
serve:
|
serve:
|
||||||
|
@ -76,12 +78,9 @@ else
|
||||||
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
$(PELICAN) -lr $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
publish: Flex/.git/config
|
publish: Flex/.git/config pelican-plugins/.git/config
|
||||||
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS)
|
$(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS)
|
||||||
|
|
||||||
ssh_upload: publish
|
|
||||||
scp -P $(SSH_PORT) -r $(OUTPUTDIR)/* $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)
|
|
||||||
|
|
||||||
rsync_upload: publish
|
rsync_upload: publish
|
||||||
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --cvs-exclude $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)
|
rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --cvs-exclude $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)
|
||||||
|
|
||||||
|
|
90
content/blog/2023-01-mobian-black-screen.md
Normal file
90
content/blog/2023-01-mobian-black-screen.md
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
---
|
||||||
|
Title: Black screen at boot on my PinePhone
|
||||||
|
Date: 2023-01-13 09:33:00
|
||||||
|
Summary: My phone was no longer booting…
|
||||||
|
---
|
||||||
|
|
||||||
|
OK so today my [PinePhone](https://fr.wikipedia.org/wiki/PinePhone)
|
||||||
|
does no longer boot, it goes like this:
|
||||||
|
|
||||||
|
- Press power button to boot it,
|
||||||
|
- type rootfs passphrase (I use full disk encryption),
|
||||||
|
- Mobian "spash screen" for a short time,
|
||||||
|
- black screen, and that's it.
|
||||||
|
|
||||||
|
My first bet was a graphical issue due to a recent upgrade ("sweet"
|
||||||
|
memories of Ubuntu failing to start its X server after almost any
|
||||||
|
upgrade...) so I try to ssh to it first... "no route to host", damned!
|
||||||
|
It don't have its IP yet so it failed before network setup.
|
||||||
|
|
||||||
|
But it's a PinePhone, and it runs
|
||||||
|
[Mobian](https://mobian-project.org/), a Debian for mobiles, so I'm
|
||||||
|
not in the dark, let's read the boot logs first before going down the
|
||||||
|
rabbit hole of connecting a UART on the jack port to debug it over
|
||||||
|
serial:
|
||||||
|
|
||||||
|
- Press power button,
|
||||||
|
- type rootfs passphrase again,
|
||||||
|
- press a volume button to get rid of the Mobian splash to see logs
|
||||||
|
|
||||||
|
```text
|
||||||
|
The root filesystem on /dev/mapper/calamares_crypt requires a manual fsck
|
||||||
|
```
|
||||||
|
|
||||||
|
OK!
|
||||||
|
|
||||||
|
Looks easy, but without a keyboard? Let's mount the
|
||||||
|
[eMMC](https://en.wikipedia.org/wiki/MultiMediaCard#eMMC) over USB!
|
||||||
|
|
||||||
|
As my phone boots using [Tow-Boot](https://tow-boot.org/) it's easy:
|
||||||
|
|
||||||
|
- Shut it down (~8s on the power button).
|
||||||
|
- Plug it to laptop with a USB-C cable.
|
||||||
|
- Make it enter "USB Mass Storage mode" (by holding the
|
||||||
|
volume up button at startup before and during the second
|
||||||
|
vibration).
|
||||||
|
- Instantly my laptop sees it and udisks auto mounts it, gnome asks
|
||||||
|
for main partition passphrase to mount it too, nice!
|
||||||
|
- Boom, it disappears... and on `journalctl -e` I see `usb 1-5: device
|
||||||
|
descriptor read/64, error -71` ... `I/O error, dev sda` ...
|
||||||
|
|
||||||
|
At this point I think there's just two options: either my USB-C cable
|
||||||
|
was badly plugged, or my eMMC is dead. I vote for the USB-C cable
|
||||||
|
issue and try again.
|
||||||
|
|
||||||
|
- Rebooting phone in USB mass storage mode again, but this time
|
||||||
|
without giving my passphrase to avoid automount: it
|
||||||
|
needs an fsck anyway.
|
||||||
|
- I can browse `/media/mdk/boot` and see no read error in `sudo journalctl -f`.
|
||||||
|
- `sudo fdisk -l /dev/sda` sees ~30GiB and both partitions.
|
||||||
|
|
||||||
|
|
||||||
|
I use encryption so to fsck the root partition, I have to use `cryptsetup` first:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo cryptsetup open /dev/sda2 mobian # it asks for my passphrase
|
||||||
|
$ file /dev/mapper/mobian # That's the unencrypted view of my partition
|
||||||
|
/dev/mapper/mobian: symbolic link to ../dm-0
|
||||||
|
$ sudo fdisk -l /dev/mapper/mobian # Just out of curiosity
|
||||||
|
Disk /dev/mapper/mobian : 28.47 GiB, 30574379008 octets, 59715584 secteurs
|
||||||
|
$ sudo fsck /dev/mapper/mobian # Running fsck manually!
|
||||||
|
fsck from util-linux 2.38.1
|
||||||
|
e2fsck 1.46.6-rc1 (12-Sep-2022)
|
||||||
|
root contains a file system with errors, check forced.
|
||||||
|
[many many errors]
|
||||||
|
$ sudo mount /dev/mapper/mobian /mnt # To check if it works
|
||||||
|
$ ls /mnt # Yeah!
|
||||||
|
bin boot dev etc home lib lost+found media mnt opt proc root run sbin srv sys tmp usr var
|
||||||
|
$ sudo umount /mnt
|
||||||
|
$ sudo cryptsetup close mobian
|
||||||
|
```
|
||||||
|
|
||||||
|
It looks OK, let's reboot the phone...
|
||||||
|
|
||||||
|
It works!!!
|
||||||
|
|
||||||
|
I know, your grandma would not be able to do fix it that way (mine
|
||||||
|
neither), but I'm still very happy to be able to fix my phone myself
|
||||||
|
when it has issues.
|
||||||
|
|
||||||
|
What would people do when a phone does no longer boot? Buy another?
|
|
@ -140,7 +140,6 @@ Date: 2021-05-05 15:21:00
|
||||||
## Cybersecurity/OSINT
|
## Cybersecurity/OSINT
|
||||||
|
|
||||||
- [The OSINT Framework](https://osintframework.com/)
|
- [The OSINT Framework](https://osintframework.com/)
|
||||||
- [This tool allows you to enumerate usernames across many websites](https://whatsmyname.app/)
|
|
||||||
- [OSINT Tool Comparison Table](https://docs.google.com/spreadsheets/d/18U1qcaPaqIF8ERVLI-g5Or3gUbv0qP_-JUtc0pbEs0E/edit#gid=0)
|
- [OSINT Tool Comparison Table](https://docs.google.com/spreadsheets/d/18U1qcaPaqIF8ERVLI-g5Or3gUbv0qP_-JUtc0pbEs0E/edit#gid=0)
|
||||||
- [Have I been Pwned (« Have them been pwned :D »)](https://haveibeenpwned.com/)
|
- [Have I been Pwned (« Have them been pwned :D »)](https://haveibeenpwned.com/)
|
||||||
- [theHarvester — E-mails, subdomains and names Harvester](https://github.com/laramies/theHarvester)
|
- [theHarvester — E-mails, subdomains and names Harvester](https://github.com/laramies/theHarvester)
|
||||||
|
@ -160,6 +159,12 @@ Date: 2021-05-05 15:21:00
|
||||||
- [MetaGooFil — Metadata Harvester (old, python2)](https://github.com/laramies/metagoofil)
|
- [MetaGooFil — Metadata Harvester (old, python2)](https://github.com/laramies/metagoofil)
|
||||||
- [SpiderFoot — SpiderFoot automates OSINT for threat intelligence and mapping your attack surface.](https://github.com/smicallef/spiderfoot)
|
- [SpiderFoot — SpiderFoot automates OSINT for threat intelligence and mapping your attack surface.](https://github.com/smicallef/spiderfoot)
|
||||||
- [Machinae — Security Intelligence Collector](https://github.com/HurricaneLabs/machinae)
|
- [Machinae — Security Intelligence Collector](https://github.com/HurricaneLabs/machinae)
|
||||||
|
- [Sociétés Françaises](https://annuaire-entreprises.data.gouv.fr)
|
||||||
|
|
||||||
|
### Cybersecurity/OSINT/User enumeration
|
||||||
|
|
||||||
|
- [Whatsmyname — This tool allows you to enumerate usernames across many websites](https://whatsmyname.app/)
|
||||||
|
- [Sherlock — Can be used to find usernames across many social networks](https://sherlock-project.github.io/)
|
||||||
|
|
||||||
|
|
||||||
### Cybersecurity/OSINT/DNS Enumeration
|
### Cybersecurity/OSINT/DNS Enumeration
|
||||||
|
|
108
content/pages/django_isup.md
Normal file
108
content/pages/django_isup.md
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
status: hidden
|
||||||
|
title: Python — Django isup
|
||||||
|
slug: inuik9Ah-django-isup
|
||||||
|
robots: noindex
|
||||||
|
|
||||||
|
|
||||||
|
Le nom du rendu est `isup`, le protocole de rendu est
|
||||||
|
[là](https://mdk.fr/pages/obiree2uaza2sh-rendu.html).
|
||||||
|
|
||||||
|
Le nom du projet Django est libre, l'app Django doit s'appeler `isup`.
|
||||||
|
|
||||||
|
|
||||||
|
## Survol
|
||||||
|
|
||||||
|
Votre projet sera composé de :
|
||||||
|
|
||||||
|
- Au moins deux modèles : `Domain` et `Check`.
|
||||||
|
- Un `Domain` est lié à un `django.contrib.auth.User` (son propriétaire) via une `models.ForeignKey`.
|
||||||
|
- Un `Domain` contient au minimum :
|
||||||
|
- `name` ou `domain` (le nom de domaine),
|
||||||
|
- `is_up` (booléen à True si le site est accessible),
|
||||||
|
- `since` qui indique depuis quand le site est up ou down.
|
||||||
|
- Un `Check` est lié à un domaine (un domaine peut avoir plusieurs checks).
|
||||||
|
- Un `Check` contient au minimum :
|
||||||
|
- La date de vérification,
|
||||||
|
- un booléen `is_up`
|
||||||
|
- un message d'explication comme « HTTPS certificate expired », « Timeout », « Up », ...
|
||||||
|
- Au moins une vue Django pour la page d'accueil.
|
||||||
|
- De quoi [créer un
|
||||||
|
compte](https://docs.djangoproject.com/en/4.0/topics/auth/default/#django.contrib.auth.forms.UserCreationForm)
|
||||||
|
(via Django, pas forcément via l'API), car seuls les utilisateurs
|
||||||
|
loggés peuvent créer des domaines (qui leur appartiendront).
|
||||||
|
- `djangorestframework` pour gérer la sérialisation des modèles, les permissions, les vues d'API, les routes d'API.
|
||||||
|
|
||||||
|
|
||||||
|
## L'API
|
||||||
|
|
||||||
|
Je m'attends à pouvoir utiliser votre API de cette manière :
|
||||||
|
|
||||||
|
```text
|
||||||
|
GET /api/domains/ # Lister tous les domaines connus et leurs état (avec de la pagination si nécessaire).
|
||||||
|
POST /api/domains/ -d '{"domain": "mdk.fr"}' # Pour ajouter un nom de domaine (qui appartient à celui qui fait le POST).
|
||||||
|
GET /api/domains/1/ # Afficher les informations du premier domaine.
|
||||||
|
PUT /api/domains/1/ # Modifier le domaine 1, seulement autorisé si j'en suis propriétaire.
|
||||||
|
DELETE /api/domains/1/ # Supprimer le domaine 1, seulement autorisé si j'en suis propriétaire.
|
||||||
|
GET /api/checks/ # Lister toutes les vérifications qui ont été effectuées.
|
||||||
|
GET /api/checks/?domain=1 # Lister toutes les vérifications effectuées pour le domaine 1.
|
||||||
|
GET /api/checks/1 # Afficher le check d'id 1.
|
||||||
|
```
|
||||||
|
|
||||||
|
Les checks sont en lecture seule, donc pas de `POST`, `PUT`, `DELETE` dessus.
|
||||||
|
|
||||||
|
Si vous voulez que votre API soit REST, la représentation d'un domaine **doit** contenir un lien vers ses `checks` :
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"domain": "mdk.fr",
|
||||||
|
"is_up": true,
|
||||||
|
"checks_url": "http://localhost:8000/uptime/checks/?domain=1",
|
||||||
|
"url": "http://localhost:8000/uptime/domains/1/"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Vérification périodique des domaines connus.
|
||||||
|
|
||||||
|
Vous utiliserez une
|
||||||
|
[Management Command](https://docs.djangoproject.com/en/3.2/howto/custom-management-commands/)
|
||||||
|
pour mettre à jour votre table, c'est là que votre script implémenté en cours sera utile.
|
||||||
|
|
||||||
|
La commande peut s'appeler `check` par exemple. Sur un serveur de
|
||||||
|
prod, le serveur devra l'appeler périodiquement, par exemples toutes
|
||||||
|
les 5mn, via un
|
||||||
|
[timer](https://www.freedesktop.org/software/systemd/man/systemd.timer.html)
|
||||||
|
ou un [cron](https://manpages.debian.org/bullseye/cron/crontab.5.en.html).
|
||||||
|
|
||||||
|
En dev vous pouvez simplement lancer `python manage.py check` à la
|
||||||
|
main de temps en temps.
|
||||||
|
|
||||||
|
Cette commande doit lancer une nouvelle vérification de **tous** les
|
||||||
|
domaines connus, chaque résultat (up ou down) doit être documenté dans
|
||||||
|
le modèle `Checks`.
|
||||||
|
|
||||||
|
|
||||||
|
## La page d'accueil
|
||||||
|
|
||||||
|
La page d'accueil doit être la plus "Django-less" possible :
|
||||||
|
|
||||||
|
- Une simple route.
|
||||||
|
- Une simple vue d'une seule ligne avec `render`.
|
||||||
|
- Un template avec au besoin du HTML, du JS, du CSS mais **pas** de templating Django (pas de `{{`, pas de `{%`).
|
||||||
|
|
||||||
|
Vous êtes autorisés à stocker le JS et le CSS en
|
||||||
|
[statique](https://docs.djangoproject.com/en/4.0/howto/static-files/),
|
||||||
|
mais je n'ai rien contre tout mettre dans le même fichier vu que je
|
||||||
|
suis dev back #sinvergüenza.
|
||||||
|
|
||||||
|
Quand je dis « Django-less » je veux dire que le front doit pouvoir
|
||||||
|
fonctionner en dehors de Django, et que dans un vrai projet avec une
|
||||||
|
équipe *front* et une équipe *back* j'aimerai que cette home, ce JS,
|
||||||
|
et ce CSS puisse être géré dans un autre repo, sans qu'à aucun moment
|
||||||
|
les devs front n'aient besoin de savoir que c'est du Django côté back.
|
||||||
|
|
||||||
|
Vous pouvez donc utiliser le framework front à la mode cette semaine.
|
||||||
|
|
||||||
|
Pour récupérer la liste des noms de domaines et leur état, le front
|
||||||
|
devra donc utiliser l'API. Pas besoin d'être loggé pour ça, on ne
|
||||||
|
modifie rien, on ne fait que consulter, keep it simple stupid.
|
10
content/pages/formations.md
Normal file
10
content/pages/formations.md
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
Title: Formations
|
||||||
|
Date: 2023-01-17 15:41:00
|
||||||
|
|
||||||
|
Développeur Python depuis 2009, formateur Python depuis 2015, je
|
||||||
|
propose ces formations :
|
||||||
|
|
||||||
|
- [Python initiation]({filename}/pages/python-initiation.md)
|
||||||
|
- [Python avancé]({filename}/pages/python-avancé.md)
|
||||||
|
|
||||||
|
Intéressés ? Contactez-moi par email : julien at palard.fr.
|
23
content/pages/index.en.md
Normal file
23
content/pages/index.en.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
Title: Julien Palard
|
||||||
|
Date: 2016-05-28
|
||||||
|
description: Julien Palard - mdk.fr
|
||||||
|
status: hidden
|
||||||
|
lang: en
|
||||||
|
URL:
|
||||||
|
save_as: index.html
|
||||||
|
|
||||||
|
CPython core developer, PSF fellow, independent Python trainer.
|
||||||
|
|
||||||
|
My projects:
|
||||||
|
|
||||||
|
- I build an interactive Python learning tool: [hackinscience.org](https://hackinscience.org/), it's free and [open-source](https://framagit.org/hackinscience/).
|
||||||
|
- I help translating the [Python documentation in French](https://docs.python.org/fr/) (come and help [here](https://github.com/python/python-docs-fr)).
|
||||||
|
- Other projects on [AFPy's gitea](https://git.afpy.org/mdk) and [my github](https://github.com/JulienPalard).
|
||||||
|
|
||||||
|
If you want to get in touch:
|
||||||
|
|
||||||
|
- By email: <a href=mailto:julien@palard.fr>julien@palard.fr</a>.
|
||||||
|
- On [Mastodon](https://joinmastodon.org): [@mdk@mamot.fr](https://mamot.fr/@mdk)
|
||||||
|
- On [IRC](https://web.libera.chat/#python-fr): `mdk`.
|
||||||
|
- Using [XMPP](https://xmpp.chapril.org/i/mdk@chapril.org): <a href=xmpp:mdk@chapril.org>mdk@chapril.org</a>.
|
||||||
|
- Here is My [GPG key](/Julien-Palard.pdf) and my [SSH keys](/id_rsa.pub).
|
|
@ -2,20 +2,22 @@ Title: Julien Palard
|
||||||
Date: 2016-05-28
|
Date: 2016-05-28
|
||||||
description: Julien Palard - mdk.fr
|
description: Julien Palard - mdk.fr
|
||||||
status: hidden
|
status: hidden
|
||||||
|
lang: fr
|
||||||
URL:
|
URL:
|
||||||
save_as: index.html
|
save_as: index.html
|
||||||
|
|
||||||
CPython core developer, PSF fellow, independent Python trainer.
|
Formateur Python indépendant, CPython core developer, PSF fellow.
|
||||||
|
|
||||||
My projects:
|
Mes projets:
|
||||||
|
|
||||||
- I build an interactive Python learning tool: [hackinscience.org](https://hackinscience.org/), it's free and [open-source](https://framagit.org/hackinscience/hkis-website).
|
- Je travaille sur un site d’apprentissage de la programmation interactif : [hackinscience.org](https://hackinscience.org/).
|
||||||
- I help translating the [Python documentation in French](https://docs.python.org/fr/) (come and help [here](https://github.com/python/python-docs-fr)).
|
- J'aide à la traduction de la [documentation de Python en Français](https://docs.python.org/fr/) (pour participer c'est [ici](https://git.afpy.org/AFPy/python-docs-fr)).
|
||||||
- Other projects on [AFPy's gitea](https://git.afpy.org/mdk) and [my github](https://github.com/JulienPalard).
|
- Mes autres projets sont sur la [forge de l'AFPy](https://git.afpy.org/mdk) et sur [mon github](https://github.com/JulienPalard).
|
||||||
|
|
||||||
If you want to get in touch:
|
Pour me contacter :
|
||||||
|
|
||||||
- I'm [@mdk@mamot.fr](https://mamot.fr/@mdk) on [Mastodon](https://joinmastodon.org).
|
- Par email : <a href=mailto:julien@palard.fr>julien@palard.fr</a>.
|
||||||
- I'm `mdk` on [IRC](https://web.libera.chat/#python-fr)
|
- Sur [Mastodon](https://joinmastodon.org) : [@mdk@mamot.fr](https://mamot.fr/@mdk).
|
||||||
- I'm <a href=xmpp:mdk@chapril.org>mdk@chapril.org</a> on [XMPP](https://xmpp.chapril.org/i/mdk@chapril.org).
|
- Sur [irc://libera.chat](https://web.libera.chat/#python-fr) : `mdk`.
|
||||||
- I'm <a href=mailto:julien@palard.fr>julien@palard.fr</a> by email.
|
- Sur [XMPP](https://xmpp.chapril.org/i/mdk@chapril.org) <a href=xmpp:mdk@chapril.org>mdk@chapril.org</a>.
|
||||||
|
- Voilà ma [clé GPG](/Julien-Palard.pdf) et ma [clé SSH](/id_rsa.pub).
|
||||||
|
|
61
content/pages/python-avancé.md
Normal file
61
content/pages/python-avancé.md
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
Title: Python avancé
|
||||||
|
Date: 2023-01-17 15:41:00
|
||||||
|
|
||||||
|
C’est la seconde de mes deux formations Python. Alors que la
|
||||||
|
[formation *initiation*]({filename}/pages/python-initiation.md)
|
||||||
|
enseigne l’utilisation des classes et bibliothèques pour créer des
|
||||||
|
programmes simples, la formation *Python avancé*, de l’autre côté du
|
||||||
|
miroir, enseigne la création de ces classes et bibliothèques pour
|
||||||
|
créer des bibliothèques réutilisables dans des programmes
|
||||||
|
arbitrairement complexes.
|
||||||
|
|
||||||
|
|
||||||
|
## Objectifs
|
||||||
|
|
||||||
|
À la fin de cette seconde formation les stagiaires maîtrisent Python
|
||||||
|
dans l’objectif de produire un code *lisible*, *maintenable*, et
|
||||||
|
*testé* sur tout type de projet.
|
||||||
|
|
||||||
|
L’accent est mis sur le partage et la réutilisation du code :
|
||||||
|
|
||||||
|
- Création de bibliothèque (modules, paquets).
|
||||||
|
- Packaging et distribution de ces bibliothèques.
|
||||||
|
- Gestion des dépendances d’une bibliothèque et d’un l’utilisant.
|
||||||
|
- Test et documentation d’une bibliothèque packagée.
|
||||||
|
|
||||||
|
|
||||||
|
## Prérequis
|
||||||
|
|
||||||
|
Le pré-requis de ce module est d’avoir suivi, ou d’avoir un niveau
|
||||||
|
équivalent, à la formation [Python
|
||||||
|
*initiation*]({filename}/pages/python-initiation.md), c’est-à-dire :
|
||||||
|
être capable de lire et de modifier du Python, être capable de
|
||||||
|
résoudre des problèmes simples en Python.
|
||||||
|
|
||||||
|
|
||||||
|
## Le contenu
|
||||||
|
|
||||||
|
- Les différents protocoles de Python (le protocole d’itération, « les dunder », …).
|
||||||
|
- Les classes et leurs instances (où on parle de la MRO, de `super()`, …).
|
||||||
|
- Le protocole descripteur.
|
||||||
|
- Le *garbage collector*.
|
||||||
|
- Les *floats* et l’IEEE 754.
|
||||||
|
- Créer et gérer les exceptions, le `else` et le `finally` du `try`.
|
||||||
|
- Les gestionnaires de contexte.
|
||||||
|
- Les décorateurs.
|
||||||
|
- Les listes en compréhension.
|
||||||
|
- L’opérateur *walrus* (`:=`).
|
||||||
|
- L’encodage des chaînes de caractères.
|
||||||
|
- Le packaging (`pyproject.toml`, `python -m build`, `twine`, …).
|
||||||
|
- L’asynchrone avec `async` et `await`.
|
||||||
|
|
||||||
|
|
||||||
|
## Durée
|
||||||
|
|
||||||
|
Cette formation se déroule idéalement en cinq jours, mais elle est
|
||||||
|
réalisable en 3 jours.
|
||||||
|
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
Pour en savoir plus, contactez-moi par email : julien at palard.fr.
|
42
content/pages/python-initiation.md
Normal file
42
content/pages/python-initiation.md
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
Title: Python initiation
|
||||||
|
Date: 2023-01-17 15:41:00
|
||||||
|
|
||||||
|
C’est la première des deux formations Python que je propose,
|
||||||
|
accessible sans prérequis.
|
||||||
|
|
||||||
|
|
||||||
|
## Objectifs
|
||||||
|
|
||||||
|
À la fin de cette formation les stagiaires ont les bases de Python et
|
||||||
|
sont capable de produire des programmes simples, de maintenir et faire
|
||||||
|
évoluer des programmes existants.
|
||||||
|
|
||||||
|
- Implémenter un programme simple résolvant un problème bien défini.
|
||||||
|
- Lire, comprendre, et modifier le code d’un autre développeur Python.
|
||||||
|
- Rédiger des tests.
|
||||||
|
|
||||||
|
|
||||||
|
## Le contenu
|
||||||
|
|
||||||
|
- Les types natifs (`bool`, `int`, `float`, `str`, …)
|
||||||
|
- Les opérateurs
|
||||||
|
- Les variables
|
||||||
|
- Les fonctions
|
||||||
|
- Les instructions (`for`, `if`, `while`, …)
|
||||||
|
- Les méthodes
|
||||||
|
- La notation en compréhension
|
||||||
|
- Les *slices*
|
||||||
|
- Les classes
|
||||||
|
- `pip` et les `venvs`
|
||||||
|
- Le packaging
|
||||||
|
- Les bonnes pratiques
|
||||||
|
|
||||||
|
|
||||||
|
## Durée
|
||||||
|
|
||||||
|
Cette formation se déroule idéalement en trois jours.
|
||||||
|
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
Pour en savoir plus, contactez-moi par email : julien at palard.fr.
|
|
@ -4,6 +4,11 @@ status: hidden
|
||||||
|
|
||||||
## Past
|
## Past
|
||||||
|
|
||||||
|
- 2022-11-26:
|
||||||
|
[Campus du Libre](https://www.campus-du-libre.org/): Démo d'HackInScience
|
||||||
|
[video](https://bbb.afpy.org/playback/presentation/2.3/62dfb87e2dfcc5d2947bceb86a2324d10dfdd55b-1669457837244),
|
||||||
|
[slides](https://mdk.fr/hkis-au-campus-du-libre).
|
||||||
|
|
||||||
- 2021-04-15:
|
- 2021-04-15:
|
||||||
[AFPy](https://discuss.afpy.org/t/en-attendant-la-pyconfr-du-15-avril-2021/222/3): Bash — trucs et astuces
|
[AFPy](https://discuss.afpy.org/t/en-attendant-la-pyconfr-du-15-avril-2021/222/3): Bash — trucs et astuces
|
||||||
[video](https://bbb.afpy.org/playback/presentation/2.0/playback.html?meetingId=fb67608c847ace007f60e5b9fa6917ff7040b495-1618502029253).
|
[video](https://bbb.afpy.org/playback/presentation/2.0/playback.html?meetingId=fb67608c847ace007f60e5b9fa6917ff7040b495-1618502029253).
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
|
|
||||||
AUTHOR = "Julien Palard"
|
AUTHOR = "Julien Palard"
|
||||||
SITENAME = "mdk.fr"
|
SITENAME = "mdk.fr"
|
||||||
SITETITLE = "Julien Palard"
|
SITETITLE = "Julien Palard"
|
||||||
|
@ -15,16 +16,48 @@ DISABLE_URL_HASH = True
|
||||||
FAVICON = "/images/favicon.png"
|
FAVICON = "/images/favicon.png"
|
||||||
|
|
||||||
DISPLAY_PAGES_ON_MENU = False
|
DISPLAY_PAGES_ON_MENU = False
|
||||||
MAIN_MENU = False
|
MAIN_MENU = True
|
||||||
|
|
||||||
|
MENUITEMS = (
|
||||||
|
("Formations", "/pages/formations.html"),
|
||||||
|
("Conférences", "/pages/talks.html"),
|
||||||
|
("Articles", "/blog/"),
|
||||||
|
)
|
||||||
|
|
||||||
LINKS = (
|
LINKS = (
|
||||||
("Blog", "/blog/"),
|
|
||||||
("My Talks", "/pages/talks.html"),
|
|
||||||
("My CV", "/Julien-Palard.pdf"),
|
|
||||||
("My SSH keys", "/id_rsa.pub"),
|
|
||||||
("My GPG key", "/pages/gpg.html"),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Social widget
|
||||||
|
SOCIAL = (
|
||||||
|
("mastodon", "https://mamot.fr/@mdk"),
|
||||||
|
("github", "https://github.com/julienpalard"),
|
||||||
|
("stack-overflow", "https://stackoverflow.com/users/232831/julien-palard"),
|
||||||
|
("rss", "/feeds/all.atom.xml"),
|
||||||
|
)
|
||||||
|
|
||||||
|
# Path to Plugins
|
||||||
|
PLUGIN_PATHS = ['pelican-plugins']
|
||||||
|
# Enable i18n plugin, probably you already have some others here.
|
||||||
|
PLUGINS = ['i18n_subsites']
|
||||||
|
# Enable Jinja2 i18n extension used to parse translations.
|
||||||
|
JINJA_ENVIRONMENT = {'extensions': ['jinja2.ext.i18n']}
|
||||||
|
I18N_TEMPLATES_LANG = "en"
|
||||||
|
|
||||||
|
# Match languages for other configs.
|
||||||
|
OG_LOCALE = "fr_FR"
|
||||||
|
LOCALE = ("fr_FR", "fr_FR.utf8")
|
||||||
|
|
||||||
|
# Your language.
|
||||||
|
DEFAULT_LANG = "fr_FR"
|
||||||
|
|
||||||
|
I18N_SUBSITES = {
|
||||||
|
'en': {
|
||||||
|
'SITENAME': 'English Julien Palard',
|
||||||
|
'LOCALE': 'en_US',
|
||||||
|
'THEME_STATIC_DIR': '../theme'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PATH = "content"
|
PATH = "content"
|
||||||
|
|
||||||
TIMEZONE = "Europe/Paris"
|
TIMEZONE = "Europe/Paris"
|
||||||
|
@ -38,27 +71,20 @@ TRANSLATION_FEED_ATOM = None
|
||||||
AUTHOR_FEED_ATOM = None
|
AUTHOR_FEED_ATOM = None
|
||||||
AUTHOR_FEED_RSS = None
|
AUTHOR_FEED_RSS = None
|
||||||
|
|
||||||
THEME_COLOR = "dark"
|
THEME_COLOR = "light"
|
||||||
THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE = True
|
THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE = True
|
||||||
THEME_COLOR_ENABLE_USER_OVERRIDE = True
|
THEME_COLOR_ENABLE_USER_OVERRIDE = False
|
||||||
|
|
||||||
PYGMENTS_STYLE = "emacs"
|
PYGMENTS_STYLE = "emacs"
|
||||||
PYGMENTS_STYLE_DARK = "monokai"
|
PYGMENTS_STYLE_DARK = "monokai"
|
||||||
|
|
||||||
# Social widget
|
|
||||||
SOCIAL = (
|
|
||||||
("mastodon", "https://mamot.fr/@mdk"),
|
|
||||||
("github", "https://github.com/julienpalard"),
|
|
||||||
("stack-overflow", "https://stackoverflow.com/users/232831/julien-palard"),
|
|
||||||
("rss", "/feeds/all.atom.xml"),
|
|
||||||
)
|
|
||||||
|
|
||||||
USE_GOOGLE_FONTS = False
|
USE_GOOGLE_FONTS = False
|
||||||
DEFAULT_PAGINATION = 10
|
DEFAULT_PAGINATION = 10
|
||||||
THEME = "Flex"
|
THEME = "Flex"
|
||||||
THEME_STATIC_DIR = "theme"
|
THEME_STATIC_DIR = "theme"
|
||||||
ARTICLE_URL = "{category}/{slug}.html"
|
ARTICLE_URL = "{category}/{slug}.html"
|
||||||
STATIC_PATHS = ["images"]
|
STATIC_PATHS = ["images"]
|
||||||
|
|
||||||
ARTICLE_SAVE_AS = "{category}/{slug}.html"
|
ARTICLE_SAVE_AS = "{category}/{slug}.html"
|
||||||
CATEGORY_URL = "{slug}/"
|
CATEGORY_URL = "{slug}/"
|
||||||
CATEGORY_SAVE_AS = "{slug}/index.html"
|
CATEGORY_SAVE_AS = "{slug}/index.html"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user