diff --git a/2023-semaine-38.html b/2023-semaine-38.html index b156a47..8ff5a31 100644 --- a/2023-semaine-38.html +++ b/2023-semaine-38.html @@ -68,6 +68,9 @@
  • 🕸️ Un super article qui explique comment fonctionnent les CRDT (Conflit-free Replicated Data Types), de manière très didactique.
  • + diff --git a/2023-semaine-39.html b/2023-semaine-39.html new file mode 100644 index 0000000..570c4a4 --- /dev/null +++ b/2023-semaine-39.html @@ -0,0 +1,74 @@ + + + + + 2023, Semaine 39 - Alexis Métaireau + + + + + + + + + +
    +

    2023, Semaine 39

    +

    Une semaine mi-statique, mi mobile. Difficile de trouver un rythme de travail qui me convienne.

    + + + +
    +
    + +

    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 procrastiné 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

    + +

    Des peines

    + +

    Vu, lu, écouté

    + +
    + + + + + \ No newline at end of file diff --git a/a-distutils2-gsoc.html b/a-distutils2-gsoc.html index e424135..8f83c9e 100644 --- a/a-distutils2-gsoc.html +++ b/a-distutils2-gsoc.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -57,6 +57,9 @@ the PEP

    As I’m relatively new to python, I’ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I’ll post here, each week, my advancement, and my tought about python and especialy python packaging world.

    +
    diff --git a/amap-media-paniers-bio-a-5e.html b/amap-media-paniers-bio-a-5e.html index a398168..45a3446 100644 --- a/amap-media-paniers-bio-a-5e.html +++ b/amap-media-paniers-bio-a-5e.html @@ -62,6 +62,9 @@ d’autres agricultures sont possibles, que la solidarité c’est bien et qu’il est possible de sortir du tout, tout de suite.

    Mais bon, apparemment, ça passe pas bien à la télé.

    + diff --git a/an-amazing-summer-of-code-working-on-distutils2.html b/an-amazing-summer-of-code-working-on-distutils2.html index 00fc8d9..110c407 100644 --- a/an-amazing-summer-of-code-working-on-distutils2.html +++ b/an-amazing-summer-of-code-working-on-distutils2.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -153,6 +153,9 @@ initiative. If you’re a student, if you’re interested about + diff --git a/analyse-users-browsing-context-to-build-up-a-web-recommender.html b/analyse-users-browsing-context-to-build-up-a-web-recommender.html index e0fabc3..607a887 100644 --- a/analyse-users-browsing-context-to-build-up-a-web-recommender.html +++ b/analyse-users-browsing-context-to-build-up-a-web-recommender.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -220,6 +220,9 @@ complete novice in that field.

    Lot of work on its way, yay !

    + diff --git a/antisexisme-ou-antiracisme-un-faux-dilemme.html b/antisexisme-ou-antiracisme-un-faux-dilemme.html index 201c0a4..f5f7963 100644 --- a/antisexisme-ou-antiracisme-un-faux-dilemme.html +++ b/antisexisme-ou-antiracisme-un-faux-dilemme.html @@ -26,7 +26,7 @@
    -

    « Antisexisme ou antiracisme ? Un faux dilemme » par Christine Delphy

    +

    Antisexisme ou antiracisme ? Un faux dilemme
    par Christine Delphy

    @@ -47,6 +47,9 @@ #sexisme, #voile, #racisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/archives.html b/archives.html index 533cbeb..9be6b24 100644 --- a/archives.html +++ b/archives.html @@ -30,6 +30,7 @@
    2023
    +
    2023, Semaine 39
    llm command-line tips
    Setting up a IRC Bouncer with ZNC
    2023, Semaine 38
    @@ -208,6 +209,9 @@
    AMAP + Média = Paniers bio à 5e ?!
    +
    + +
    diff --git a/archlinux-et-mise-a-jour-du-keyring.html b/archlinux-et-mise-a-jour-du-keyring.html index c4daf42..27a8cbd 100644 --- a/archlinux-et-mise-a-jour-du-keyring.html +++ b/archlinux-et-mise-a-jour-du-keyring.html @@ -47,6 +47,9 @@ bien.

    #arch-linux - Posté dans la catégorie code

    +
    + +
    diff --git a/artfevre-2020-defi-artistique-en-fevrier.html b/artfevre-2020-defi-artistique-en-fevrier.html index 7c0fe7a..d187fc5 100644 --- a/artfevre-2020-defi-artistique-en-fevrier.html +++ b/artfevre-2020-defi-artistique-en-fevrier.html @@ -89,6 +89,9 @@ Techniquement ?

    J’ai peur de pas avoir l’inspiration !

    Pour nous, attendre l’inspiration est un prétexte qu’on se donne pour repousser le moment de se mettre au travail. L’inspiration, ça se provoque, ça ne s’attend pas. Et puis peut-être que je trouverai nulle ma création du jour, mais au moins j’aurai fait quelque chose. 1 vaut mieux que 0. Et de ce truc que moi je trouve nul (c’est pas pour ça que c’est nul, à vrai dire), peut-être que j’en tirerai une note que j’aime bien, une formulation qui me plaît, un mouvement que j’adore, et que je ré-utiliserai après dans une autre création. Ou alors, peut-être que je ne retirerai que la satisfaction de l’avoir fait, et c’est déjà pas mal !

    +
    + +
    diff --git a/articles.html b/articles.html index 09e84c8..e4875ea 100644 --- a/articles.html +++ b/articles.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles10.html b/articles10.html index 09e84c8..e4875ea 100644 --- a/articles10.html +++ b/articles10.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles11.html b/articles11.html index 09e84c8..e4875ea 100644 --- a/articles11.html +++ b/articles11.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles12.html b/articles12.html index 09e84c8..e4875ea 100644 --- a/articles12.html +++ b/articles12.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles13.html b/articles13.html index 09e84c8..e4875ea 100644 --- a/articles13.html +++ b/articles13.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles14.html b/articles14.html index 09e84c8..e4875ea 100644 --- a/articles14.html +++ b/articles14.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles15.html b/articles15.html index 09e84c8..e4875ea 100644 --- a/articles15.html +++ b/articles15.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles16.html b/articles16.html index 09e84c8..e4875ea 100644 --- a/articles16.html +++ b/articles16.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles17.html b/articles17.html index 09e84c8..e4875ea 100644 --- a/articles17.html +++ b/articles17.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles18.html b/articles18.html index 09e84c8..e4875ea 100644 --- a/articles18.html +++ b/articles18.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles19.html b/articles19.html index 09e84c8..e4875ea 100644 --- a/articles19.html +++ b/articles19.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles2.html b/articles2.html index 09e84c8..e4875ea 100644 --- a/articles2.html +++ b/articles2.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles20.html b/articles20.html index 09e84c8..e4875ea 100644 --- a/articles20.html +++ b/articles20.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles21.html b/articles21.html index 09e84c8..e4875ea 100644 --- a/articles21.html +++ b/articles21.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles22.html b/articles22.html index 09e84c8..e4875ea 100644 --- a/articles22.html +++ b/articles22.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles23.html b/articles23.html index 09e84c8..e4875ea 100644 --- a/articles23.html +++ b/articles23.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles24.html b/articles24.html index 09e84c8..e4875ea 100644 --- a/articles24.html +++ b/articles24.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles25.html b/articles25.html index 09e84c8..e4875ea 100644 --- a/articles25.html +++ b/articles25.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles26.html b/articles26.html index 09e84c8..e4875ea 100644 --- a/articles26.html +++ b/articles26.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles27.html b/articles27.html index 09e84c8..e4875ea 100644 --- a/articles27.html +++ b/articles27.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles28.html b/articles28.html index 09e84c8..e4875ea 100644 --- a/articles28.html +++ b/articles28.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles29.html b/articles29.html index 09e84c8..e4875ea 100644 --- a/articles29.html +++ b/articles29.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles3.html b/articles3.html index 09e84c8..e4875ea 100644 --- a/articles3.html +++ b/articles3.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles30.html b/articles30.html index 09e84c8..e4875ea 100644 --- a/articles30.html +++ b/articles30.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles31.html b/articles31.html index 09e84c8..e4875ea 100644 --- a/articles31.html +++ b/articles31.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles32.html b/articles32.html index 09e84c8..e4875ea 100644 --- a/articles32.html +++ b/articles32.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles33.html b/articles33.html index 09e84c8..e4875ea 100644 --- a/articles33.html +++ b/articles33.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles34.html b/articles34.html index 09e84c8..e4875ea 100644 --- a/articles34.html +++ b/articles34.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles35.html b/articles35.html index 09e84c8..e4875ea 100644 --- a/articles35.html +++ b/articles35.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles36.html b/articles36.html index 09e84c8..e4875ea 100644 --- a/articles36.html +++ b/articles36.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles37.html b/articles37.html index 09e84c8..e4875ea 100644 --- a/articles37.html +++ b/articles37.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles38.html b/articles38.html index 09e84c8..e4875ea 100644 --- a/articles38.html +++ b/articles38.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles39.html b/articles39.html index 09e84c8..e4875ea 100644 --- a/articles39.html +++ b/articles39.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles4.html b/articles4.html index 09e84c8..e4875ea 100644 --- a/articles4.html +++ b/articles4.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles40.html b/articles40.html index 09e84c8..e4875ea 100644 --- a/articles40.html +++ b/articles40.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles41.html b/articles41.html index 09e84c8..e4875ea 100644 --- a/articles41.html +++ b/articles41.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles42.html b/articles42.html index 09e84c8..e4875ea 100644 --- a/articles42.html +++ b/articles42.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles43.html b/articles43.html index 09e84c8..e4875ea 100644 --- a/articles43.html +++ b/articles43.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles44.html b/articles44.html index 09e84c8..e4875ea 100644 --- a/articles44.html +++ b/articles44.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles45.html b/articles45.html index 09e84c8..e4875ea 100644 --- a/articles45.html +++ b/articles45.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles46.html b/articles46.html index 09e84c8..e4875ea 100644 --- a/articles46.html +++ b/articles46.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles47.html b/articles47.html index 09e84c8..e4875ea 100644 --- a/articles47.html +++ b/articles47.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles48.html b/articles48.html index 09e84c8..e4875ea 100644 --- a/articles48.html +++ b/articles48.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles49.html b/articles49.html index 09e84c8..e4875ea 100644 --- a/articles49.html +++ b/articles49.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles5.html b/articles5.html index 09e84c8..e4875ea 100644 --- a/articles5.html +++ b/articles5.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles50.html b/articles50.html index 09e84c8..e4875ea 100644 --- a/articles50.html +++ b/articles50.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles51.html b/articles51.html index 09e84c8..e4875ea 100644 --- a/articles51.html +++ b/articles51.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles52.html b/articles52.html index 09e84c8..e4875ea 100644 --- a/articles52.html +++ b/articles52.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles53.html b/articles53.html index 09e84c8..e4875ea 100644 --- a/articles53.html +++ b/articles53.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles54.html b/articles54.html index 09e84c8..e4875ea 100644 --- a/articles54.html +++ b/articles54.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles55.html b/articles55.html new file mode 100644 index 0000000..e4875ea --- /dev/null +++ b/articles55.html @@ -0,0 +1,278 @@ + + + + + Alexis Métaireau + + + + + + + + +

    +
    + + + python, llm, bash, sqlite

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    +
    + + + ZNC, Weechat, IRC

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    +
    + + + llm

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    + + + relations, amitié

    Éloge de l’amitié

    + 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. +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    + + + gitlab, docker

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    +
    + + + arch-linux

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + + +
    + +
    + + + + \ No newline at end of file diff --git a/articles6.html b/articles6.html index 09e84c8..e4875ea 100644 --- a/articles6.html +++ b/articles6.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles7.html b/articles7.html index 09e84c8..e4875ea 100644 --- a/articles7.html +++ b/articles7.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles8.html b/articles8.html index 09e84c8..e4875ea 100644 --- a/articles8.html +++ b/articles8.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/articles9.html b/articles9.html index 09e84c8..e4875ea 100644 --- a/articles9.html +++ b/articles9.html @@ -114,6 +114,7 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour

    Avec une utilisation fréquente du système, aucun problème …

    +
    + +
    diff --git a/assurance-chomage.html b/assurance-chomage.html index 0d78271..8fb3a73 100644 --- a/assurance-chomage.html +++ b/assurance-chomage.html @@ -86,6 +86,9 @@
  • Le rechargement des droits à l’indemnisation chômage est repoussé à 6 mois (contre 1 mois avant la réforme) ;
  • +
    + +
    diff --git a/astuces-ssh.html b/astuces-ssh.html index 191e538..537fb95 100644 --- a/astuces-ssh.html +++ b/astuces-ssh.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -59,6 +59,9 @@ PATH=.:\$PATH nc -w1 $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /') hostname ip_serveur_publique+ip_serveur_privé +
    + +
    diff --git a/ateliers-dautodefense-numerique.html b/ateliers-dautodefense-numerique.html index bd9bf59..402b3d4 100644 --- a/ateliers-dautodefense-numerique.html +++ b/ateliers-dautodefense-numerique.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -156,6 +156,9 @@ co-construire avec d’autres des plans de formation.

    Docs. Tous les retours sont évidemment les bienvenus !

    +
    + +
    diff --git a/au-dela-de-la-penetration.html b/au-dela-de-la-penetration.html index fbf71e9..c139bcc 100644 --- a/au-dela-de-la-penetration.html +++ b/au-dela-de-la-penetration.html @@ -26,7 +26,10 @@
    -

    « Au delà de la pénétration » par Martin Page

    +
    + +
    +

    Au delà de la pénétration
    par Martin Page

    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.

    @@ -67,6 +70,9 @@ Le patriarcat règne. Souvent la pénétration reproduit la domination de l̵ #sexualité, #féminisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/author/.html b/author/.html index 311e54c..9da56a7 100644 --- a/author/.html +++ b/author/.html @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html10 b/author/.html10 index 311e54c..9da56a7 100644 --- a/author/.html10 +++ b/author/.html10 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html11 b/author/.html11 index 311e54c..9da56a7 100644 --- a/author/.html11 +++ b/author/.html11 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html12 b/author/.html12 index 311e54c..9da56a7 100644 --- a/author/.html12 +++ b/author/.html12 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html13 b/author/.html13 index 311e54c..9da56a7 100644 --- a/author/.html13 +++ b/author/.html13 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html14 b/author/.html14 index 311e54c..9da56a7 100644 --- a/author/.html14 +++ b/author/.html14 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html15 b/author/.html15 index 311e54c..9da56a7 100644 --- a/author/.html15 +++ b/author/.html15 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html16 b/author/.html16 index 311e54c..9da56a7 100644 --- a/author/.html16 +++ b/author/.html16 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html17 b/author/.html17 index 311e54c..9da56a7 100644 --- a/author/.html17 +++ b/author/.html17 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html18 b/author/.html18 index 311e54c..9da56a7 100644 --- a/author/.html18 +++ b/author/.html18 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html19 b/author/.html19 index 311e54c..9da56a7 100644 --- a/author/.html19 +++ b/author/.html19 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html2 b/author/.html2 index 311e54c..9da56a7 100644 --- a/author/.html2 +++ b/author/.html2 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html20 b/author/.html20 index 311e54c..9da56a7 100644 --- a/author/.html20 +++ b/author/.html20 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html21 b/author/.html21 index 311e54c..9da56a7 100644 --- a/author/.html21 +++ b/author/.html21 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html22 b/author/.html22 index 311e54c..9da56a7 100644 --- a/author/.html22 +++ b/author/.html22 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html23 b/author/.html23 index 311e54c..9da56a7 100644 --- a/author/.html23 +++ b/author/.html23 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html24 b/author/.html24 index 311e54c..9da56a7 100644 --- a/author/.html24 +++ b/author/.html24 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html25 b/author/.html25 index 311e54c..9da56a7 100644 --- a/author/.html25 +++ b/author/.html25 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html26 b/author/.html26 index 311e54c..9da56a7 100644 --- a/author/.html26 +++ b/author/.html26 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html27 b/author/.html27 index 311e54c..9da56a7 100644 --- a/author/.html27 +++ b/author/.html27 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html28 b/author/.html28 index 311e54c..9da56a7 100644 --- a/author/.html28 +++ b/author/.html28 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html29 b/author/.html29 index 311e54c..9da56a7 100644 --- a/author/.html29 +++ b/author/.html29 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html3 b/author/.html3 index 311e54c..9da56a7 100644 --- a/author/.html3 +++ b/author/.html3 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html30 b/author/.html30 index 311e54c..9da56a7 100644 --- a/author/.html30 +++ b/author/.html30 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html31 b/author/.html31 index 311e54c..9da56a7 100644 --- a/author/.html31 +++ b/author/.html31 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html32 b/author/.html32 index 311e54c..9da56a7 100644 --- a/author/.html32 +++ b/author/.html32 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html33 b/author/.html33 index 311e54c..9da56a7 100644 --- a/author/.html33 +++ b/author/.html33 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html34 b/author/.html34 index 311e54c..9da56a7 100644 --- a/author/.html34 +++ b/author/.html34 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html35 b/author/.html35 index 311e54c..9da56a7 100644 --- a/author/.html35 +++ b/author/.html35 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html36 b/author/.html36 index 311e54c..9da56a7 100644 --- a/author/.html36 +++ b/author/.html36 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html37 b/author/.html37 index 311e54c..9da56a7 100644 --- a/author/.html37 +++ b/author/.html37 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html38 b/author/.html38 index 311e54c..9da56a7 100644 --- a/author/.html38 +++ b/author/.html38 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html39 b/author/.html39 index 311e54c..9da56a7 100644 --- a/author/.html39 +++ b/author/.html39 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html4 b/author/.html4 index 311e54c..9da56a7 100644 --- a/author/.html4 +++ b/author/.html4 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html40 b/author/.html40 index 311e54c..9da56a7 100644 --- a/author/.html40 +++ b/author/.html40 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html41 b/author/.html41 index 311e54c..9da56a7 100644 --- a/author/.html41 +++ b/author/.html41 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html42 b/author/.html42 index 311e54c..9da56a7 100644 --- a/author/.html42 +++ b/author/.html42 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html43 b/author/.html43 index 311e54c..9da56a7 100644 --- a/author/.html43 +++ b/author/.html43 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html44 b/author/.html44 index 311e54c..9da56a7 100644 --- a/author/.html44 +++ b/author/.html44 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html45 b/author/.html45 index 311e54c..9da56a7 100644 --- a/author/.html45 +++ b/author/.html45 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html46 b/author/.html46 index 311e54c..9da56a7 100644 --- a/author/.html46 +++ b/author/.html46 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html47 b/author/.html47 index 311e54c..9da56a7 100644 --- a/author/.html47 +++ b/author/.html47 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html48 b/author/.html48 index 311e54c..9da56a7 100644 --- a/author/.html48 +++ b/author/.html48 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html49 b/author/.html49 index 311e54c..9da56a7 100644 --- a/author/.html49 +++ b/author/.html49 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html5 b/author/.html5 index 311e54c..9da56a7 100644 --- a/author/.html5 +++ b/author/.html5 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html50 b/author/.html50 new file mode 100644 index 0000000..9da56a7 --- /dev/null +++ b/author/.html50 @@ -0,0 +1,269 @@ + + + + + Alexis Métaireau - + + + + + + + + +

    +
    + + + python, llm, bash, sqlite

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    +
    + + + ZNC, Weechat, IRC

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    +
    + + + llm

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    + + + gitlab, docker

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    +
    + + + arch-linux

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    +
    + + + python, packaging, zsh

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + + +
    + +
    + + + + \ No newline at end of file diff --git a/author/.html6 b/author/.html6 index 311e54c..9da56a7 100644 --- a/author/.html6 +++ b/author/.html6 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html7 b/author/.html7 index 311e54c..9da56a7 100644 --- a/author/.html7 +++ b/author/.html7 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html8 b/author/.html8 index 311e54c..9da56a7 100644 --- a/author/.html8 +++ b/author/.html8 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/.html9 b/author/.html9 index 311e54c..9da56a7 100644 --- a/author/.html9 +++ b/author/.html9 @@ -120,6 +120,7 @@ discovered hatch

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + +
    diff --git a/author/aude-vidal.html b/author/aude-vidal.html index dc71b85..afa81de 100644 --- a/author/aude-vidal.html +++ b/author/aude-vidal.html @@ -40,6 +40,9 @@
    +
    + +
    diff --git a/author/christine-delphy.html b/author/christine-delphy.html index 767e101..ef235d6 100644 --- a/author/christine-delphy.html +++ b/author/christine-delphy.html @@ -35,6 +35,9 @@
    +
    + +
    diff --git a/author/david-vercauteren.html b/author/david-vercauteren.html index a268796..cfcc228 100644 --- a/author/david-vercauteren.html +++ b/author/david-vercauteren.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/francis-dupuis-deri.html b/author/francis-dupuis-deri.html index 2f29c4f..4a69f5f 100644 --- a/author/francis-dupuis-deri.html +++ b/author/francis-dupuis-deri.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/francoise-verges.html b/author/francoise-verges.html index cc63cb6..8e4511f 100644 --- a/author/francoise-verges.html +++ b/author/francoise-verges.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/geoffroy-de-lagasnerie.html b/author/geoffroy-de-lagasnerie.html index a448217..76ce00a 100644 --- a/author/geoffroy-de-lagasnerie.html +++ b/author/geoffroy-de-lagasnerie.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/harrison-owen.html b/author/harrison-owen.html index ddd254b..b95f1b7 100644 --- a/author/harrison-owen.html +++ b/author/harrison-owen.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/jeremie-cravatte.html b/author/jeremie-cravatte.html index 1b7cad7..250d2e3 100644 --- a/author/jeremie-cravatte.html +++ b/author/jeremie-cravatte.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/jeremie-lefranc.html b/author/jeremie-lefranc.html index adbaca8..e601953 100644 --- a/author/jeremie-lefranc.html +++ b/author/jeremie-lefranc.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/john-stolenberg.html b/author/john-stolenberg.html index b73fc9b..c29c5ea 100644 --- a/author/john-stolenberg.html +++ b/author/john-stolenberg.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.html b/author/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.html index 7c687ab..2d7ae5e 100644 --- a/author/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.html +++ b/author/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/leo-thiers-vidal.html b/author/leo-thiers-vidal.html index 7be5ad5..122b256 100644 --- a/author/leo-thiers-vidal.html +++ b/author/leo-thiers-vidal.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/martin-page.html b/author/martin-page.html index 7321cc2..73f91d5 100644 --- a/author/martin-page.html +++ b/author/martin-page.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/author/peter-gelderloos.html b/author/peter-gelderloos.html index 9263b13..a29eedd 100644 --- a/author/peter-gelderloos.html +++ b/author/peter-gelderloos.html @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/avez-vous-confiance-en-ssl.html b/avez-vous-confiance-en-ssl.html index 1a872be..b4a94b5 100644 --- a/avez-vous-confiance-en-ssl.html +++ b/avez-vous-confiance-en-ssl.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -191,6 +191,9 @@ et interventions du développeur du projet m’ont fait changer d’ Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la bienvenue sur ces sujets!

    +
    + +
    diff --git a/bidouille.html b/bidouille.html index b17de11..65927c4 100644 --- a/bidouille.html +++ b/bidouille.html @@ -74,6 +74,9 @@ compte, m’échappe encore complètement. De l’éducation à la bidou

    Allez, demain c’est fer à souder, piles, leds, interrupteurs, potars et c’est parti !

    +
    + +
    diff --git a/biere-maison.html b/biere-maison.html index ab393e7..6c7f81a 100644 --- a/biere-maison.html +++ b/biere-maison.html @@ -136,6 +136,9 @@ comprendre comment faire pour lui donner la saveur que l’on souhaite, mais c’est déjà un grand pas en avant. Prochaine étape… La bière de Noël !

    +
    + +
    diff --git a/brasserie-du-vieux-singe-installation-en-cours.html b/brasserie-du-vieux-singe-installation-en-cours.html index c1a2afd..a1e5ce1 100644 --- a/brasserie-du-vieux-singe-installation-en-cours.html +++ b/brasserie-du-vieux-singe-installation-en-cours.html @@ -54,6 +54,9 @@ manquent, je ne ferais machine arrière pour rien au monde: je trouve finalement

    Après cette phase assez énorme de réfléxion, de questionnement, de tricotage, de détricotage, de retricotage, j’ai bien envie de passer à l’action; et ça tombe bien, c’est ce qui est à l’horizon. L’idée est d’ouvrir la brasserie à la fin de cette année pour commencer la commercialisation en Janvier 2018. Ça fait un peu peur de voir l’échéance arriver, mais c’est aussi excitant que vertigineux…

    Faire ensemble. Imaginer les choses en petit un peu partout. Collaborer plutôt que se tirer dans les pattes. Renverser la vapeur. Trouver des alliés. Faire levier. Inscrire ses projets dans le temps. C’est peut-être un peu ça, grandir ?

    +
    + +
    diff --git a/break-technologique.html b/break-technologique.html index 18aaec9..507614b 100644 --- a/break-technologique.html +++ b/break-technologique.html @@ -81,6 +81,9 @@

    L’avenir dira ce que j’en fais, mais je suis content d’écrire ça :-)

    +
    + +
    diff --git a/categories.html b/categories.html index b4f4aca..c06b1ad 100644 --- a/categories.html +++ b/categories.html @@ -24,14 +24,24 @@ href="https://blog.notmyidea.org/lectures/">Lectures - + +
    +

    Code, etc.

    +
    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais). 65 articles.
    +

    Journal

    +
    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.. 68 articles.
    +

    Notes de lecture

    +
    Quelques notes prises au détour d'une lecture, plutôt pour ne pas les oublier, et me remémorer le livre quand j'en ai besoin.. 15 articles.
    +

    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.. 13 articles.
    +

    Notes hebdo

    +
    Chaque semaine, je fais un petit résumé de ce qui s'est passé. Cela m'aide à garder le fil de mes idées et de mes différents projets. Un bon moyen de faire un pause et d'observer la semaine sous un autre angle.. 2 articles.
    +
    + + +
    + +
    diff --git a/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html b/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html index 87f6dc2..8734cfa 100644 --- a/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html +++ b/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html @@ -85,6 +85,9 @@ de la lutte – car il y en a et il faut qu’il y en ait – ne seront pas susceptibles de déraper vers une reconduction douce de la domination.»

    — http://lmsi.net/La-non-mixite-une-necessite

    +
    + +
    diff --git a/cheese-code-party-october-20-21.html b/cheese-code-party-october-20-21.html index 8e8f2d3..66d827d 100644 --- a/cheese-code-party-october-20-21.html +++ b/cheese-code-party-october-20-21.html @@ -60,6 +60,9 @@ people will come by will allow me to handle things better), please put information there:

    http://wiki.python.org/moin/ComputerCampAlexis

    +
    + +
    diff --git a/cheese-code-wrap-up.html b/cheese-code-wrap-up.html index d4fe52d..cc41292 100644 --- a/cheese-code-wrap-up.html +++ b/cheese-code-wrap-up.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -139,6 +139,9 @@ use it, really quickly (these examples are how to interact with daybed)

    respective houses and cities.

    Until next time?

    +
    + +
    diff --git a/chiffrement.html b/chiffrement.html index 05af3fa..019ce87 100644 --- a/chiffrement.html +++ b/chiffrement.html @@ -88,8 +88,6 @@ sphère privée ce qui devrait l’être à priori.

    Enigmail et de le configurer correctement. Ce n’est pas très compliqué et permet d’avoir des échanges chiffrés. Référez vous à ce guide pour des instructions pas à pas.

    -

    La clé publique pour me contacter est -0x078805D867F56F12. Et vous ?

    Je vous invite à aller voir le documentaire Citizen Four, qui passe en salles. Si vous ni avez pas accès, vous pouvez le visionner ici, et éventuellement faire un don aux auteurs ou associations qui gravitent @@ -109,6 +107,9 @@ quadrature du net en france ou d’autres…)

    HTML5 video

    +
    + +
    diff --git a/circus-sprint-at-pyconfr.html b/circus-sprint-at-pyconfr.html index 903f714..044ffc7 100644 --- a/circus-sprint-at-pyconfr.html +++ b/circus-sprint-at-pyconfr.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -99,6 +99,9 @@ interesting to everyone.

    feel free to reach us if you’re going there, we’ll be happy to meet and enjoy beers!

    +
    + +
    diff --git a/cloisonnement-des-activites.html b/cloisonnement-des-activites.html index 84e9bf5..a6fb95d 100644 --- a/cloisonnement-des-activites.html +++ b/cloisonnement-des-activites.html @@ -65,6 +65,9 @@ passions pour le reste sont bien vivantes.

    Bref, merci sudweb pour m’avoir accompagné dans ces reflexions, à l’année prochaine, je ramène des futs ?

    +
    + +
    diff --git a/code/index.html b/code/index.html index 56b06ef..16f4960 100644 --- a/code/index.html +++ b/code/index.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Code, etc.

    +

    Code, etc. + +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    @@ -135,8 +137,119 @@ discovered hatch

    +
    + +
    diff --git a/code/index10.html b/code/index10.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index10.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index11.html b/code/index11.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index11.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index12.html b/code/index12.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index12.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index13.html b/code/index13.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index13.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index14.html b/code/index14.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index14.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index15.html b/code/index15.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index15.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index16.html b/code/index16.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index16.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index17.html b/code/index17.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index17.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index18.html b/code/index18.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index18.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index19.html b/code/index19.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index19.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index2.html b/code/index2.html index 56b06ef..16f4960 100644 --- a/code/index2.html +++ b/code/index2.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Code, etc.

    +

    Code, etc. + +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    @@ -135,8 +137,119 @@ discovered hatch

    +
    + +
    diff --git a/code/index20.html b/code/index20.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index20.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index21.html b/code/index21.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index21.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index22.html b/code/index22.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index22.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index3.html b/code/index3.html index 56b06ef..16f4960 100644 --- a/code/index3.html +++ b/code/index3.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Code, etc.

    +

    Code, etc. + +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    @@ -135,8 +137,119 @@ discovered hatch

    +
    + +
    diff --git a/code/index4.html b/code/index4.html index 56b06ef..16f4960 100644 --- a/code/index4.html +++ b/code/index4.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Code, etc.

    +

    Code, etc. + +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    @@ -135,8 +137,119 @@ discovered hatch

    +
    + +
    diff --git a/code/index5.html b/code/index5.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index5.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index6.html b/code/index6.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index6.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index7.html b/code/index7.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index7.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index8.html b/code/index8.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index8.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/code/index9.html b/code/index9.html new file mode 100644 index 0000000..16f4960 --- /dev/null +++ b/code/index9.html @@ -0,0 +1,256 @@ + + + + + Alexis Métaireau + + + + + + + + +

    Code, etc. + +

    +

    Des bouts de trucs liés au code, que je trouve utiles de stocker quelque part (en anglais)

    +
    + +
    + + +

    llm command-line tips

    +

    I’m using llm more and more, and today I had to find back prompts I used in the past. Here is a command I’ve been using, which allows me to filter the results based on what I want. It leverages sql-utils, a cli tool which is able to …

    +
    + python, llm, bash, sqlite
    +
    + + +

    Setting up a IRC Bouncer with ZNC

    +

    It’s been a while since I’ve used IRC, but I needed to connect to it today to discuss around Peewee.

    +

    The main issue with IRC is that you need to be connected to see the answer, and to get the context of the conversation. Unless… you set up …

    +
    + ZNC, Weechat, IRC
    +
    + + +

    How to run the vigogne model locally

    + +

    Vigogne is a LLM model based on LLAMA2, but trained with french data. As I’m working mostly in french, it might be useful. The current models that I can get locally are in english.

    +

    The information I’ve found online are scarse and not so easy to follow, so …

    +
    + llm
    +
    + + +

    Creating a simple command line to post snippets on Gitlab

    + +

    I’m trying to get away from Github, and one thing that I find useful is the gist utility they’re providing. Seems that gitlab provides a similar tool.

    +

    You can use it using python-gitlab:

    +
    pipx install python-gitlab
    +
    + +

    And then :

    +
    gitlab snippet create --title="youpi" --file-name="snip.py" --content snip …
    +
    +
    +
    + + +

    Creating an online space to share markdown files

    + +

    I wanted to create a space on my server where I can upload markdown files and have them rendered directly, for them to be shared with other people.

    +

    I stumbled on the markdown module for nginx which does exactly what I want, but seemed to ask for compilation of nginx …

    +
    +
    +
    + + +

    Conversion d’un fichier svg en favicon.ico

    + +

    Il y a plusieurs sites qui permettent de faire ça automatiquement, mais j’aime bien faire les choses depuis mon terminal, voici donc une commande qui permet de faire ça simplement, en utilisant ImageMagick. Merci à ce gist

    +
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 …
    +
    +
    +
    + + +

    Découverte de nouveaux outils pour le développement: LLM, Helix et plus

    + +

    LLM

    +
      +
    • LocalAI permet de faire tourner des modèles en local avec la même API HTTP que celle d’OpenAI
    • +
    • Le modèle Vigogne est un modèle entrainé (fine-tuned) avec des données en Français. Notamment ce modèlequi prends LLAMA2 en entrée.
    • +
    • LangChain semble être un framework pour travailler avec les différents …
    +
    +
    +
    + + +

    Running the Gitlab CI locally

    + +

    Sometimes, I need to change how the continuous integration is setup, and I find +myself pushing to a branch to test if my changes are working. Oftentimes, it +takes me multiple commits to find the correct configuration, which is… suboptimal.

    +

    I discovered today Gitlab CI +local which makes it possible …

    +
    + gitlab, docker
    +
    + + +

    ArchLinux et mise à jour du keyring

    + +

    Pour les mises à jour Arch, j’utilise yay. Je +ne fais les mises à jour que de manière semi-régulière, et parfois après une +longue période je me retrouve avec des soucis de clé qui ne sont plus à jour ou manquantes.

    +

    Avec une utilisation fréquente du système, aucun problème …

    +
    + arch-linux
    +
    + + +

    Python packaging with Hatch, pipx and Zsh environment variables

    + +

    It’s been a while I didn’t packaged something new. I recently remembered an old +package of mine that needed some attention : +debts. It’s now time to package it, so I +discovered hatch

    +

    hatch new —init

    +

    This does the heavy-lifting for you, actually porting the setup.py files …

    +
    + python, packaging, zsh
    + +
    +
    + +
    + + + + \ No newline at end of file diff --git a/comment-est-ce-que-vous-generez-vos-formulaires.html b/comment-est-ce-que-vous-generez-vos-formulaires.html index d77b902..59cd9f5 100644 --- a/comment-est-ce-que-vous-generez-vos-formulaires.html +++ b/comment-est-ce-que-vous-generez-vos-formulaires.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -118,6 +118,9 @@ ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez su

    Bref, en espérant que ça vous serve ! Un petit pas dans la direction des données rendues à leurs utilisateurs !

    +
    + +
    diff --git a/comment-la-non-violence-protege-letat.html b/comment-la-non-violence-protege-letat.html index 8d008a1..3d19b7b 100644 --- a/comment-la-non-violence-protege-letat.html +++ b/comment-la-non-violence-protege-letat.html @@ -26,7 +26,10 @@
    -

    « Comment la non-violence protège l’état » par Peter Gelderloos

    +
    + +
    +

    Comment la non-violence protège l’état
    par Peter Gelderloos

    Essai sur l'inefficacité des mouvements sociaux

    @@ -46,6 +49,9 @@ L’histoire pacifiste de la lutte indienne ne peut rendre compte du fait que Su #non-violence, #anarchisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/conflit.html b/conflit.html index f617d9a..297d3c0 100644 --- a/conflit.html +++ b/conflit.html @@ -44,6 +44,9 @@ #Savoir-Être, #Coopération, #Conflit - Posté dans la catégorie journal

    +
    + +
    diff --git a/conversion-dun-fichier-svg-en-faviconico.html b/conversion-dun-fichier-svg-en-faviconico.html index a8edbaf..c54c908 100644 --- a/conversion-dun-fichier-svg-en-faviconico.html +++ b/conversion-dun-fichier-svg-en-faviconico.html @@ -37,6 +37,9 @@
    convert -density 256x256 -background transparent favicon.svg -define icon:auto-resize -colors 256 favicon.ico
     
    +
    + +
    diff --git a/cooperation-et-travail.html b/cooperation-et-travail.html index 2efd2bb..d6ae630 100644 --- a/cooperation-et-travail.html +++ b/cooperation-et-travail.html @@ -54,6 +54,9 @@ #Coopération, #Travail - Posté dans la catégorie journal

    +
    + +
    diff --git a/creating-a-simple-command-line-to-post-snippets-on-gitlab.html b/creating-a-simple-command-line-to-post-snippets-on-gitlab.html index cf41f4c..0fc2526 100644 --- a/creating-a-simple-command-line-to-post-snippets-on-gitlab.html +++ b/creating-a-simple-command-line-to-post-snippets-on-gitlab.html @@ -68,6 +68,9 @@

    I can now do snip README.md and that will create the snippet for me :-)

    +
    + +
    diff --git a/creating-an-online-space-to-share-markdown-files.html b/creating-an-online-space-to-share-markdown-files.html index f91f9f3..c7420ba 100644 --- a/creating-an-online-space-to-share-markdown-files.html +++ b/creating-an-online-space-to-share-markdown-files.html @@ -70,6 +70,9 @@

    This is a minimalistic version, but it works :-)

    +
    + +
    diff --git a/crucial-conversations.html b/crucial-conversations.html index 67ab1eb..ad4c716 100644 --- a/crucial-conversations.html +++ b/crucial-conversations.html @@ -26,7 +26,10 @@
    -

    « Crucial Conversations » par Kerry Patterson, Stephen R. Covey, Joseph Grenny, Ron McMillan et Al Switzler

    +
    + +
    +

    Crucial Conversations
    par Kerry Patterson, Stephen R. Covey, Joseph Grenny, Ron McMillan et Al Switzler

    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.

    @@ -98,18 +101,22 @@
  • Clarifiez ce que vous voulez réellement : pour vous, pour les autres, et pour la relation.
  • 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.

    +

    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.
    • +

    Décider De Ses Histoires

    Les histoires créent des émotions. Les émotions n’arrivent pas d’elles-mêmes, et sont liées à des histoires qu’on se raconte.

    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 -4. Agir

    +

    Le schéma peut être le suivant :

    +
      +
    1. Voir et entendre (les faits)
    2. +
    3. Se raconter une histoire
    4. +
    5. Ressentir
    6. +
    7. Agir
    8. +

    Partie 2 : Comment Ouvrir la Bouche

    Apprendre à Regarder

    Comment se rendre compte que la sécurité est mise en jeu ? Il faut apprendre à regarder et à capter les signes. Quand une conversation devient stressante, on a tendance à faire les mauvaises choses. Apprenez à regarder :

    @@ -122,17 +129,21 @@

    Sécuriser la Conversation

    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 ?

    +

    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 ?
    • +

    Pour commencer la discussion, partagez vos bonnes intentions : qu’est-ce que vous voulez ? Pour vous et pour l’autre personne ?

    Excusez-vous lorsque c’est approprié.

    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 -- Brainstormez les nouvelles stratégies

    +

    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
    • +
    • Brainstormez les nouvelles stratégies
    • +

    Décrire Sa Vision Des Choses

    Comprendre Les Visions Des Autres

    Écouter

    @@ -141,6 +152,9 @@

    Oui mais…

    Trucs Et Astuces

    +
    + +
    diff --git a/de-mozilla-a-la-brasserie-du-vieux-singe.html b/de-mozilla-a-la-brasserie-du-vieux-singe.html index 046ba1f..216d4bb 100644 --- a/de-mozilla-a-la-brasserie-du-vieux-singe.html +++ b/de-mozilla-a-la-brasserie-du-vieux-singe.html @@ -58,6 +58,9 @@ Dans nos pratiques courantes, on décide d’intégrer du temps pour documen

    Et, si je n’avais pas réduit mon temps de travail, j’aurais peut-être loupé la découverte de ce nouveau monde, celui qui me passionne aujourd’hui.

    Alors je vous invite à vous poser la question — indispensable — de vos valeurs: qu’est-ce que vous souhaitez faire ? Qu’est-ce qui vous anime ? Et peut-être à aménager du temps pour explorer vos envies.

    +
    + +
    diff --git a/decouverte-de-nouveaux-outils-pour-le-developpement-llm-helix-et-plus.html b/decouverte-de-nouveaux-outils-pour-le-developpement-llm-helix-et-plus.html index c19202c..519ac4d 100644 --- a/decouverte-de-nouveaux-outils-pour-le-developpement-llm-helix-et-plus.html +++ b/decouverte-de-nouveaux-outils-pour-le-developpement-llm-helix-et-plus.html @@ -82,6 +82,9 @@ git diff |<

    J’aime beaucoup ce que ça dit. Faire confiance est peut-être nécessaire, même si on est déçu au final, on aura au moins appris. Ça me touche.

    +
    + +
    diff --git a/des-carnets-desquisse.html b/des-carnets-desquisse.html index bfaed48..d30850a 100644 --- a/des-carnets-desquisse.html +++ b/des-carnets-desquisse.html @@ -43,7 +43,7 @@ que je veux me garder de coté, des pensées que je souhaite partager… Un endroit ou je peux venir écrire quelque chose et le compléter plus tard.

    Du coup, le flux Atom contiens désormais quelques notes sur des sujets variés. Ces notes ne sont pas relayées sur la page d’accueil, mais vous -pouvez les trouver dans la section notes.

    +pouvez les trouver dans la section notes.

    Je ne sais pas encore si il s’agit du meilleur endroit pour ça, mais peu importe, essayons. A bas la pudeur rédactionelle.

    J’ai du au passage chambouler un peu vos agrégateurs, pardonnez moi :)

    @@ -62,6 +62,9 @@ ce service sur discus.notmyidea.org, ou d’utiliser Daybed pour faire la même chose, mais faut il encore que je le fasse, alors en attendant, j’ai réactivé disqus ici! (Le mieux est l’ennemi du bien, paraît il !)

    +
    + +
    diff --git a/des-profils-de-confiance-partout-et-pour-tout.html b/des-profils-de-confiance-partout-et-pour-tout.html index 3ad7518..040feba 100644 --- a/des-profils-de-confiance-partout-et-pour-tout.html +++ b/des-profils-de-confiance-partout-et-pour-tout.html @@ -69,6 +69,9 @@ partager le prix d’un trajet avec quelqu’un, c’est bien d̵ maintenant cela serait rendu accessible à tous grâce à “l’intelligence collective”; gommant au passage les différences de valeur; Préférant éviter de rencontrer les inconnus aux profils “légers”.

    Je sais pas vous, mais elle me fait peur cette idée.

    +
    + +
    diff --git a/djangocong-2012.html b/djangocong-2012.html index bdad1de..ea74869 100644 --- a/djangocong-2012.html +++ b/djangocong-2012.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -98,6 +98,9 @@ brasucade …

    Bref, vivement la prochaine (et allez, cette fois ci je ferais une présentation !)

    +
    + +
    diff --git a/drafts/accueil-transmission-et-confiance.html b/drafts/accueil-transmission-et-confiance.html index 3af27cf..138b28c 100644 --- a/drafts/accueil-transmission-et-confiance.html +++ b/drafts/accueil-transmission-et-confiance.html @@ -78,6 +78,9 @@ +
    + +
    diff --git a/drafts/fermentation-en-futs.html b/drafts/fermentation-en-futs.html index 3766870..7ed8892 100644 --- a/drafts/fermentation-en-futs.html +++ b/drafts/fermentation-en-futs.html @@ -41,6 +41,9 @@ je trouve que l’embouteillage est souvent difficile,

    e me retrouve souvent avec des

    +
    + +
    diff --git a/drafts/les-illusions-liberales-individualisme-et-pouvoir-social.html b/drafts/les-illusions-liberales-individualisme-et-pouvoir-social.html index 4ac6940..cc1360d 100644 --- a/drafts/les-illusions-liberales-individualisme-et-pouvoir-social.html +++ b/drafts/les-illusions-liberales-individualisme-et-pouvoir-social.html @@ -26,7 +26,7 @@
    -

    « Les illusions libérales, individualisme et pouvoir social » par Jean-léon Beauvois

    +

    Les illusions libérales, individualisme et pouvoir social
    par Jean-léon Beauvois

    Petit traité des grandes illusions

    @@ -40,6 +40,9 @@ #libéralisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/dynamically-change-your-gnome-desktop-wallpaper.html b/dynamically-change-your-gnome-desktop-wallpaper.html index 7a29e60..19322a1 100644 --- a/dynamically-change-your-gnome-desktop-wallpaper.html +++ b/dynamically-change-your-gnome-desktop-wallpaper.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -83,6 +83,9 @@ $ pip install gnome-background-generator -b, --debug +
    + +
    diff --git a/eco-systeme-et-stockage-generique.html b/eco-systeme-et-stockage-generique.html index 7bc67dd..1f9e2a4 100644 --- a/eco-systeme-et-stockage-generique.html +++ b/eco-systeme-et-stockage-generique.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -353,6 +353,9 @@ Cloud Services!

    Storage. +
    + +
    diff --git a/ecran-et-dependances.html b/ecran-et-dependances.html index 7663c23..77abe04 100644 --- a/ecran-et-dependances.html +++ b/ecran-et-dependances.html @@ -37,6 +37,9 @@

    Il y a quelques mois, j’ai choisi de ne pas avoir d’ordinateur à la maison durant une semaine. Résultat ? Je me suis remis à lire ! Depuis, j’essaye de reproduire quelque chose de similaire, mais me retrouve face à un triste constat : je suis drogué.

    Les écrans sont trop présents. Comment faire sans eux ? Comment limiter leur pouvoir sur mon temps ? Que de questions :-)

    +
    + +
    diff --git a/egologie.html b/egologie.html index 6e32b18..fec9969 100644 --- a/egologie.html +++ b/egologie.html @@ -26,7 +26,10 @@
    -

    « Égologie » par Aude Vidal

    +
    + +
    +

    Égologie
    par Aude Vidal

    Écologie, individualisme et course au bonheur

    @@ -51,6 +54,9 @@ #écologie, #développement-personnel - Posté dans la catégorie lectures

    +
    + +
    diff --git a/elitisme-et-apprentissage.html b/elitisme-et-apprentissage.html index 6f6186b..9d7cfa7 100644 --- a/elitisme-et-apprentissage.html +++ b/elitisme-et-apprentissage.html @@ -42,6 +42,9 @@

    Rester dans une position de sachant semble me pousser à des comportements de fermeture d’esprit. La « sagesse » serait-elle la faculté à se remettre en question ? Mais quid des « fausses vérités » et des avis de surface, de ce que l’on croit connaître ?

    Peut-être que la solution est de connaître mes limites, ou en tout cas de les rechercher et de reconnaître mes zones de flou.

    +
    + +
    diff --git a/eloge-de-lamitie.html b/eloge-de-lamitie.html index fc42a3a..0001011 100644 --- a/eloge-de-lamitie.html +++ b/eloge-de-lamitie.html @@ -26,7 +26,10 @@
    -

    « Éloge de l’amitié » par Geoffroy de Lagasnerie

    +
    + +
    +

    Éloge de l’amitié
    par Geoffroy de Lagasnerie

    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.

    @@ -148,6 +151,9 @@ L’intérêt, c’est ce qui est entre soi et soi (ce qui nous aug #relations, #amitié - Posté dans la catégorie lectures

    +
    + +
    diff --git a/facebook-competition-ethique-et-marketing.html b/facebook-competition-ethique-et-marketing.html index f241ec4..62c9108 100644 --- a/facebook-competition-ethique-et-marketing.html +++ b/facebook-competition-ethique-et-marketing.html @@ -56,6 +56,9 @@

    Cela fait maintenant un an et demi que je suis ces quelques règles, et je pense que les effets délétères du média social se tassent ;-)

    +
    + +
    diff --git a/faire-de-la-musique-sous-linux.html b/faire-de-la-musique-sous-linux.html index 154cf9f..bbc51ee 100644 --- a/faire-de-la-musique-sous-linux.html +++ b/faire-de-la-musique-sous-linux.html @@ -122,6 +122,9 @@ wine Kontakt\_patchUn outil pour faire un scan des problèmes de perf connus +
    + +
    diff --git a/faire-moins.html b/faire-moins.html index 4481861..9f23fc2 100644 --- a/faire-moins.html +++ b/faire-moins.html @@ -38,6 +38,9 @@

    Enfin ! Je retrouve ce précieux temps. Je retrouve ces moments d’ennui. Oui, je comprends bien que ça puisse parraître fou de voir quelqu’un se réjouir de son ennui… Cet ennui me permet de creuser de nouvelles idées, de reprendre ce bouquin qu’on avait laissé tomber sans trop de raison.

    Et surtout, c’est se retrouver à contrôler son engagement.

    +
    + +
    diff --git a/fatigue-et-competition.html b/fatigue-et-competition.html index 8714d94..a4b3bc1 100644 --- a/fatigue-et-competition.html +++ b/fatigue-et-competition.html @@ -40,6 +40,9 @@

    Lorsque je décèle que je rentre en compétition, je cherche à changer ma posture : je demande des précisions à mon interlocut⋅eur⋅rice plutôt que d’y opposer une connaissance que je pense détenir (voire même que je créé parfois sur le moment ?).

    Ça me renvoie au fait qu’il me semble mieux de ne pas savoir, plutôt que d’affirmer quelque chose dont je ne suis pas pas certain (même avec aplomb).

    +
    + +
    diff --git a/fatigue-relationnelle.html b/fatigue-relationnelle.html index 9006f36..3624da1 100644 --- a/fatigue-relationnelle.html +++ b/fatigue-relationnelle.html @@ -43,6 +43,9 @@ #Coopération, #Savoir-Être, #Fatigue, #Conflit - Posté dans la catégorie journal

    +
    + +
    diff --git a/feeds/.atom.xml b/feeds/.atom.xml index 17e1750..7a29907 100644 --- a/feeds/.atom.xml +++ b/feeds/.atom.xml @@ -1,5 +1,39 @@ -Alexis Métaireauhttps://blog.notmyidea.org/2023-09-27T00:00:00+02:00llm command-line tips2023-09-27T00:00:00+02:002023-09-27T00:00:00+02:00tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p><p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to talk to a <span class="caps">SQLITE</span> database and answer in json, and <a href="https://github.com/jqlang/jq">jq</a> a command-line tool capable of doing requests for&nbsp;json.</p> +Alexis Métaireauhttps://blog.notmyidea.org/2023-09-29T00:00:00+02:002023, Semaine 392023-09-29T00:00:00+02:002023-09-29T00:00:00+02:00tag:blog.notmyidea.org,2023-09-29:/2023-semaine-39.html +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques …</dd></dl> +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques, pour finalement en changer et me questionner sur la partie <strong>metier</strong>, ce qui me semblait plus intéressant. A partir du moment où j&#8217;ai arrêté d&#8217;essayer d&#8217;appliquer une solution « déjà faite » j&#8217;ai pu me questionner sur le modèle de données et aller de l&#8217;avant. Étrangement c&#8217;est quand j&#8217;ai produit le moins de code que j&#8217;ai trouvé que j&#8217;étais le plus&nbsp;productif.</dd> +<dt>Notmyidea</dt> +<dd>Je n&#8217;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&nbsp;décider.</dd> +<dd>J&#8217;ai <del>procrastiné</del> passé beaucoup plus de temps que prévu sur la mise en place d&#8217;outils utiles pour moi, et à peaufiné mon site web. J&#8217;ai maintenant un bouncer <span class="caps">ZNC</span> et un <span class="caps">VPN</span> fait maison qui me permettent de travailler dans de meilleures conditions. Je suis à la fois content d&#8217;avoir pris le temps de mettre en place des outils, et en même temps j&#8217;ai une impression de&nbsp;procrastination.</dd> +</dl> +<h2 id="des-joies">Des&nbsp;joies</h2> +<ul> +<li>Avoir pris le temps d&#8217;aller « à la ville » pour passer du temps avec des amis et&nbsp;sociabiliser.</li> +<li>M&#8217;écouter et décider de dormir sur place pour travailler aussi sur Rennes le&nbsp;lendemain.</li> +<li>Aller à l&#8217;espace de coworkig à côté de chez&nbsp;moi.</li> +<li>Prendre le temps de faire des choses peu importantes entassées dans ma todolist depuis trop&nbsp;longtemps.</li> +<li>Récolter des fruits de discussions passées lors d&#8217;une soirée. Vive les todo-list&nbsp;!</li> +<li>Voir qu&#8217;une demande de modifications que j&#8217;ai faite soit appréciée et intégrée&nbsp;rapidement.</li> +<li>Dépanner le serveur de <a href="https://github.com/almet/copanier">copanier</a>, trouver le problème rapidement et le régler&nbsp;facilement.</li> +</ul> +<h2 id="des-peines">Des&nbsp;peines</h2> +<ul> +<li>Je suis retombé malade en fin de semaine, et donc bien fatigué. Ca impacte mon moral et ma capacité de&nbsp;concentration.</li> +<li>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&nbsp;autres.</li> +<li>Sentir que ma posture dans les conversations est plus ferme que par le passé. Je suis à la fois content de ne pas <strong>toujours</strong> me remettre en question, mais j&#8217;aimerai réussir à faire preuve de plus d&#8217;ouverture. Il faut trouver&nbsp;l&#8217;équilibre </li> +<li>Triste de voir des conflits escalader alors que ça pourrait être&nbsp;autrement.</li> +</ul> +<h2 id="vu-lu-ecoute">Vu, lu,&nbsp;écouté</h2> +<ul> +<li>🎮 J&#8217;ai continué <a href="https://fr.wikipedia.org/wiki/Baba_Is_You">Baba is you</a> avec Arthur. C&#8217;était sympa de se faire les reflexions à deux&nbsp;cerveaux.</li> +<li>▶︎ <a href="https://www.youtube.com/watch?app=desktop&amp;v=dVzfNZN9NKI&amp;list=PL8uoeex94UhFcwvAfWHybD7SfNgIUBRo-&amp;index=128">Vu une présentation sur DuckDB</a>, une base de données locale et minimaliste qui semble adaptée pour de la visualisation de données à grande&nbsp;échelle.</li> +</ul>llm command-line tips2023-09-27T00:00:00+02:002023-09-27T00:00:00+02:00tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p><p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to talk to a <span class="caps">SQLITE</span> database and answer in json, and <a href="https://github.com/jqlang/jq">jq</a> a command-line tool capable of doing requests for&nbsp;json.</p> <p>All in all, it&#8217;s pretty satisfying to use. I finally got a simple way to query databases! I&#8217;m also using <a href="https://github.com/charmbracelet/glow">glow</a>, which is capable of transforming markdown into a better version on the&nbsp;terminal.</p> <div class="highlight"><pre><span></span><code>sqlite-utils<span class="w"> </span><span class="s2">&quot;</span><span class="k">$(</span>llm<span class="w"> </span>logs<span class="w"> </span>path<span class="k">)</span><span class="s2">&quot;</span><span class="w"> </span><span class="s2">&quot;SELECT * FROM responses WHERE prompt LIKE &#39;%search%&#39;&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>jq<span class="w"> </span><span class="s1">&#39;.[].response&#39;</span><span class="w"> </span>-r<span class="w"> </span><span class="p">|</span><span class="w"> </span>glow </code></pre></div> @@ -755,7 +789,7 @@ sudo<span class="w"> </span>/bin/systemctl<span class="w"> < <div class="highlight"><pre><span></span><code>sudo certbot --nginx </code></pre></div> -<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Réveil difficile2022-05-30T00:00:00+02:002022-05-30T00:00:00+02:00tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p><p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente, venaient de&nbsp;bouger.</p> +<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Réveil difficile2022-05-30T00:00:00+02:002022-05-30T00:00:00+02:00tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p><p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente, venaient de&nbsp;bouger.</p> <p>Comme si je sortais d&#8217;un ensorcellement, que mon comportement — ma perception, même — avaient étés durant des années différents, et que, enfin, je me réveillais. Avec un arrière-goût amer dans le fond du&nbsp;palais.</p> <p>L&#8217;incantation ne commençait pas : ses effets finissaient par disparaître. Comme sorti du brouillard, une certitude : bien que je n&#8217;étais pas le seul à réaliser le sort qui m&#8217;avait été réservé, beaucoup d&#8217;autres n&#8217;en avaient pas du tout conscience. Voire même : ceux qui n&#8217;en avaient pas conscience semblaient évoluer dans ce qui me semblait maintenant une béatitude <em>malaisante</em>.</p> <p>Certain⋅e⋅s s&#8217;injectaient même volontairement des <em>doses</em> de cette <em>potion</em> pour que le brouillard ne se dissipe pas. Et je comprends pourquoi : les effets sont puissants, ils rendent les frontières lisses, colorent les interstices, remplacent les malaises par des joies&nbsp;candides.</p> @@ -1772,9 +1806,9 @@ L&#8217;avantage de ce matériel c&#8217;est que c&#8217;est la < <p>Et quand on passe des tests à l’échelle, (de 20L à 1500L), on est moyennement rassurés&nbsp;!</p> <p>Après quelques brassins validés, on est un peu plus relax sur le sujet, et on a mis en place de quoi faire des expérimentations à petite échelle de manière simple : vu qu&#8217;on produit du moût toutes les semaines, on en utilise une partie pour faire quelques tests : changement de levure, adjonctions, changement des températures de fermentation,&nbsp;etc.</p> <p>Ah ça, c’est pas les idées qui nous manquent :-) Et c&#8217;est une super manière&nbsp;d&#8217;expérimenter.</p> -<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/experimentations/sobacha.png"></p> -<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/experimentations/monstrueuse-normalite.png"></p> -<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/experimentations/chainon-manquant.png"></p> +<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/un-an/sobacha.png"></p> +<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/un-an/monstrueuse-normalite.png"></p> +<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/un-an/chainon-manquant.png"></p> <h2 id="ouverture-au-public-evenements-et-equilibre">Ouverture au public, évènements et&nbsp;équilibre</h2> <p>On a pris le parti d&#8217;ouvrir le magasin toutes les fins de semaine (le jeudi et vendredi de 17h à 19h) et on est hyper contents de faire visiter la brasserie aux personnes qui passent de temps à autre. Pour nous, ça fait partie des plaisirs du métier. Par contre, on avait clairement sous estimé le temps que ça nous prendrait. On accueille beaucoup et les gens sont curieux. La fabrication de bière reste encore aujourd’hui quelque chose de nouveau pour la plupart, et il faut satisfaire cette curiosité (il faut plus de brasseries&nbsp;!).</p> <p>Ce qui se passe en ce moment sur la scène brassicole est génial : beaucoup de nouvelles brasseries proposent des produits exceptionnels, et les évènements se multiplient aux quatre coins de la France. On adore partager, goûter, discuter, mais on ne pensait pas être autant sollicités par des évènements extérieurs, souvent sur des week-end, et parfois loin. <strong>On souhaite garder un équilibre entre notre vie personnelle et notre vie professionnelle</strong>. Aller aux évènements aussi par plaisir. Être partout est probablement un des maux de notre temps ;-) À force de voir des brasseurs exténués, il y a de quoi se poser des questions sur la pérennité sur le long terme d’un rythme aussi&nbsp;effréné.</p> @@ -1868,7 +1902,7 @@ paiements s&#8217;effectuent directement entre&nbsp;nous.</p> <li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des&nbsp;chèques</a></li> <li><a href="https://docs.google.com/spreadsheets/d/1bnPRSvf2Q2RDxKerWnEqUyJjuCFePnVMq6pWo8LeA_k/edit?usp=sharing">une version « à remplir » de notre tableau de commandes</a> (le mieux est d&#8217;en faire une copie&nbsp;!).</li> </ul> -<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> +<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> <ul> <li>enregistrer une sélection de texte ainsi que son contexte: heure, site&nbsp;web.</li> <li>fonctionner sur&nbsp;Firefox;</li> @@ -1879,7 +1913,7 @@ paiements s&#8217;effectuent directement entre&nbsp;nous.</p> <p>J&#8217;ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j&#8217;ai baptisé « Webnotes ». C&#8217;est <a href="https://addons.mozilla.org/en-US/firefox/addon/wwebnotes/">une extension Firefox</a>, qui se configure assez simplement, et qui stocke les données dans une instance de <a href="http://kinto-storage.org/">Kinto</a>.</p> <p><img src="https://github.com/almet/webnotes/blob/master/webnotes.gif?raw=true" /></p> <p>C&#8217;est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué&nbsp;!</p> -<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Faire moins2018-01-25T00:00:00+01:002018-01-25T00:00:00+01:00tag:blog.notmyidea.org,2018-01-25:/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p><p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser un sujet en particulier) est l&#8217;occasion de contribuer à éviter notre société&nbsp;d&#8217;experts.</p> +<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Faire moins2018-01-25T00:00:00+01:002018-01-25T00:00:00+01:00tag:blog.notmyidea.org,2018-01-25:/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p><p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser un sujet en particulier) est l&#8217;occasion de contribuer à éviter notre société&nbsp;d&#8217;experts.</p> <p>Le hic, c&#8217;est que trop, c&#8217;est trop. J&#8217;ai donc décidé d&#8217;arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j&#8217;ai même arreté de faire des choses que j&#8217;avais commencé à faire (par exemple de l&#8217;escalade), me libérant du&nbsp;temps.</p> <p>Enfin ! Je retrouve ce précieux temps. Je retrouve ces moments d&#8217;ennui. Oui, je comprends bien que ça puisse parraître fou de voir quelqu&#8217;un se réjouir de son ennui… Cet ennui me permet de creuser de nouvelles idées, de reprendre ce bouquin qu&#8217;on avait laissé tomber sans trop de&nbsp;raison.</p> <p>Et surtout, c&#8217;est se retrouver à contrôler son&nbsp;engagement.</p>NEIPA #32017-12-29T00:00:00+01:002017-12-29T00:00:00+01:00tag:blog.notmyidea.org,2017-12-29:/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L&#8217;idée est de pouvoir les relire et m&#8217;améliorer au fur et à&nbsp;mesure.</em></p> @@ -2206,7 +2240,7 @@ ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez su coté pour avoir accès aux&nbsp;réponses.</li> </ul> <p>Bref, en espérant que ça vous serve ! Un petit pas dans la direction des données -rendues à leurs utilisateurs&nbsp;!</p>Cloisonnement des activités ?2016-05-25T00:00:00+02:002016-05-25T00:00:00+02:00tag:blog.notmyidea.org,2016-05-25:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques +rendues à leurs utilisateurs&nbsp;!</p>Cloisonnement des activités ?2016-05-25T00:00:00+02:002016-05-25T00:00:00+02:00tag:blog.notmyidea.org,2016-05-25:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques jours à l&#8217;occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas cette conférence, il s&#8217;agit d&#8217;un moment avec des gens chouettes qui se posent des questions sur leur metier, comment le vivre et …</p><p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques @@ -2398,7 +2432,7 @@ la lecture de <a href="https://www.indolering.com/okturtles-dnschain-unblock- et interventions du développeur du projet m&#8217;ont fait changer&nbsp;d&#8217;avis.</p> <p>Reste encore la piste de <em>Namecoin Control</em> que je n&#8217;ai pas encore creusée. Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la -bienvenue sur ces&nbsp;sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> +bienvenue sur ces&nbsp;sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> <p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. I need&nbsp;to.</p> <p>And this thing makes me feel uncomfortable at the end of the day, @@ -2545,7 +2579,7 @@ un tas de petites ressources (par catégorie par ex.). Les gros médias pourraie <h3 id="est-ce-quon-a-vraiment-besoin-dun-tracker">Est-ce qu&#8217;on à vraiment besoin d&#8217;un tracker&nbsp;?</h3> <p>Le support d&#8217;une <span class="caps">DHT</span> <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, mais pour l&#8217;instant pas encore implémenté. L&#8217;utilisation de la <span class="caps">DHT</span> BitTorrent -n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>L’horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00tag:blog.notmyidea.org,2016-03-02:/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. +n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>L’horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00tag:blog.notmyidea.org,2016-03-02:/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. image :&nbsp;images/horizon.jpg</p> <blockquote> <p>L&#8217;Utopie, c&#8217;est l&#8217;horizon. C&#8217;est ce qui permet d&#8217;avoir une direction, @@ -2685,7 +2719,7 @@ pourrait ressembler à ceci&nbsp;:</p> <span class="n">collection_hash</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> </pre></div> </div> -Let’s Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> +Let’s Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> <blockquote> <p>It’s time for the Web to take a big step forward in terms …</p></blockquote><p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> <blockquote> @@ -2793,7 +2827,7 @@ compatible avec&nbsp;HAProxy:</p> </ul> <p>Et voila ! <a href="https://github.com/almet/infra/">Le tout est dans un dépot github</a>, si jamais ça peut vous servir, -tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des +tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des outils pour faire face à la surveillance généralisée, et notamment en rapport au chiffrement des données. Une de mes envies de l&#8217;époque était l&#8217;animation&nbsp;d&#8217;ateliers.</p> @@ -2921,7 +2955,7 @@ formation sur le sujet, j&#8217;ai donc décidé de publier les nôtres, afi co-construire avec d&#8217;autres des plans de&nbsp;formation.</p> <p>Ils sont pour l&#8217;instant disponibles <a href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The Docs</a>. Tous les -retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> +retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> <p>Et même si j&#8217;arrive à convaincre certains de …</p><p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> <p>Et même si j&#8217;arrive à convaincre certains de mes proches à installer <span class="caps">PGP</span>, je ne suis pas satisfait du résultat: les méta-données (qui contacte qui à quel moment, et pour lui dire quoi) transitent de toute manière, elles, en clair, à la vue de&nbsp;tous.</p> @@ -2938,7 +2972,7 @@ mail&nbsp;fonctionnel.</p> incriminer l&#8217;emmeteur du message&nbsp;(deniability);</li> </ul> <p>Avec au moins ces besoins en tête, il semble qu&#8217;une revue de l&#8217;ensemble des projets existants pointe du doigt vers <a href="https://github.com/agl/pond">pond</a>, ou vers <a href="https://www.whispersystems.org">Signal</a>.</p> -<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I +<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I want to share with the crypto community to actually see if any solution exists to solve this particular&nbsp;problem.</em></p> <p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in @@ -3037,7 +3071,7 @@ User-Agent (or the distributor of the User-Agent), a little green icon could be presented to the User, so they know that they can be confident about&nbsp;this.</p> <p>A bit like User-Agents do for <span class="caps">SSL</span>, but for the actual signature of the -files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel +files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel lors de la conception&nbsp;d&#8217;APIs.</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p><strong>tldr; Cliquet est un toolkit Python pour construire des APIs, qui implémente @@ -3138,7 +3172,7 @@ pour des millions d&#8217;utilisateurs et des retours d&#8217;expérienc de <em>Firefox Sync</em> pour la gestion de la concurrence et de&nbsp;l&#8217;«offline-first».</p> <p>Il est <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/api/index.html">documenté en détail</a>.</p> <p>Dans un monde idéal, ce protocole serait versionné, et formalisé dans une <span class="caps">RFC</span>. -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.). <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a></p> <table class="docutils footnote" frame="void" id="footnote-1" rules="none"> <colgroup><col class="label" /><col /></colgroup> @@ -3210,7 +3244,7 @@ au fur et à mesure que ses besoins se&nbsp;précisent.</p> mais rien n&#8217;empêcherait d&#8217;implémenter le stockage dans un modèle&nbsp;relationnel.</p> <p>Comme les composants peuvent être remplacés depuis la configuration, il est tout à fait possible d&#8217;étendre <em>Cliquet</em> avec des notions métiers ou des -technologies exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation +codes exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation de l&#8217;éco-système</a>.</p> <p>Dans les prochaines semaines, nous allons introduire la notion d&#8217;«évènements» (ou signaux), qui permettraient aux extensions de s&#8217;interfacer beaucoup plus&nbsp;proprement.</p> @@ -3361,7 +3395,7 @@ projets en&nbsp;cascade.</li> <blockquote> Pourquoi Python ?</blockquote> <p>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&nbsp;!</p> <p>Et puis, après avoir passé près d&#8217;un an sur un projet Node.js, l&#8217;équipe avait bien envie de refaire du&nbsp;Python.</p> @@ -3431,7 +3465,7 @@ il y a de grandes chances que nous agissions pour s&#8217;assurer que les ab et les mécanismes d&#8217;extension fournis permettent de l&#8217;implémenter sous forme&nbsp;d&#8217;extension.</p> </div> </div> -Charte et événements non-mixtes au sein de l’Afpy2015-07-09T00:00:00+02:002015-07-09T00:00:00+02:00tag:blog.notmyidea.org,2015-07-09:/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html +Charte et événements non-mixtes au sein de l’Afpy2015-07-09T00:00:00+02:002015-07-09T00:00:00+02:00tag:blog.notmyidea.org,2015-07-09:/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html <p><em>Mail envoyé sur la liste de diffusion de l&#8217;<span class="caps">AFPY</span> en Juillet&nbsp;2015</em></p> <p>Bonjour à toutes et&nbsp;tous,</p> <p>Récemment, l&#8217;Afpy à pris la décision de ne pas relayer la tenue d&#8217;un @@ -3652,7 +3686,7 @@ construire une solution libre, générique, simple et auto-hébergeable pour le de données sur le Web&nbsp;:)</p> <img alt="Friday Night Party - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-top-roof.jpg" /> </div> -Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00tag:blog.notmyidea.org,2015-06-29:/roles.html<p>Headline : De l&#8217;importance des rôles informels et de leur partage au sein d&#8217;un&nbsp;groupe.</p> +Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00tag:blog.notmyidea.org,2015-06-29:/roles.html<p>Headline : De l&#8217;importance des rôles informels et de leur partage au sein d&#8217;un&nbsp;groupe.</p> <blockquote> <p>Un […] dispositif consiste à tenter de faire bouger les rôles (pré)acquis ou qui se fixent dans le groupe, les pousser ailleurs que @@ -3849,7 +3883,7 @@ est <em>pluggable</em>).</td></tr> <tr><td class="label"><a class="fn-backref" href="#footnote-reference-4">[4]</a></td><td>La feuille de route de Kinto: <a class="reference external" href="https://github.com/mozilla-services/kinto/wiki/roadmap">https://github.com/mozilla-services/kinto/wiki/roadmap</a></td></tr> </tbody> </table> -Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> +Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p><strong>tl;dr: On a maintenant un super système de permission mais comment faire pour stocker et interroger ces permissions de manière efficace&nbsp;?</strong></p> <div class="section" id="la-problematique"> @@ -4132,7 +4166,7 @@ un objet et également de pouvoir récupérer tous les objets d&#8217;une collection pour un utilisateur si celui-ci n&#8217;a pas accès à tous les records de la collection, ou toutes les collections du&nbsp;bucket.</p> </div> -Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote> +Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote> <p>Flip a bit in the communication between sender and recipient and they will experience decryption or verification errors. How high are the chances they will start to exchange the data in the clear rather than @@ -4201,7 +4235,7 @@ qui explique comment configurer son installation&nbsp;correctement.</p> <p>Le <a href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils de chiffrement d&#8217;échanges de messages et de <span class="caps">VPN</span> simples à utiliser, encore quelque chose à&nbsp;regarder.</p> -<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00tag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<hr> +<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00tag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<hr> <blockquote> <p>Low-risk, low-pressure, and love: The 3 rules of side projects. &#8212; <a href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side&nbsp;projects</a></p> @@ -4305,7 +4339,7 @@ exportées sur des serveurs de clés existants. C&#8217;est quelque chose soulève des questions qui méritent qu&#8217;on s&#8217;y attarde un&nbsp;brin.</p> <p>Par ailleurs, <a href="https://leap.se/nicknym">d&#8217;autres projets qui visent des objectifs similaires</a> existent, via le projet <span class="caps">LEAP</span>, mais -je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html +je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html <ul> <li>headline<br> Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de @@ -4369,7 +4403,7 @@ personnelles, en utilisant des phrases de passe plus&nbsp;complexes.</p&g <p>Reste encore la question de la sauvegarde de ces clés privées de manière chiffrée, que je n&#8217;ai pas encore résolue. Bref, tout cela me semble bien compliqué pour réussir à l&#8217;expliquer à des novices, qui pour certains ne -sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00tag:blog.notmyidea.org,2015-05-08:/chiffrement.html +sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00tag:blog.notmyidea.org,2015-05-08:/chiffrement.html <ul> <li>headline<br> Face a la surveillance généralisée, une seule solution, le @@ -4434,8 +4468,6 @@ sphère privée ce qui devrait l&#8217;être à&nbsp;priori.</p> Enigmail et de le configurer correctement. Ce n&#8217;est pas très compliqué et permet d&#8217;avoir des échanges chiffrés. <a href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à&nbsp;pas.</p> -<p>La clé publique pour me contacter est -<a href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et vous&nbsp;?</p> <p>Je vous invite à aller voir le documentaire Citizen Four, qui passe en salles. Si vous ni avez pas accès, vous pouvez le visionner ici, et éventuellement faire un don aux auteurs ou associations qui gravitent @@ -5100,7 +5132,7 @@ donner aux applications qui agissent en son&nbsp;nom.</p> réflexions, n&#8217;hésitez pas à nous interrompre pendant qu&#8217;il est encore temps&nbsp;!</p> </div> </div> -Eco-système et stockage générique2015-04-30T00:00:00+02:002015-04-30T00:00:00+02:00tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.html +Eco-système et stockage générique2015-04-30T00:00:00+02:002015-04-30T00:00:00+02:00tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.html <p><strong>tl;dr Nous devons construire un service de suivi de paiements, et nous hésitons à continuer à nous entêter avec notre propre solution de&nbsp;stockage/synchronisation.</strong></p> <p>Comme nous l&#8217;écrivions <a href="https://blog.notmyidea.org/service-de-nuages-fr.html">dans l&#8217;article @@ -5426,7 +5458,7 @@ Cloud Services</em>!</p> <li>Il existe le <a href="https://sharesome.5apps.com/">projet Sharesome</a> qui permet de partager publiquement des ressources de son <em>remote Storage</em>.</li> -</ol>Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> +</ol>Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p>Pas mal de changements depuis le début de l&#8217;année pour l&#8217;équipe «cloud-services»&nbsp;francophone!</p> @@ -5497,7 +5529,7 @@ rassemblées dans le protocole (ou <em>Cliquet</em>), certains point et de vous présenter notre vision via des exemples et&nbsp;tutoriaux.</p> <p>À bientôt, donc&nbsp;!</p> </div> -Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00tag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html +Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00tag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html <p>Un enfant demande à son père&nbsp;:</p> <blockquote> <p>Dis papa, quel est le secret pour être heureux&nbsp;?</p> @@ -5727,7 +5759,7 @@ in case that helps you to integrate with your&nbsp;projects.</p> (that&#8217;s a pyramid / cornice)&nbsp;app.</li> <li>It&#8217;s also interesting to note that Kumar put together <a href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for the django rest&nbsp;framework</a></li> -</ul>Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html +</ul>Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html <p>Aujourd&#8217;hui, mon métier est d&#8217;être développeur d&#8217;applications. Imaginer des solutions techniques pour faire marcher des logiciels, puis écrire les lignes de code&nbsp;nécessaires.</p> @@ -5822,7 +5854,7 @@ de génération de formulaires en ligne, qui ne soit pas centré sur les services de&nbsp;google…</p> <p>Allez, au boulot&nbsp;!</p> <p><span class="caps">PS</span>: je me rends compte après relecture que ce billet fait echo à un -billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="%7Bfilename%7D2011.05.travailler-moins-mieux.rst">sur le +billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler.html">sur le sens du travail et de l&#8217;informatique</a>, ça fait du bien&nbsp;:)</p>Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html @@ -5839,7 +5871,7 @@ restent&nbsp;intacts.</p> <p>Deux ans ça parait énorme, c&#8217;est le temps le plus long que j&#8217;ai passé à travailler sur un projet, avec quasiment les mêmes personnes. Si vous suivez un peu ces carnets, vous savez surement que j&#8217;ai beaucoup -travaillé avec <a href="ziade.org">Tarek</a> par&nbsp;exemple.</p> +travaillé avec <a href="https://ziade.org">Tarek</a> par&nbsp;exemple.</p> <p>Ça a été (et c&#8217;est toujours) un réel plaisir de bosser avec la personne dont j&#8217;avais lu les livres pour apprendre le python, merci&nbsp;!</p> <h2 id="services">Services</h2> @@ -6081,7 +6113,7 @@ que je veux me garder de coté, des pensées que je souhaite partager… Un endroit ou je peux venir écrire quelque chose et le compléter plus&nbsp;tard.</p> <p>Du coup, le flux Atom contiens désormais quelques notes sur des sujets variés. Ces notes ne sont pas relayées sur la page d&#8217;accueil, mais vous -pouvez les trouver dans <a href="%7Ccategory%7Cnotes">la section notes</a>.</p> +pouvez les trouver dans <a href="/notes">la section notes</a>.</p> <p>Je ne sais pas encore si il s&#8217;agit du meilleur endroit pour ça, mais peu importe, essayons. A bas la pudeur&nbsp;rédactionelle.</p> <p>J&#8217;ai du au passage chambouler un peu vos agrégateurs, pardonnez moi&nbsp;:)</p> @@ -6606,7 +6638,7 @@ want to either understand how <span class="caps">CORS</span> works, </ul> <p>Of course, the <span class="caps">W3C</span> specification is the best resource to rely on. This specification isn&#8217;t hard to read, so you may want to go through it. -Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>New year python meme, 20122013-01-07T00:00:00+01:002013-01-07T00:00:00+01:00tag:blog.notmyidea.org,2013-01-07:/new-year-python-meme-2012.html +Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>New year python meme, 20122013-01-07T00:00:00+01:002013-01-07T00:00:00+01:00tag:blog.notmyidea.org,2013-01-07:/new-year-python-meme-2012.html <p>This series, also known as &#8220;<a href="http://ziade.org">Tarek Ziadé</a> strikes again&#8221;, is a good occasion to take a look back at 2012 and see what I&#8217;ve done related to python. So, let&#8217;s&nbsp;try.</p> @@ -6761,7 +6793,7 @@ J&#8217;utilisais haproxy + stunnel, et la négiciation <span class="caps fois <span class="caps">SSL</span> et <span class="caps">TLS</span> activés, et SSLv2 désactivé, tout fonctionne&nbsp;mieux.</p> <h2 id="et-voila">Et&nbsp;voilà</h2> <p>Finalement, j&#8217;ai mon joli status-board qui tourne à merveille sur -<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00tag:blog.notmyidea.org,2012-12-28:/habitat-collectif.html +<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00tag:blog.notmyidea.org,2012-12-28:/habitat-collectif.html <p>Habiter à plusieurs, partager un lieu de vie, monter une communauté, changer nos modes de vie et prendre plus de temps les uns pour les&nbsp;autres.</p> <p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez&nbsp;moi.</p> @@ -6835,7 +6867,7 @@ PATH=.:\$PATH nc -w1 $(echo %h | sed &#39;s/^.*+//;/:/!s/$/ %p/;s/:/ /&# user &lt;monuser(root)&gt; IdentityFile &lt;chemin vers ma clé ssh pour le serveur publique&gt; hostname ip_serveur_publique+ip_serveur_privé -</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html +</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html <p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de regarder du coté de gnome 3, à&nbsp;nouveau.</p> @@ -6878,7 +6910,7 @@ que je liste&nbsp;ici.</p> donc je ne sais pas encore si ça va rester, mais pourquoi&nbsp;pas.</li> </ul> <p>Vous pouvez aller faire un tour sur <a href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> pour -en trouver d&#8217;autres à votre&nbsp;gout.</p>“Groovy”2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/groovy.html +en trouver d&#8217;autres à votre&nbsp;gout.</p>“Groovy”2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/groovy.html <p>“Groovy”, c&#8217;est comme ça que je l&#8217;aime la musique: peut importe le style finalement, la bonne musique c&#8217;est celle qui sonne, celle qui groove, celle qui fait que tu tapes du pied (le droit chez moi) et que que ta @@ -7049,7 +7081,7 @@ use it, really quickly (these examples are how to interact with&nbsp;daybed) <p>Finally, we were out of cheese so everyone headed back to their respective houses and&nbsp;cities.</p> -<p>Until next&nbsp;time?</p>Bière maison !2012-10-04T00:00:00+02:002012-10-04T00:00:00+02:00tag:blog.notmyidea.org,2012-10-04:/biere-maison.html +<p>Until next&nbsp;time?</p>Bière maison !2012-10-04T00:00:00+02:002012-10-04T00:00:00+02:00tag:blog.notmyidea.org,2012-10-04:/biere-maison.html <p>Et voilà, c&#8217;est notre troisième brassin. On a commencé à faire notre propre bière (avec un ami, Fred) il y a quasiment un an maintenant, et après quelques dératés, même s&#8217;il nous reste encore bien du chemin à @@ -7328,7 +7360,7 @@ community again and discuss how Circus can evolve in ways that are interesting to&nbsp;everyone.</p> <p>Tarek and me are going to <a href="http://python.ie/pycon/2012/">Pycon ireland</a>, feel free to reach us if you&#8217;re going there, we&#8217;ll be happy to meet and -enjoy&nbsp;beers!</p>Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00tag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla.html +enjoy&nbsp;beers!</p>Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00tag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla.html <p>Depuis que j&#8217;ai commencé à bosser chez Mozilla, je me retrouve assez souvent à expliquer ce que j&#8217;y fais. J&#8217;aime bien raconter l&#8217;histoire de Mozilla, la mission, et comment je m&#8217;y&nbsp;rattache.</p> @@ -7746,7 +7778,7 @@ this service description tool: it looks at what&#8217;s described and build- the documentation from&nbsp;it.</p> <p>The resulting branch is not merged yet. Still, you can <a href="https://github.com/mozilla-services/cornice/tree/refactor-the-world">have a look at it</a>.</p> -<p>Any suggestions are of course welcome&nbsp;:-)</p>Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00tag:blog.notmyidea.org,2012-04-30:/bidouille.html +<p>Any suggestions are of course welcome&nbsp;:-)</p>Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00tag:blog.notmyidea.org,2012-04-30:/bidouille.html <p>Bidouille bidouille&nbsp;bidouille.</p> <p>Je pense que je suis un bidouilleur logiciel: j&#8217;aime bien aller farfouiller dans le code pour comprendre comment tel ou tel programme @@ -7862,7 +7894,7 @@ qu&#8217;ils mentent avec leur soit disant&nbsp;soleil).</p> <p>Et c&#8217;est sans parler de <a href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la brasucade</a>&nbsp;…</p> <p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une -présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html +présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html <p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> <p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même chose, à quelques détails près: une page web avec un formulaire qui @@ -8047,7 +8079,7 @@ solutions ou&nbsp;suggestions.</p> <a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. N&#8217;hésitez pas à l&#8217;éditer et à ajouter vos commentaires, c&#8217;est son&nbsp;objectif!</p> <p>Merci à <a href="http://sneakernet.fr/">Arnaud</a> pour la relecture et la -correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html +correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html <p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> <p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> <p>A bunch of friends asked me twice for quite the same thing: a webpage @@ -8207,7 +8239,7 @@ is written in stone yet. Comments and proposals are&nbsp;welcome!</p> <a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don&#8217;t hesitate to add your thoughts and edit it, that&#8217;s what it&#8217;s made&nbsp;for!</p> <p>Thanks to <a href="http://sneakernet.fr/">Arnaud</a> and -<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00tag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique.html +<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00tag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique.html <p>Le framablog vient de publier <a href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l&#8217;article de <span class="caps">RMS</span> à propos des dangers du livre électronique</a>. @@ -8455,7 +8487,7 @@ clients to discover services in a nice&nbsp;way.</p> <p>Of course, we are open to all your ideas and patches! If you feel haskish and want to see the sources, <a href="https://github.com/mozilla-services/cornice">go grab them on github</a> , commit and send -us a pull&nbsp;request!</p>Quels usages pour l’informatique ?2011-12-01T00:00:00+01:002011-12-01T00:00:00+01:00tag:blog.notmyidea.org,2011-12-01:/quels-usages-pour-linformatique.html +us a pull&nbsp;request!</p>Quels usages pour l’informatique ?2011-12-01T00:00:00+01:002011-12-01T00:00:00+01:00tag:blog.notmyidea.org,2011-12-01:/quels-usages-pour-linformatique.html <p>Quand on termine ses études, on s&#8217;en pose un tas, des questions. Sur le métier que l&#8217;on veut faire, sur ce que ça signifie, sur le sens et la valeur du travail. Et j&#8217;en suis arrivé à faire un constat simple: @@ -8633,7 +8665,7 @@ flask for this (and I should release&nbsp;it!).</p> and would be happy to work with new people and implement new ideas. If you have a nice idea about this, if you want to tweak it or to fill bugs. Don&#8217;t hesitate a second! The project lives at -<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>La simplicité volontaire contre le mythe de l’abondance2011-10-01T00:00:00+02:002011-10-01T00:00:00+02:00tag:blog.notmyidea.org,2011-10-01:/la-simplicite-volontaire-contre-le-mythe-de-labondance.html +<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>La simplicité volontaire contre le mythe de l’abondance2011-10-01T00:00:00+02:002011-10-01T00:00:00+02:00tag:blog.notmyidea.org,2011-10-01:/la-simplicite-volontaire-contre-le-mythe-de-labondance.html <p>Paul Ariès dans la préface de &#8220;<a href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de l&#8217;abondance</a>&#8221;</p> @@ -8697,7 +8729,7 @@ languages (and the resulting script would be easier) to do so, but the resulting graph would probably be way less&nbsp;readable.</p> <p>You can find the script <a href="https://github.com/ametaireau/experiments">on my github account</a>. Feel free to adapt -it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html +it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html <p>Back in October, I released <a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of code I wrote to power this weblog. I had simple needs: I wanted to be @@ -8719,7 +8751,7 @@ different services such as twitter or piwik, import from dotclear and rss, fixed a number of mistakes and improved a lot the codebase. This was a proof that there is a bunch of people that are willing to make better softwares just for the sake of&nbsp;fun.</p> -<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html +<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html <p>Java provides some interesting libraries that have no exact equivalent in python. In my case, the awesome boilerpipe library allows me to remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other @@ -8797,7 +8829,7 @@ similar, but from&nbsp;python</p> <p>I must say I didn&#8217;t thought it could work so easily. This will allow me to extract text content from URLs and remove the <em>boilerplate</em> text easily for infuse (my master thesis project), without having to write -java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html +java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html <p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais besoin d&#8217;un petit coup de&nbsp;main.</p> @@ -8830,7 +8862,7 @@ téléchargé et le compte créé il faut renseigner vos identifiants dans le plugin en question, et c&#8217;est&nbsp;tout!</p> <p>A votre bon cœur ! Je récupérerais probablement des données durant les 2 prochains mois pour ensuite les analyser&nbsp;correctement.</p> -<p>Merci pour votre aide&nbsp;!</p>Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00tag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler.html +<p>Merci pour votre aide&nbsp;!</p>Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00tag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler.html <p>Je viens de passer une semaine et demi quasiment hors-ligne et je dois dire que je suis assez impressionné du résultat: je suis de retour chez mes parents pour le &#8220;easter break&#8221; et j&#8217;en ai profité pour donner un @@ -9070,7 +9102,7 @@ complete novice in that&nbsp;field.</p> <li>Analyse web pages in order to categorize them. Processing their contents as well, to do some keyword based classification will be&nbsp;done.</li> </ul> -<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html +<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html <p>I have a server running freebsd since some time now, and was wondering about the possibility to directly have a development environment ready to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> @@ -9226,7 +9258,7 @@ its&nbsp;content.</p> <p>And it comes from <a href="http://ubuntuforums.org/showthread.php?p=10148738#post10148738">here</a>.</p> <p>A sync takes about 20s + the upload time on my machine, which stay -acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html +acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html <p>Finally, thanks to a bunch of people that helped me to pay my train and bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> <p>They have been a bit more than 10 people to come during the sprint, and @@ -9268,7 +9300,7 @@ the tubes, and will be ready for a release (hopefully) at the end of the&nbs providing us food, and to bearstech for providing some money for breakfast and&nbsp;bears^Wbeers.</p> <p>Again, a big thanks to all the people who gave me money to pay the -transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html +transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html <p>By now, there are two ways to retrieve data from PyPI (the Python Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several @@ -9357,7 +9389,7 @@ store in&nbsp;couchdb:</p> <p>The work I&#8217;ve done by now is available on <a href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it&#8217;s still a work in progress, and everything can break at any time. However, -any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html +any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html <p><strong>Edit: Thanks to logilab and some amazing people, I can make it to paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> <p>There will be a distutils2 sprint from the 27th to the 30th of january, @@ -9381,7 +9413,7 @@ help while&nbsp;needed.</p> <p>If you want to contribute some money to help me go there, feel free to use this chipin page: <a href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> -<p>Thanks for your support&nbsp;!</p>Fork you! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00tag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html +<p>Thanks for your support&nbsp;!</p>Fork you! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00tag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html <p>With <a href="http://github.com">github</a> and <a href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the developpers: it&#8217;s now easy to get feedback on your @@ -9544,7 +9576,7 @@ the command line tools curl, grep and tail (but really harder to&nbsp;read). <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> <span class="n">url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="o">.</span><span class="n">urljoin</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">boxurl</span><span class="p">,</span> <span class="n">REBOOT_URL</span><span class="p">)</span> <span class="n">reboot</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> -</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html +</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html <p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s not so easy, and you can&#8217;t just tell: use the pictures in this folder to do&nbsp;so.</p> @@ -9598,7 +9630,7 @@ $ pip install gnome-background-generator <span class="w"> </span><span class="o">-</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">set</span><span class="o">-</span><span class="n">background</span><span class="w"> </span><span class="s1">&#39;&#39;&#39;try to set the background using gnome-appearance-</span> <span class="s1"> properties</span> <span class="s1"> -b, --debug</span> -</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html +</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html <ul> <li> <p>date<br>&nbsp;2010-10-10</p> @@ -9666,7 +9698,7 @@ that will work without effort over&nbsp;time.</p> <span class="p">}</span> </code></pre></div> -<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html +<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html <p>Those days, I&#8217;ve wrote a little python application to fit my blogging needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> @@ -9733,7 +9765,7 @@ optional<span class="w"> </span>arguments: <span class="w"> </span>-b,<span class="w"> </span>--debug </code></pre></div> -<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html +<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html <p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It was a really amazing experience, for many&nbsp;reasons.</p> @@ -9861,7 +9893,7 @@ into their offices from time to time, to share they cheerfulness ! Many thanks too to the Google Summer of Code program for setting up such an initiative. If you&#8217;re a student, if you&#8217;re interested about <span class="caps">FOSS</span>, dont hesitate any second, it&#8217;s a really good opportunity to work on -interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html +interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html <ul> <li> <p>date<br>&nbsp;2010-07-06</p> @@ -9947,7 +9979,7 @@ seems to be a must-read, so, I know what to&nbsp;do.</p> <p>It was really great. Next time, we&#8217;ll need to focus a bit more on distutils2, and to have a bullet list of things to do, but days like this one are opportunities to catch ! We&#8217;ll probably do another sprint -in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html +in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html <p>I&#8217;m working for about a month for distutils2, even if I was being a bit busy (as I had some class courses and exams to work&nbsp;on)</p> <p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so @@ -10051,7 +10083,7 @@ avoid some changes on the <span class="caps">API</span>, and some lo <p>Also, I&#8217;ve set up <a href="http://wiki.notmyidea.org/distutils2_schedule">a schedule</a>, and the goal is to be sure everything will be ready in time, for the end of the -summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html +summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html <ul> <li> <p>date<br>&nbsp;2010-06-25</p> @@ -10096,7 +10128,7 @@ source</a>, used</a>, and the command line to generate the <span class="caps">PDF</span>:</p> <div class="highlight"><pre><span></span><code>rst2pdf couchdb.rst -b1 -s ../slides.style -</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html +</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html <p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> during the past week, taking part of the <a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short @@ -10158,7 +10190,7 @@ grabbed code, and do some software design work (to not expose all things as privates methods, have a clear <span class="caps">API</span>, and other things like this), then update the tests accordingly and write a documentation to make this&nbsp;clear.</p> <p>Next step is to a little client, as I&#8217;ve <a href="http://github.com/ametaireau/pypiclient">already started -here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html +here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html <p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> program, and will work on <a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> @@ -10187,7 +10219,7 @@ the <a href="http://www.python.org/dev/peps/pep-0376/"><span class="ca <li>PyPI <span class="caps">XML</span>-<span class="caps">RPC</span> client for distutils 2: <a href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> </ul> -<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00tag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y.html +<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00tag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y.html <p>Ouf, notre <a href="http://www.reseaugrappe.org">semaine de l&#8217;environnement</a> s&#8217;est terminée, après un peu de neige et un brin de soleil quand il en fallait&nbsp;!</p> @@ -10400,7 +10432,7 @@ python</a> sur mon profil, peut c&#8217;est ce qui m&#8217;agaçait avec <span class="caps">PHP</span> qui est un langage à typage faible&nbsp;dynamique.</li> </ul> <p>Cous pouvez également aller regarder <a href="http://video.pycon.fr/videos/free/53/">l&#8217;atelier donné par Victor Stinner -durant le Pyconfr 09</a>. Have fun&nbsp;!</p>AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00tag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e.html +durant le Pyconfr 09</a>. Have fun&nbsp;!</p>AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00tag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e.html <p>Le raccourci me semble un peu rapide. Et pourtant, il est emprunté bien trop souvent. La dernière <em>mes-utilisation</em> que j&#8217;ai à décrier est celle d&#8217;un reportage télé, passé sur France 2 vendredi 23 Octobre (<a href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la diff --git a/feeds/.rss.xml b/feeds/.rss.xml index 34d00d0..33de80e 100644 --- a/feeds/.rss.xml +++ b/feeds/.rss.xml @@ -1,5 +1,9 @@ -Alexis Métaireauhttps://blog.notmyidea.org/Wed, 27 Sep 2023 00:00:00 +0200llm command-line tipshttps://blog.notmyidea.org/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p>Wed, 27 Sep 2023 00:00:00 +0200tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.htmlcodepythonllmbashsqliteSetting up a IRC Bouncer with ZNChttps://blog.notmyidea.org/setting-up-a-irc-bouncer-with-znc.html<p>It&#8217;s been a while since I&#8217;ve used <span class="caps">IRC</span>, but I needed to connect to it today to discuss around <a href="https://docs.peewee-orm.com">Peewee</a>.</p> +Alexis Métaireauhttps://blog.notmyidea.org/Fri, 29 Sep 2023 00:00:00 +02002023, Semaine 39https://blog.notmyidea.org/2023-semaine-39.html +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques …</dd></dl>Fri, 29 Sep 2023 00:00:00 +0200tag:blog.notmyidea.org,2023-09-29:/2023-semaine-39.htmlweeknotesllm command-line tipshttps://blog.notmyidea.org/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p>Wed, 27 Sep 2023 00:00:00 +0200tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.htmlcodepythonllmbashsqliteSetting up a IRC Bouncer with ZNChttps://blog.notmyidea.org/setting-up-a-irc-bouncer-with-znc.html<p>It&#8217;s been a while since I&#8217;ve used <span class="caps">IRC</span>, but I needed to connect to it today to discuss around <a href="https://docs.peewee-orm.com">Peewee</a>.</p> <p>The main issue with <span class="caps">IRC</span> is that you need to be connected to see the answer, and to get the context of the conversation. Unless&#8230; you set up …</p>Wed, 27 Sep 2023 00:00:00 +0200tag:blog.notmyidea.org,2023-09-27:/setting-up-a-irc-bouncer-with-znc.htmlcodeZNCWeechatIRC2023, Semaine 38https://blog.notmyidea.org/2023-semaine-38.html <h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> <dl> @@ -51,7 +55,7 @@ Les trucs « conviviaux » des boites « cool », c’est un moyen très <blockquote> <p>Dans la voiture bar d&#8217;un train Paris -&gt; Quimper ;<br> Ne pas entendre une blague du « barista » parce que je me suis écarté pour laisser passer …</p></blockquote>Fri, 24 Feb 2023 00:00:00 +0100tag:blog.notmyidea.org,2023-02-24:/tolerance-empathie-et-limites.htmljournalLimitesSavoir-ÊtreInstallation de Mosquitto, InfluxDB, Telegraf et Grafanahttps://blog.notmyidea.org/installation-de-mosquitto-influxdb-telegraf-et-grafana.html<p>Récemment, on a m&#8217;a demandé un petit coup de main pour aider à l&#8217;installation d&#8217;une pile logicielle qui permet de stocker des données temporelles et en faire des&nbsp;graphiques.</p> -<p>Voici donc quelques notes prises durant l&#8217;installation du système, concues pour que des personnes qui n&#8217;y …</p>Mon, 29 Aug 2022 00:00:00 +0200tag:blog.notmyidea.org,2022-08-29:/installation-de-mosquitto-influxdb-telegraf-et-grafana.htmltechnologieAdministration SystèmeRéveil difficilehttps://blog.notmyidea.org/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p>Mon, 30 May 2022 00:00:00 +0200tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.htmljournalPoésieL’Ère de la critiquehttps://blog.notmyidea.org/lere-de-la-critique.html<p>Au détour d&#8217;<a href="https://tutut.delire.party/@almet/108257053355480866">une discussion sur mastodon</a> je viens de retrouver ce bout de texte écrit mais jamais&nbsp;publié.</p> +<p>Voici donc quelques notes prises durant l&#8217;installation du système, concues pour que des personnes qui n&#8217;y …</p>Mon, 29 Aug 2022 00:00:00 +0200tag:blog.notmyidea.org,2022-08-29:/installation-de-mosquitto-influxdb-telegraf-et-grafana.htmlcodeAdministration SystèmeRéveil difficilehttps://blog.notmyidea.org/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p>Mon, 30 May 2022 00:00:00 +0200tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.htmljournalPoésieL’Ère de la critiquehttps://blog.notmyidea.org/lere-de-la-critique.html<p>Au détour d&#8217;<a href="https://tutut.delire.party/@almet/108257053355480866">une discussion sur mastodon</a> je viens de retrouver ce bout de texte écrit mais jamais&nbsp;publié.</p> <p>J&#8217;y parle de ce que formuler des critiques me fait, de la hiérarchisation qui en découle, et de ce qu&#8217;elle me fait à moi mais aussi aux&nbsp;producteurs⋅ices …</p>Sat, 07 May 2022 00:00:00 +0200tag:blog.notmyidea.org,2022-05-07:/lere-de-la-critique.htmljournalSavoir-ÊtreFatigue relationnellehttps://blog.notmyidea.org/fatigue-relationnelle.html<p>Depuis peu, je me retrouve confronté à mon manque d&#8217;envie d&#8217;être avec d&#8217;autres personnes. Comme si mon quota d’interactions sociales était plus rapidement atteint qu&#8217;il y a quelques&nbsp;années.</p> <p>Je ne sais pas exactement d&#8217;où cela vient : si c&#8217;est un des nombreux effets …</p>Fri, 06 May 2022 00:00:00 +0200tag:blog.notmyidea.org,2022-05-06:/fatigue-relationnelle.htmljournalCoopérationSavoir-ÊtreFatigueConflitConflithttps://blog.notmyidea.org/conflit.html<p>J&#8217;ai pensé durant de nombreuses années que je savais gérer le conflit, alors que c&#8217;était en fait&nbsp;impensé.</p> <p>Ne pas être en conflit signifie parfois s&#8217;adapter aux autres, parfois ne pas (assez) s&#8217;écouter, et ne pas se faire&nbsp;entendre. </p> @@ -125,7 +129,7 @@ capacité relationnelle&nbsp;générale.</p> <li>se passer d&#8217;intermédiaires et favoriser les circuits&nbsp;courts</li> <li>aller à la rencontre des producteurs locaux et&nbsp;échanger</li> </ul> -<p>Notre groupement …</p>Sat, 03 Mar 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.htmltechnologieWebnoteshttps://blog.notmyidea.org/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p>Sun, 25 Feb 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-02-25:/webnotes.htmltechnologieFaire moinshttps://blog.notmyidea.org/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p>Thu, 25 Jan 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-01-25:/faire-moins.htmljournalNEIPA #3https://blog.notmyidea.org/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L&#8217;idée est de pouvoir les relire et m&#8217;améliorer au fur et à&nbsp;mesure.</em></p> +<p>Notre groupement …</p>Sat, 03 Mar 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.htmlcodeWebnoteshttps://blog.notmyidea.org/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p>Sun, 25 Feb 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-02-25:/webnotes.htmlcodeFaire moinshttps://blog.notmyidea.org/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p>Thu, 25 Jan 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-01-25:/faire-moins.htmljournalNEIPA #3https://blog.notmyidea.org/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L&#8217;idée est de pouvoir les relire et m&#8217;améliorer au fur et à&nbsp;mesure.</em></p> <p>Test autour d&#8217;une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab&#8217; avec&nbsp;Heiko.</p> <h1 id="objectifs">Objectifs:</h1> <ul> @@ -140,63 +144,63 @@ capacité relationnelle&nbsp;générale.</p> <p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s&#8217;ajouter, et c&#8217;est vrai qu&#8217;on sent …</p>Fri, 06 Oct 2017 00:00:00 +0200tag:blog.notmyidea.org,2017-10-06:/un-club-des-brasseurs-amateurs-rennais.htmljournalBrasserie du Vieux Singe — Installation en cours.https://blog.notmyidea.org/brasserie-du-vieux-singe-installation-en-cours.html<p>Ça fait maintenant quelques mois que j&#8217;ai décidé de <a href="https://www.vieuxsinge.com">changer de métier</a>. Choix à la fois difficile et excitant. Une rupture qui laisse place à quelques étoiles dans les yeux. Enfin, je retrouve l&#8217;envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop …</p>Mon, 26 Jun 2017 00:00:00 +0200tag:blog.notmyidea.org,2017-06-26:/brasserie-du-vieux-singe-installation-en-cours.htmljournalComment est-ce que vous générez vos formulaires ?https://blog.notmyidea.org/comment-est-ce-que-vous-generez-vos-formulaires.html<p><span class="caps">TL</span>; <span class="caps">DR</span>: Je viens à peine de <em>releaser</em> la première version d&#8217;un service de génération de formulaires. Allez jeter un coup d&#8217;œil sur <a href="https://www.fourmilieres.net">https://www.fourmilieres.net</a></p> <p><em>En février 2012, je parlais ici <a href="https://blog.notmyidea.org/carto-forms.html">d&#8217;un service de génération de formulaires</a>. -Depuis, pas mal d&#8217;eau à coulé sous …</em></p>Tue, 31 May 2016 00:00:00 +0200tag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.htmltechnologieCloisonnement des activités ?https://blog.notmyidea.org/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques +Depuis, pas mal d&#8217;eau à coulé sous …</em></p>Tue, 31 May 2016 00:00:00 +0200tag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.htmlcodeCloisonnement des activités ?https://blog.notmyidea.org/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques jours à l&#8217;occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas cette conférence, il s&#8217;agit d&#8217;un moment avec des gens chouettes qui se posent des questions sur leur metier, comment le vivre et …</p>Wed, 25 May 2016 00:00:00 +0200tag:blog.notmyidea.org,2016-05-25:/cloisonnement-des-activites.htmljournalAvez vous confiance en SSL?https://blog.notmyidea.org/avez-vous-confiance-en-ssl.html<p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d&#8217;autodéfense numérique</a>, j&#8217;ai passé un peu de temps à creuser sur l&#8217;utilisation de <span class="caps">SSL</span> puisque contrairement à ce que la plupart des personnes ont encore tendance à croire, -le petit cadenas (qui prouve qu&#8217;une connexion <span class="caps">SSL</span> est en cours) n&#8217;est …</p>Fri, 25 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-25:/avez-vous-confiance-en-ssl.htmltechnologieFocusing on what mattershttps://blog.notmyidea.org/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> +le petit cadenas (qui prouve qu&#8217;une connexion <span class="caps">SSL</span> est en cours) n&#8217;est …</p>Fri, 25 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-25:/avez-vous-confiance-en-ssl.htmlcodeFocusing on what mattershttps://blog.notmyidea.org/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> <p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. I need&nbsp;to.</p> <p>And this thing makes me feel uncomfortable at the end of the day, because I feel that I missed something. That I missed some good time …</p>Thu, 17 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.htmljournalRetours sur un atelier ZeroNethttps://blog.notmyidea.org/retours-sur-un-atelier-zeronet.html<p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> dans les locaux de l&#8217;<span class="caps">INSA</span> de&nbsp;Rennes.</p> <p>L&#8217;évènement s&#8217;étant rempli au delà de toutes les espérances, on m&#8217;a proposé de venir y tenir un atelier, que j&#8217;ai proposé sur <a href="https://zeronet.io">ZeroNet</a>, un -petit projet fort sympathique qui pourrait devenir une …</p>Thu, 17 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-17:/retours-sur-un-atelier-zeronet.htmltechnologieL’horizonhttps://blog.notmyidea.org/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. +petit projet fort sympathique qui pourrait devenir une …</p>Thu, 17 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-17:/retours-sur-un-atelier-zeronet.htmlcodeL’horizonhttps://blog.notmyidea.org/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. image :&nbsp;images/horizon.jpg</p> <blockquote> <p>L&#8217;Utopie, c&#8217;est l&#8217;horizon. C&#8217;est ce qui permet d&#8217;avoir une direction, de mettre un pied devant l&#8217;autre, de savoir vers où&nbsp;marcher.</p> </blockquote> <p>Il y …</p>Wed, 02 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-02:/lhorizon.htmljournalService de nuages : Garantir l’intégrité des données via des signatureshttps://blog.notmyidea.org/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.html<p class="first last">Comment garantir l&#8217;intégrité des données en utilisant les&nbsp;signatures.</p> -Tue, 01 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-01:/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.htmltechnologieLet’s Encrypt + HAProxyhttps://blog.notmyidea.org/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> +Tue, 01 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-01:/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.htmlcodeLet’s Encrypt + HAProxyhttps://blog.notmyidea.org/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> <blockquote> -<p>It’s time for the Web to take a big step forward in terms …</p></blockquote>Thu, 11 Feb 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.htmltechnologieAteliers d’autodéfense numériquehttps://blog.notmyidea.org/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des +<p>It’s time for the Web to take a big step forward in terms …</p></blockquote>Thu, 11 Feb 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.htmlcodeAteliers d’autodéfense numériquehttps://blog.notmyidea.org/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des outils pour faire face à la surveillance généralisée, et notamment en rapport au chiffrement des données. Une de mes envies de l&#8217;époque était l&#8217;animation&nbsp;d&#8217;ateliers.</p> <blockquote> <p>Je compte&nbsp;donc:</p> <ul> -<li>Organiser des ateliers de …</li></ul></blockquote>Thu, 14 Jan 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.htmltechnologieLe mail doit-il mourir ?https://blog.notmyidea.org/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> -<p>Et même si j&#8217;arrive à convaincre certains de …</p>Tue, 24 Nov 2015 00:00:00 +0100tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.htmltechnologieWeb distribution signinghttps://blog.notmyidea.org/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I +<li>Organiser des ateliers de …</li></ul></blockquote>Thu, 14 Jan 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.htmlcodeLe mail doit-il mourir ?https://blog.notmyidea.org/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> +<p>Et même si j&#8217;arrive à convaincre certains de …</p>Tue, 24 Nov 2015 00:00:00 +0100tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.htmlcodeWeb distribution signinghttps://blog.notmyidea.org/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I want to share with the crypto community to actually see if any solution exists to solve this particular&nbsp;problem.</em></p> <p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in -web-based cryptographic applications is the fact that there is no way …</p>Mon, 12 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.htmltechnologieService de nuages : Pourquoi avons-nous fait Cliquet ?https://blog.notmyidea.org/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel +web-based cryptographic applications is the fact that there is no way …</p>Mon, 12 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.htmlcodeService de nuages : Pourquoi avons-nous fait Cliquet ?https://blog.notmyidea.org/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel lors de la conception&nbsp;d&#8217;APIs.</p> -Tue, 14 Jul 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquettechnologieCharte et événements non-mixtes au sein de l’Afpyhttps://blog.notmyidea.org/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html +Tue, 14 Jul 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquetcodeCharte et événements non-mixtes au sein de l’Afpyhttps://blog.notmyidea.org/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html <p><em>Mail envoyé sur la liste de diffusion de l&#8217;<span class="caps">AFPY</span> en Juillet&nbsp;2015</em></p> <p>Bonjour à toutes et&nbsp;tous,</p> <p>Récemment, l&#8217;Afpy à pris la décision de ne pas relayer la tenue d&#8217;un événement non-mixte d&#8217;apprentissage de Python organisé par PyLadies&nbsp;[0].</p> <p>La raison est le fait que la …</p>Thu, 09 Jul 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-07-09:/charte-et-evenements-non-mixtes-au-sein-de-lafpy.htmljournalService de nuages : Perspectives pour l’étéhttps://blog.notmyidea.org/service-de-nuages-perspectives-pour-lete-fr.html<p class="first last">Le travail en cours et les fonctionnalités à venir pour les prochains&nbsp;mois.</p> -Tue, 07 Jul 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-07-07:/service-de-nuages-perspectives-pour-lete-fr.htmltechnologieRôleshttps://blog.notmyidea.org/roles.html<p>Headline : De l&#8217;importance des rôles informels et de leur partage au sein d&#8217;un&nbsp;groupe.</p> +Tue, 07 Jul 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-07-07:/service-de-nuages-perspectives-pour-lete-fr.htmlcodeRôleshttps://blog.notmyidea.org/roles.html<p>Headline : De l&#8217;importance des rôles informels et de leur partage au sein d&#8217;un&nbsp;groupe.</p> <blockquote> <p>Un […] dispositif consiste à tenter de faire bouger les rôles (pré)acquis ou qui se fixent dans le groupe, les pousser ailleurs que là où ils ont pris l’habitude de se réfugier suivant …</p></blockquote>Mon, 29 Jun 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-06-29:/roles.htmljournalService de nuages : Achievement unlockedhttps://blog.notmyidea.org/service-de-nuages-achievement-unlocked-fr.html<p class="first last">Après près de 3 mois intensifs, nous venons de <em>tagguer</em> Cliquet 2.0 et Kinto 1.0&nbsp;!</p> -Mon, 01 Jun 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-06-01:/service-de-nuages-achievement-unlocked-fr.htmltechnologieService de nuages : Stocker et interroger les permissions avec Kintohttps://blog.notmyidea.org/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> -Tue, 26 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.htmltechnologieLes problèmes de PGPhttps://blog.notmyidea.org/les-problemes-de-pgp.html<blockquote> +Mon, 01 Jun 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-06-01:/service-de-nuages-achievement-unlocked-fr.htmlcodeService de nuages : Stocker et interroger les permissions avec Kintohttps://blog.notmyidea.org/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> +Tue, 26 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.htmlcodeLes problèmes de PGPhttps://blog.notmyidea.org/les-problemes-de-pgp.html<blockquote> <p>Flip a bit in the communication between sender and recipient and they will experience decryption or verification errors. How high are the chances they will start to exchange the data in the clear rather than trying to hunt down the man in the&nbsp;middle?</p> <p>&#8212; <a href="http://secushare.org/PGP">http://secushare.org/<span class="caps">PGP</span></a></p> </blockquote> -<p>Une fois …</p>Mon, 25 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.htmltechnologieTravail et créativitéhttps://blog.notmyidea.org/travail-et-creativite.html<hr> +<p>Une fois …</p>Mon, 25 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.htmlcodeTravail et créativitéhttps://blog.notmyidea.org/travail-et-creativite.html<hr> <blockquote> <p>Low-risk, low-pressure, and love: The 3 rules of side projects. &#8212; <a href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side&nbsp;projects</a></p> @@ -211,7 +215,7 @@ commencé parce que j&#8217;en avais l&#8217;envie …</p>Mon, 11 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.htmltechnologiePhrases de passe et bonnes pratiqueshttps://blog.notmyidea.org/phrases-de-passe-et-bonnes-pratiques.html +décide de publier une clé en mon nom, et en …</p>Mon, 11 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.htmlcodePhrases de passe et bonnes pratiqueshttps://blog.notmyidea.org/phrases-de-passe-et-bonnes-pratiques.html <ul> <li>headline<br> Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de @@ -220,7 +224,7 @@ décide de publier une clé en mon nom, et en …</p>Sat, 09 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.htmltechnologieChiffrementhttps://blog.notmyidea.org/chiffrement.html +difficiles à deviner. La raison est qu&#8217;un …</p></blockquote>Sat, 09 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.htmlcodeChiffrementhttps://blog.notmyidea.org/chiffrement.html <ul> <li>headline<br> Face a la surveillance généralisée, une seule solution, le @@ -236,15 +240,15 @@ de surveiller massivement et sans contrôle la population&nbsp;française.&l internationaux, diplomates ou ministres à s&#8217;exprimer dans une langue qui n&#8217;est pas la leur équivaut à les placer en situation d&#8217;infériorité. <strong>Cela les prive de la …</strong></p></blockquote>Fri, 01 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-01:/language.htmljournalService de nuages : La gestion des permissionshttps://blog.notmyidea.org/service-de-nuages-la-gestion-des-permissions-fr.html<p class="first last">Démystification du vocabulaire des permissions et proposition d&#8217;implémentation pour&nbsp;Kinto</p> -Fri, 01 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-01:/service-de-nuages-la-gestion-des-permissions-fr.htmltechnologieEco-système et stockage génériquehttps://blog.notmyidea.org/eco-systeme-et-stockage-generique.html +Fri, 01 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-01:/service-de-nuages-la-gestion-des-permissions-fr.htmlcodeEco-système et stockage génériquehttps://blog.notmyidea.org/eco-systeme-et-stockage-generique.html <p><strong>tl;dr Nous devons construire un service de suivi de paiements, et nous hésitons à continuer à nous entêter avec notre propre solution de&nbsp;stockage/synchronisation.</strong></p> <p>Comme nous l&#8217;écrivions <a href="https://blog.notmyidea.org/service-de-nuages-fr.html">dans l&#8217;article précédent</a>, nous souhaitons construire une solution de stockage générique. On refait <a href="http://daybed.readthedocs.org">Daybed</a> chez Mozilla&nbsp;!</p> -<p>Notre objectif est …</p>Thu, 30 Apr 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.htmltechnologieService de nuages !https://blog.notmyidea.org/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> -Wed, 01 Apr 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.htmltechnologieLe secret du bonheurhttps://blog.notmyidea.org/le-secret-du-bonheur.html +<p>Notre objectif est …</p>Thu, 30 Apr 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.htmlcodeService de nuages !https://blog.notmyidea.org/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> +Wed, 01 Apr 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.htmlcodeLe secret du bonheurhttps://blog.notmyidea.org/le-secret-du-bonheur.html <p>Un enfant demande à son père&nbsp;:</p> <blockquote> <p>Dis papa, quel est le secret pour être heureux&nbsp;?</p> @@ -257,7 +261,7 @@ scheme</a> for a number of projects, and we came up creating two libraries to ease integration into pyramid and node.js&nbsp;apps.</p> <p>But maybe you don&#8217;t know&nbsp;Hawk.</p> -<p>Hawk is a relatively new technology, crafted by one of the …</p>Thu, 31 Jul 2014 00:00:00 +0200tag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.htmltechnologieQuel métier, quelle utilité ?https://blog.notmyidea.org/quel-metier-quelle-utilite.html +<p>Hawk is a relatively new technology, crafted by one of the …</p>Thu, 31 Jul 2014 00:00:00 +0200tag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.htmlcodeQuel métier, quelle utilité ?https://blog.notmyidea.org/quel-metier-quelle-utilite.html <p>Aujourd&#8217;hui, mon métier est d&#8217;être développeur d&#8217;applications. Imaginer des solutions techniques pour faire marcher des logiciels, puis écrire les lignes de code&nbsp;nécessaires.</p> @@ -313,7 +317,7 @@ Check it out and expect more technical articles there in the future. </div> -<p>For security reasons, it …</p>Mon, 04 Feb 2013 00:00:00 +0100tag:blog.notmyidea.org,2013-02-04:/implementing-cors-in-cornice.htmltechnologieNew year python meme, 2012https://blog.notmyidea.org/new-year-python-meme-2012.html +<p>For security reasons, it …</p>Mon, 04 Feb 2013 00:00:00 +0100tag:blog.notmyidea.org,2013-02-04:/implementing-cors-in-cornice.htmlcodeNew year python meme, 2012https://blog.notmyidea.org/new-year-python-meme-2012.html <p>This series, also known as &#8220;<a href="http://ziade.org">Tarek Ziadé</a> strikes again&#8221;, is a good occasion to take a look back at 2012 and see what I&#8217;ve done related to python. So, let&#8217;s&nbsp;try.</p> @@ -323,7 +327,7 @@ have discovered in 2012&nbsp;?</strong></p> <p>À force de démarrer des services web pour un oui et pour un non, de proposer à des copains d&#8217;héberger leurs sites, de faire pareil pour quelques assos etc, je me suis retrouvé avec, comme dirait l&#8217;autre, <em>une -bonne platrée</em> de sites et de services à gérer sur …</p>Sat, 29 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-29:/status-board.htmltechnologieHabitat collectifhttps://blog.notmyidea.org/habitat-collectif.html +bonne platrée</em> de sites et de services à gérer sur …</p>Sat, 29 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-29:/status-board.htmlcodeHabitat collectifhttps://blog.notmyidea.org/habitat-collectif.html <p>Habiter à plusieurs, partager un lieu de vie, monter une communauté, changer nos modes de vie et prendre plus de temps les uns pour les&nbsp;autres.</p> <p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez&nbsp;moi.</p> @@ -343,12 +347,12 @@ pour les filles, tu sais, un &#8220;truc de&nbsp;gonzesse&#8221;.< séparés par des &#8220;+&#8221;&nbsp;:</p> <div class="highlight"><pre><span></span><code>Host *+* ProxyCommand ssh $(echo %h | sed -&#39;s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l …</code></pre></div>Thu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/astuces-ssh.htmltechnologieGnome 3, extensionshttps://blog.notmyidea.org/gnome-3-extensions.html +&#39;s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l …</code></pre></div>Thu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/astuces-ssh.htmlcodeGnome 3, extensionshttps://blog.notmyidea.org/gnome-3-extensions.html <p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de regarder du coté de gnome 3, à&nbsp;nouveau.</p> <p>Et finalement, j&#8217;ai trouvé quelques extensions qui sont vraiment utiles, -que je …</p>Thu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.htmltechnologie“Groovy”https://blog.notmyidea.org/groovy.html +que je …</p>Thu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.htmlcode“Groovy”https://blog.notmyidea.org/groovy.html <p>“Groovy”, c&#8217;est comme ça que je l&#8217;aime la musique: peut importe le style finalement, la bonne musique c&#8217;est celle qui sonne, celle qui groove, celle qui fait que tu tapes du pied (le droit chez moi) et que que ta @@ -372,7 +376,7 @@ comme d&#8217;hab font un travail&nbsp;impeccable.</p> Angers,&nbsp;France.</p> <p>We were a bunch of python hackers and it rained a lot, wich forced us to stay inside and to code.&nbsp;Bad.</p> -<p>We were not enough to get rid of all the cheese and the awesome …</p>Mon, 22 Oct 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.htmltechnologieBière maison !https://blog.notmyidea.org/biere-maison.html +<p>We were not enough to get rid of all the cheese and the awesome …</p>Mon, 22 Oct 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.htmlcodeBière maison !https://blog.notmyidea.org/biere-maison.html <p>Et voilà, c&#8217;est notre troisième brassin. On a commencé à faire notre propre bière (avec un ami, Fred) il y a quasiment un an maintenant, et après quelques dératés, même s&#8217;il nous reste encore bien du chemin à @@ -390,7 +394,7 @@ Paris. It was the opportunity to meet a lot of people and to talk about python awesomness in&nbsp;general.</p> <p>We had three tracks this year, plus sprints the two first days. We sprinted on <a href="http://circus.io">Circus</a>, the process and socket manager -we …</p>Mon, 17 Sep 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.htmltechnologiePourquoi Mozilla?https://blog.notmyidea.org/pourquoi-mozilla.html +we …</p>Mon, 17 Sep 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.htmlcodePourquoi Mozilla?https://blog.notmyidea.org/pourquoi-mozilla.html <p>Depuis que j&#8217;ai commencé à bosser chez Mozilla, je me retrouve assez souvent à expliquer ce que j&#8217;y fais. J&#8217;aime bien raconter l&#8217;histoire de Mozilla, la mission, et comment je m&#8217;y&nbsp;rattache.</p> @@ -406,7 +410,7 @@ turned out that the current implementation wasn&#8217;t flexible enough to allow us to do what we wanted to&nbsp;do.</p> <p>Cornice started as a toolkit on top of the <a href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> -routing system, allowing to register services …</p>Tue, 01 May 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-05-01:/refactoring-cornice.htmltechnologieBidouillehttps://blog.notmyidea.org/bidouille.html +routing system, allowing to register services …</p>Tue, 01 May 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-05-01:/refactoring-cornice.htmlcodeBidouillehttps://blog.notmyidea.org/bidouille.html <p>Bidouille bidouille&nbsp;bidouille.</p> <p>Je pense que je suis un bidouilleur logiciel: j&#8217;aime bien aller farfouiller dans le code pour comprendre comment tel ou tel programme @@ -418,17 +422,17 @@ conférence autour de <a href="http://djangoproject.org">django</a>, <a href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques kilomètres de Montpellier la&nbsp;belle.</p> <p>J&#8217;ai vraiment apprécié les trois jours passés avec cette bande de geeks. -Je m&#8217;attendais à des <em>nerds</em>, j …</p>Mon, 16 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-16:/djangocong-2012.htmltechnologieGénération de formulaires, geolocalisés ?https://blog.notmyidea.org/generation-de-formulaires-geolocalises.html +Je m&#8217;attendais à des <em>nerds</em>, j …</p>Mon, 16 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-16:/djangocong-2012.htmlcodeGénération de formulaires, geolocalisés ?https://blog.notmyidea.org/generation-de-formulaires-geolocalises.html <p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> <p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même chose, à quelques détails près: une page web avec un formulaire qui permettrait de soumettre des informations géographiques, lié à une carte -et des manières de filtrer&nbsp;l&#8217;information …</p>Mon, 02 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.htmltechnologieThoughts about a form generation service, GIS enabledhttps://blog.notmyidea.org/thoughts-about-a-form-generation-service-gis-enabled.html +et des manières de filtrer&nbsp;l&#8217;information …</p>Mon, 02 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.htmlcodeThoughts about a form generation service, GIS enabledhttps://blog.notmyidea.org/thoughts-about-a-form-generation-service-gis-enabled.html <p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> <p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> <p>A bunch of friends asked me twice for quite the same thing: a webpage with a form, tied to a map generation with some information filtering. -They didn&#8217;t explicitly ask that but that&#8217;s the …</p>Mon, 02 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.htmltechnologieLes dangers du livre numériquehttps://blog.notmyidea.org/les-dangers-du-livre-numerique.html +They didn&#8217;t explicitly ask that but that&#8217;s the …</p>Mon, 02 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.htmlcodeLes dangers du livre numériquehttps://blog.notmyidea.org/les-dangers-du-livre-numerique.html <p>Le framablog vient de publier <a href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l&#8217;article de <span class="caps">RMS</span> à propos des dangers du livre électronique</a>. @@ -442,7 +446,7 @@ to do at services is to provide a way for developers to make web …</p>Wed, 07 Dec 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-12-07:/introducing-cornice.htmltechnologieQuels usages pour l’informatique ?https://blog.notmyidea.org/quels-usages-pour-linformatique.html +can focus on what&#8217;s important. Cornice provides you …</p>Wed, 07 Dec 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-12-07:/introducing-cornice.htmlcodeQuels usages pour l’informatique ?https://blog.notmyidea.org/quels-usages-pour-linformatique.html <p>Quand on termine ses études, on s&#8217;en pose un tas, des questions. Sur le métier que l&#8217;on veut faire, sur ce que ça signifie, sur le sens et la valeur du travail. Et j&#8217;en suis arrivé à faire un constat simple: @@ -451,7 +455,7 @@ l&#8217;informatique, c&#8217;est utile, tant …</p>Sat, 15 Oct 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.htmltechnologieLa simplicité volontaire contre le mythe de l’abondancehttps://blog.notmyidea.org/la-simplicite-volontaire-contre-le-mythe-de-labondance.html +great …</p>Sat, 15 Oct 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.htmlcodeLa simplicité volontaire contre le mythe de l’abondancehttps://blog.notmyidea.org/la-simplicite-volontaire-contre-le-mythe-de-labondance.html <p>Paul Ariès dans la préface de &#8220;<a href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de l&#8217;abondance</a>&#8221;</p> @@ -462,23 +466,23 @@ the languages influenced by python, and the languages that influenced python&nbsp;itself.</p> <p>Well, that&#8217;s kind of interesting to know which languages influenced others, it could even be more interesting to have an overview of the -connexion between them …</p>Tue, 16 Aug 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.htmltechnologiePelican, 9 months laterhttps://blog.notmyidea.org/pelican-9-months-later.html +connexion between them …</p>Tue, 16 Aug 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.htmlcodePelican, 9 months laterhttps://blog.notmyidea.org/pelican-9-months-later.html <p>Back in October, I released <a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of code I wrote to power this weblog. I had simple needs: I wanted to be able to use my text editor of choice (vim), a vcs (mercurial) and -restructured text. I started to write a really simple blog engine in …</p>Mon, 25 Jul 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.htmltechnologieUsing JPype to bridge python and Javahttps://blog.notmyidea.org/using-jpype-to-bridge-python-and-java.html +restructured text. I started to write a really simple blog engine in …</p>Mon, 25 Jul 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.htmlcodeUsing JPype to bridge python and Javahttps://blog.notmyidea.org/using-jpype-to-bridge-python-and-java.html <p>Java provides some interesting libraries that have no exact equivalent in python. In my case, the awesome boilerpipe library allows me to remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other &#8220;boilerplate&#8221;&nbsp;contents.</p> <p>Boilerpipe is written in Java. Two solutions then: using java from -python or reimplement boilerpipe …</p>Sat, 11 Jun 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.htmltechnologieUn coup de main pour mon mémoire !https://blog.notmyidea.org/un-coup-de-main-pour-mon-memoire.html +python or reimplement boilerpipe …</p>Sat, 11 Jun 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.htmlcodeUn coup de main pour mon mémoire !https://blog.notmyidea.org/un-coup-de-main-pour-mon-memoire.html <p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais besoin d&#8217;un petit coup de&nbsp;main.</p> <p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui -connaissent …</p>Wed, 25 May 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.htmltechnologieTravailler moins pour mieux travailler ?https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler.html +connaissent …</p>Wed, 25 May 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.htmlcodeTravailler moins pour mieux travailler ?https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler.html <p>Je viens de passer une semaine et demi quasiment hors-ligne et je dois dire que je suis assez impressionné du résultat: je suis de retour chez mes parents pour le &#8220;easter break&#8221; et j&#8217;en ai profité pour donner un @@ -486,25 +490,25 @@ coup aux travaux de la maison (et pour me reposer …</p>Fri, 01 Apr 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.htmltechnologieWorking directly on your server? How to backup and sync your dev environment with unisonhttps://blog.notmyidea.org/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html +quickly. Exams are coming in one month or such and then I&#8217;ll …</p>Fri, 01 Apr 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.htmlcodeWorking directly on your server? How to backup and sync your dev environment with unisonhttps://blog.notmyidea.org/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html <p>I have a server running freebsd since some time now, and was wondering about the possibility to directly have a development environment ready to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> -<p>Since I use vim to code, and spend most of my …</p>Wed, 16 Mar 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.htmltechnologieWrap up of the distutils2 paris’ sprinthttps://blog.notmyidea.org/wrap-up-of-the-distutils2-paris-sprint.html +<p>Since I use vim to code, and spend most of my …</p>Wed, 16 Mar 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.htmlcodeWrap up of the distutils2 paris’ sprinthttps://blog.notmyidea.org/wrap-up-of-the-distutils2-paris-sprint.html <p>Finally, thanks to a bunch of people that helped me to pay my train and bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> <p>They have been a bit more than 10 people to come during the sprint, and -it was very productive. Here&#8217;s a taste …</p>Tue, 08 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.htmltechnologiePyPI on CouchDBhttps://blog.notmyidea.org/pypi-on-couchdb.html +it was very productive. Here&#8217;s a taste …</p>Tue, 08 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.htmlcodePyPI on CouchDBhttps://blog.notmyidea.org/pypi-on-couchdb.html <p>By now, there are two ways to retrieve data from PyPI (the Python Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several existing&nbsp;drawbacks.</p> -<p>Basically, if you want to …</p>Thu, 20 Jan 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.htmltechnologieHelp me to go to the distutils2 paris’ sprinthttps://blog.notmyidea.org/help-me-to-go-to-the-distutils2-paris-sprint.html +<p>Basically, if you want to …</p>Thu, 20 Jan 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.htmlcodeHelp me to go to the distutils2 paris’ sprinthttps://blog.notmyidea.org/help-me-to-go-to-the-distutils2-paris-sprint.html <p><strong>Edit: Thanks to logilab and some amazing people, I can make it to paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> <p>There will be a distutils2 sprint from the 27th to the 30th of january, thanks to logilab which will host the&nbsp;event.</p> -<p>You can find more …</p>Sat, 15 Jan 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.htmltechnologieFork you! or how the social coding can help youhttps://blog.notmyidea.org/fork-you-or-how-the-social-coding-can-help-you.html +<p>You can find more …</p>Sat, 15 Jan 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.htmlcodeFork you! or how the social coding can help youhttps://blog.notmyidea.org/fork-you-or-how-the-social-coding-can-help-you.html <p>With <a href="http://github.com">github</a> and <a href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the developpers: it&#8217;s now easy to get feedback on your @@ -515,12 +519,12 @@ forking&nbsp;repositories.</p> very slow from time to time. After rebooting the box (yes, that&#8217;s a hard solution), all the things seems to go fine&nbsp;again.</p> <h2 id="edit-using-grep"><span class="caps">EDIT</span> : Using&nbsp;grep</h2> -<p>After a bit of reflexion, that&#8217;s also really easy …</p>Thu, 21 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.htmltechnologieDynamically change your gnome desktop wallpaperhttps://blog.notmyidea.org/dynamically-change-your-gnome-desktop-wallpaper.html +<p>After a bit of reflexion, that&#8217;s also really easy …</p>Thu, 21 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.htmlcodeDynamically change your gnome desktop wallpaperhttps://blog.notmyidea.org/dynamically-change-your-gnome-desktop-wallpaper.html <p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s not so easy, and you can&#8217;t just tell: use the pictures in this folder to do&nbsp;so.</p> <p>You can have a look to the git repository if you want: -<a href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau …</a></p>Mon, 11 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.htmltechnologieHow to install NGINX + PHP 5.3 on FreeBSD.https://blog.notmyidea.org/how-to-install-nginx-php-53-on-freebsd.html +<a href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau …</a></p>Mon, 11 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.htmlcodeHow to install NGINX + PHP 5.3 on FreeBSD.https://blog.notmyidea.org/how-to-install-nginx-php-53-on-freebsd.html <ul> <li> <p>date<br>&nbsp;2010-10-10</p> @@ -533,12 +537,12 @@ do&nbsp;so.</p> reminder about how to install php on <span class="caps">NGINX</span>, for FreeBSD. Nothing hard, but that&#8217;s worse to have the piece of configuration somewhere&nbsp;!</p> <div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="nx">update</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">ports</span> -<span class="err">$</span><span class="w"> </span><span class="nx">portsnap</span><span class="w"> </span><span class="nx">fetch</span><span class="w"> </span><span class="nx">update …</span></code></pre></div>Sun, 10 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.htmltechnologiePelican, a simple static blog generator in pythonhttps://blog.notmyidea.org/pelican-a-simple-static-blog-generator-in-python.html +<span class="err">$</span><span class="w"> </span><span class="nx">portsnap</span><span class="w"> </span><span class="nx">fetch</span><span class="w"> </span><span class="nx">update …</span></code></pre></div>Sun, 10 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.htmlcodePelican, a simple static blog generator in pythonhttps://blog.notmyidea.org/pelican-a-simple-static-blog-generator-in-python.html <p>Those days, I&#8217;ve wrote a little python application to fit my blogging needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> <p><a href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple -tool …</p>Wed, 06 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.htmltechnologieAn amazing summer of code working on distutils2https://blog.notmyidea.org/an-amazing-summer-of-code-working-on-distutils2.html +tool …</p>Wed, 06 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.htmlcodeAn amazing summer of code working on distutils2https://blog.notmyidea.org/an-amazing-summer-of-code-working-on-distutils2.html <p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It was a really amazing experience, for many&nbsp;reasons.</p> @@ -547,7 +551,7 @@ distutils2: <a href="http://zubin71.wordpress.com">Zubin</a>, <a href="http://wokslog.wordpress.com/">Éric</a>, <a href="http://gsoc.djolonga.com/">Josip</a>, <a href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, -<a href="http://mouadino.blogspot.com/">Mouad</a> have worked on …</p>Mon, 16 Aug 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.htmltechnologieSprinting on distutils2 in Tourshttps://blog.notmyidea.org/sprinting-on-distutils2-in-tours.html +<a href="http://mouadino.blogspot.com/">Mouad</a> have worked on …</p>Mon, 16 Aug 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.htmlcodeSprinting on distutils2 in Tourshttps://blog.notmyidea.org/sprinting-on-distutils2-in-tours.html <ul> <li> <p>date<br>&nbsp;2010-07-06</p> @@ -559,11 +563,11 @@ distutils2: <a href="http://zubin71.wordpress.com">Zubin</a>, <p>Yesterday, as I was traveling to Tours, I&#8217;ve took some time to visit Éric, another student who&#8217;s working on distutils2 this summer, as a part of the GSoC. Basically, it was to take a drink, discuss a bit about -distutils2, our respective tasks and …</p>Sat, 10 Jul 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.htmltechnologieIntroducing the distutils2 index crawlershttps://blog.notmyidea.org/introducing-the-distutils2-index-crawlers.html +distutils2, our respective tasks and …</p>Sat, 10 Jul 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.htmlcodeIntroducing the distutils2 index crawlershttps://blog.notmyidea.org/introducing-the-distutils2-index-crawlers.html <p>I&#8217;m working for about a month for distutils2, even if I was being a bit busy (as I had some class courses and exams to work&nbsp;on)</p> <p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so -far. You can also find, if …</p>Tue, 06 Jul 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.htmltechnologieUse Restructured Text (ReST) to power your presentationshttps://blog.notmyidea.org/use-restructured-text-rest-to-power-your-presentations.html +far. You can also find, if …</p>Tue, 06 Jul 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.htmlcodeUse Restructured Text (ReST) to power your presentationshttps://blog.notmyidea.org/use-restructured-text-rest-to-power-your-presentations.html <ul> <li> <p>date<br>&nbsp;2010-06-25</p> @@ -575,19 +579,19 @@ far. You can also find, if …</p>Tue, 06 Jul 2010 <p>Wednesday, we give a presentation, with some friends, about the CouchDB Database, to <a href="http://www.toulibre.org">the Toulouse local <span class="caps">LUG</span></a>. Thanks a lot to all the presents for being there, it was a pleasure to talk about -this topic with you. Too bad the season is over now an …</p>Fri, 25 Jun 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.htmltechnologiefirst week working on distutils2https://blog.notmyidea.org/first-week-working-on-distutils2.html +this topic with you. Too bad the season is over now an …</p>Fri, 25 Jun 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.htmlcodefirst week working on distutils2https://blog.notmyidea.org/first-week-working-on-distutils2.html <p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> during the past week, taking part of the <a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short summary of what I&#8217;ve done so&nbsp;far.</p> <p>As my courses are not over yet, I&#8217;ve not worked as much as I wanted, and -this will continues until …</p>Fri, 04 Jun 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.htmltechnologieA Distutils2 GSoChttps://blog.notmyidea.org/a-distutils2-gsoc.html +this will continues until …</p>Fri, 04 Jun 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.htmlcodeA Distutils2 GSoChttps://blog.notmyidea.org/a-distutils2-gsoc.html <p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> program, and will work on <a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> <blockquote> <p>So, it&#8217;s about building the successor of Distutils2, ie. &#8220;the python -package manager&#8221;. Today, there is too many ways to package …</p></blockquote>Sat, 01 May 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.htmltechnologieLe temps des grâces, courrez-y !https://blog.notmyidea.org/le-temps-des-graces-courrez-y.html +package manager&#8221;. Today, there is too many ways to package …</p></blockquote>Sat, 01 May 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.htmlcodeLe temps des grâces, courrez-y !https://blog.notmyidea.org/le-temps-des-graces-courrez-y.html <p>Ouf, notre <a href="http://www.reseaugrappe.org">semaine de l&#8217;environnement</a> s&#8217;est terminée, après un peu de neige et un brin de soleil quand il en fallait&nbsp;!</p> @@ -605,7 +609,7 @@ Terre</a>, à <a href="http://www.attac.org/"><span class="caps"& projet en <a href="http://www.djangoproject.org">django</a>, et que, nécessairement, je me forme à <a href="http://python.org/">Python</a>. Je prends un plaisir non dissimulé à découvrir ce langage (et à l&#8217;utiliser), qui -ne cesse de me surprendre. Les premiers mots qui me …</p>Thu, 17 Dec 2009 00:00:00 +0100tag:blog.notmyidea.org,2009-12-17:/python-go.htmltechnologieAMAP + Média = Paniers bio à 5e ?!https://blog.notmyidea.org/amap-media-paniers-bio-a-5e.html +ne cesse de me surprendre. Les premiers mots qui me …</p>Thu, 17 Dec 2009 00:00:00 +0100tag:blog.notmyidea.org,2009-12-17:/python-go.htmlcodeAMAP + Média = Paniers bio à 5e ?!https://blog.notmyidea.org/amap-media-paniers-bio-a-5e.html <p>Le raccourci me semble un peu rapide. Et pourtant, il est emprunté bien trop souvent. La dernière <em>mes-utilisation</em> que j&#8217;ai à décrier est celle d&#8217;un reportage télé, passé sur France 2 vendredi 23 Octobre (<a href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la diff --git a/feeds/all-en.atom.xml b/feeds/all-en.atom.xml index 4dd7acb..cc9f654 100644 --- a/feeds/all-en.atom.xml +++ b/feeds/all-en.atom.xml @@ -1,5 +1,39 @@ -Alexis Métaireauhttps://blog.notmyidea.org/2023-09-27T00:00:00+02:00llm command-line tips2023-09-27T00:00:00+02:002023-09-27T00:00:00+02:00tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p><p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to talk to a <span class="caps">SQLITE</span> database and answer in json, and <a href="https://github.com/jqlang/jq">jq</a> a command-line tool capable of doing requests for&nbsp;json.</p> +Alexis Métaireauhttps://blog.notmyidea.org/2023-09-29T00:00:00+02:002023, Semaine 392023-09-29T00:00:00+02:002023-09-29T00:00:00+02:00tag:blog.notmyidea.org,2023-09-29:/2023-semaine-39.html +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques …</dd></dl> +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques, pour finalement en changer et me questionner sur la partie <strong>metier</strong>, ce qui me semblait plus intéressant. A partir du moment où j&#8217;ai arrêté d&#8217;essayer d&#8217;appliquer une solution « déjà faite » j&#8217;ai pu me questionner sur le modèle de données et aller de l&#8217;avant. Étrangement c&#8217;est quand j&#8217;ai produit le moins de code que j&#8217;ai trouvé que j&#8217;étais le plus&nbsp;productif.</dd> +<dt>Notmyidea</dt> +<dd>Je n&#8217;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&nbsp;décider.</dd> +<dd>J&#8217;ai <del>procrastiné</del> passé beaucoup plus de temps que prévu sur la mise en place d&#8217;outils utiles pour moi, et à peaufiné mon site web. J&#8217;ai maintenant un bouncer <span class="caps">ZNC</span> et un <span class="caps">VPN</span> fait maison qui me permettent de travailler dans de meilleures conditions. Je suis à la fois content d&#8217;avoir pris le temps de mettre en place des outils, et en même temps j&#8217;ai une impression de&nbsp;procrastination.</dd> +</dl> +<h2 id="des-joies">Des&nbsp;joies</h2> +<ul> +<li>Avoir pris le temps d&#8217;aller « à la ville » pour passer du temps avec des amis et&nbsp;sociabiliser.</li> +<li>M&#8217;écouter et décider de dormir sur place pour travailler aussi sur Rennes le&nbsp;lendemain.</li> +<li>Aller à l&#8217;espace de coworkig à côté de chez&nbsp;moi.</li> +<li>Prendre le temps de faire des choses peu importantes entassées dans ma todolist depuis trop&nbsp;longtemps.</li> +<li>Récolter des fruits de discussions passées lors d&#8217;une soirée. Vive les todo-list&nbsp;!</li> +<li>Voir qu&#8217;une demande de modifications que j&#8217;ai faite soit appréciée et intégrée&nbsp;rapidement.</li> +<li>Dépanner le serveur de <a href="https://github.com/almet/copanier">copanier</a>, trouver le problème rapidement et le régler&nbsp;facilement.</li> +</ul> +<h2 id="des-peines">Des&nbsp;peines</h2> +<ul> +<li>Je suis retombé malade en fin de semaine, et donc bien fatigué. Ca impacte mon moral et ma capacité de&nbsp;concentration.</li> +<li>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&nbsp;autres.</li> +<li>Sentir que ma posture dans les conversations est plus ferme que par le passé. Je suis à la fois content de ne pas <strong>toujours</strong> me remettre en question, mais j&#8217;aimerai réussir à faire preuve de plus d&#8217;ouverture. Il faut trouver&nbsp;l&#8217;équilibre </li> +<li>Triste de voir des conflits escalader alors que ça pourrait être&nbsp;autrement.</li> +</ul> +<h2 id="vu-lu-ecoute">Vu, lu,&nbsp;écouté</h2> +<ul> +<li>🎮 J&#8217;ai continué <a href="https://fr.wikipedia.org/wiki/Baba_Is_You">Baba is you</a> avec Arthur. C&#8217;était sympa de se faire les reflexions à deux&nbsp;cerveaux.</li> +<li>▶︎ <a href="https://www.youtube.com/watch?app=desktop&amp;v=dVzfNZN9NKI&amp;list=PL8uoeex94UhFcwvAfWHybD7SfNgIUBRo-&amp;index=128">Vu une présentation sur DuckDB</a>, une base de données locale et minimaliste qui semble adaptée pour de la visualisation de données à grande&nbsp;échelle.</li> +</ul>llm command-line tips2023-09-27T00:00:00+02:002023-09-27T00:00:00+02:00tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p><p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to talk to a <span class="caps">SQLITE</span> database and answer in json, and <a href="https://github.com/jqlang/jq">jq</a> a command-line tool capable of doing requests for&nbsp;json.</p> <p>All in all, it&#8217;s pretty satisfying to use. I finally got a simple way to query databases! I&#8217;m also using <a href="https://github.com/charmbracelet/glow">glow</a>, which is capable of transforming markdown into a better version on the&nbsp;terminal.</p> <div class="highlight"><pre><span></span><code>sqlite-utils<span class="w"> </span><span class="s2">&quot;</span><span class="k">$(</span>llm<span class="w"> </span>logs<span class="w"> </span>path<span class="k">)</span><span class="s2">&quot;</span><span class="w"> </span><span class="s2">&quot;SELECT * FROM responses WHERE prompt LIKE &#39;%search%&#39;&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>jq<span class="w"> </span><span class="s1">&#39;.[].response&#39;</span><span class="w"> </span>-r<span class="w"> </span><span class="p">|</span><span class="w"> </span>glow </code></pre></div> @@ -787,18 +821,22 @@ L&#8217;analyse, l’élaboration, la remise en question des relations de po <li>Clarifiez ce que vous voulez réellement : pour vous, pour les autres, et pour la&nbsp;relation.</li> <li>Demandez-vous ce que vous devriez faire pour aller vers ce que vous souhaitez réellement&nbsp;?</li> </ul> -<p><strong>Refusez le dualisme</strong> : -- 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&#8217;un <strong>et</strong> l&#8217;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&nbsp;sain.</p> +<p><strong>Refusez le dualisme</strong>&nbsp;:</p> +<ul> +<li>Alors que vous considérez ce que vous voulez, notez quand vous vous piégez vous-même dans un&nbsp;dualisme.</li> +<li>Cherchez comment faire l&#8217;un <strong>et</strong>&nbsp;l&#8217;autre.</li> +<li>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&nbsp;sain.</li> +</ul> <h3 id="decider-de-ses-histoires">Décider De Ses&nbsp;Histoires</h3> <p>Les histoires créent des émotions. Les émotions n&#8217;arrivent pas d&#8217;elles-mêmes, et sont liées à des histoires qu&#8217;on se&nbsp;raconte.</p> <p>Il peut être utile de séparer les faits des histoires qu&#8217;on se raconte pour pouvoir repenser nos&nbsp;émotions.</p> -<p>Le schéma peut être le suivant : -1. Voir et entendre (les faits) -2. Se raconter une histoire -3. Ressentir -4.&nbsp;Agir</p> +<p>Le schéma peut être le suivant&nbsp;:</p> +<ol> +<li>Voir et entendre (les&nbsp;faits)</li> +<li>Se raconter une&nbsp;histoire</li> +<li>Ressentir</li> +<li>Agir</li> +</ol> <h2 id="partie-2-comment-ouvrir-la-bouche">Partie 2 : Comment Ouvrir la&nbsp;Bouche</h2> <h3 id="apprendre-a-regarder">Apprendre à&nbsp;Regarder</h3> <p>Comment se rendre compte que la sécurité est mise en jeu ? Il faut apprendre à regarder et à capter les signes. Quand une conversation devient stressante, on a tendance à faire les mauvaises choses. Apprenez à regarder&nbsp;:</p> @@ -811,17 +849,21 @@ L&#8217;analyse, l’élaboration, la remise en question des relations de po </ul> <h3 id="securiser-la-conversation">Sécuriser la&nbsp;Conversation</h3> <p>Pour sécuriser la conversation, il faut réussir à sortir du contenu de la conversation d&#8217;abord. L&#8217;idée étant de se rendre compte quand les gens deviennent violents ou silencieux, pour renouer le dialogue. Une fois que c&#8217;est fait on peut reprendre la&nbsp;discussion.</p> -<p>Comprendre ce qui crée un risque pour la sécurité : -- <strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations ? -- <strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</p> +<p>Comprendre ce qui crée un risque pour la sécurité&nbsp;:</p> +<ul> +<li><strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations&nbsp;?</li> +<li><strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</li> +</ul> <p>Pour commencer la discussion, <strong>partagez vos bonnes intentions</strong> : qu&#8217;est-ce que vous voulez ? Pour vous et pour l&#8217;autre personne&nbsp;?</p> <p><strong>Excusez-vous</strong> lorsque c&#8217;est&nbsp;approprié.</p> <p><strong>Contrastez</strong> pour régler les incompréhensions : Commencez par ce que vous ne voulez pas dire, puis expliquez ce que vous voulez&nbsp;dire.</p> -<p>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 -- Brainstormez les nouvelles&nbsp;stratégies</p> +<p>Créez un objectif commun lorsque vous vous rendez compte que les choses sont compliquées&nbsp;:</p> +<ul> +<li>Dites que votre objectif est de trouver un but&nbsp;commun.</li> +<li>Reconnaissez les buts derrière les&nbsp;stratégies</li> +<li>Inventez un but&nbsp;commun</li> +<li>Brainstormez les nouvelles&nbsp;stratégies</li> +</ul> <h3 id="decrire-sa-vision-des-choses">Décrire Sa Vision Des&nbsp;Choses</h3> <h3 id="comprendre-les-visions-des-autres">Comprendre Les Visions Des&nbsp;Autres</h3> <h3 id="ecouter">Écouter</h3> @@ -1063,7 +1105,7 @@ sudo<span class="w"> </span>/bin/systemctl<span class="w"> < <div class="highlight"><pre><span></span><code>sudo certbot --nginx </code></pre></div> -<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Réveil difficile2022-05-30T00:00:00+02:002022-05-30T00:00:00+02:00tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p><p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente, venaient de&nbsp;bouger.</p> +<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Réveil difficile2022-05-30T00:00:00+02:002022-05-30T00:00:00+02:00tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p><p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente, venaient de&nbsp;bouger.</p> <p>Comme si je sortais d&#8217;un ensorcellement, que mon comportement — ma perception, même — avaient étés durant des années différents, et que, enfin, je me réveillais. Avec un arrière-goût amer dans le fond du&nbsp;palais.</p> <p>L&#8217;incantation ne commençait pas : ses effets finissaient par disparaître. Comme sorti du brouillard, une certitude : bien que je n&#8217;étais pas le seul à réaliser le sort qui m&#8217;avait été réservé, beaucoup d&#8217;autres n&#8217;en avaient pas du tout conscience. Voire même : ceux qui n&#8217;en avaient pas conscience semblaient évoluer dans ce qui me semblait maintenant une béatitude <em>malaisante</em>.</p> <p>Certain⋅e⋅s s&#8217;injectaient même volontairement des <em>doses</em> de cette <em>potion</em> pour que le brouillard ne se dissipe pas. Et je comprends pourquoi : les effets sont puissants, ils rendent les frontières lisses, colorent les interstices, remplacent les malaises par des joies&nbsp;candides.</p> @@ -2296,9 +2338,9 @@ L&#8217;avantage de ce matériel c&#8217;est que c&#8217;est la < <p>Et quand on passe des tests à l’échelle, (de 20L à 1500L), on est moyennement rassurés&nbsp;!</p> <p>Après quelques brassins validés, on est un peu plus relax sur le sujet, et on a mis en place de quoi faire des expérimentations à petite échelle de manière simple : vu qu&#8217;on produit du moût toutes les semaines, on en utilise une partie pour faire quelques tests : changement de levure, adjonctions, changement des températures de fermentation,&nbsp;etc.</p> <p>Ah ça, c’est pas les idées qui nous manquent :-) Et c&#8217;est une super manière&nbsp;d&#8217;expérimenter.</p> -<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/experimentations/sobacha.png"></p> -<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/experimentations/monstrueuse-normalite.png"></p> -<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/experimentations/chainon-manquant.png"></p> +<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/un-an/sobacha.png"></p> +<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/un-an/monstrueuse-normalite.png"></p> +<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/un-an/chainon-manquant.png"></p> <h2 id="ouverture-au-public-evenements-et-equilibre">Ouverture au public, évènements et&nbsp;équilibre</h2> <p>On a pris le parti d&#8217;ouvrir le magasin toutes les fins de semaine (le jeudi et vendredi de 17h à 19h) et on est hyper contents de faire visiter la brasserie aux personnes qui passent de temps à autre. Pour nous, ça fait partie des plaisirs du métier. Par contre, on avait clairement sous estimé le temps que ça nous prendrait. On accueille beaucoup et les gens sont curieux. La fabrication de bière reste encore aujourd’hui quelque chose de nouveau pour la plupart, et il faut satisfaire cette curiosité (il faut plus de brasseries&nbsp;!).</p> <p>Ce qui se passe en ce moment sur la scène brassicole est génial : beaucoup de nouvelles brasseries proposent des produits exceptionnels, et les évènements se multiplient aux quatre coins de la France. On adore partager, goûter, discuter, mais on ne pensait pas être autant sollicités par des évènements extérieurs, souvent sur des week-end, et parfois loin. <strong>On souhaite garder un équilibre entre notre vie personnelle et notre vie professionnelle</strong>. Aller aux évènements aussi par plaisir. Être partout est probablement un des maux de notre temps ;-) À force de voir des brasseurs exténués, il y a de quoi se poser des questions sur la pérennité sur le long terme d’un rythme aussi&nbsp;effréné.</p> @@ -2392,7 +2434,7 @@ paiements s&#8217;effectuent directement entre&nbsp;nous.</p> <li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des&nbsp;chèques</a></li> <li><a href="https://docs.google.com/spreadsheets/d/1bnPRSvf2Q2RDxKerWnEqUyJjuCFePnVMq6pWo8LeA_k/edit?usp=sharing">une version « à remplir » de notre tableau de commandes</a> (le mieux est d&#8217;en faire une copie&nbsp;!).</li> </ul> -<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> +<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> <ul> <li>enregistrer une sélection de texte ainsi que son contexte: heure, site&nbsp;web.</li> <li>fonctionner sur&nbsp;Firefox;</li> @@ -2403,7 +2445,7 @@ paiements s&#8217;effectuent directement entre&nbsp;nous.</p> <p>J&#8217;ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j&#8217;ai baptisé « Webnotes ». C&#8217;est <a href="https://addons.mozilla.org/en-US/firefox/addon/wwebnotes/">une extension Firefox</a>, qui se configure assez simplement, et qui stocke les données dans une instance de <a href="http://kinto-storage.org/">Kinto</a>.</p> <p><img src="https://github.com/almet/webnotes/blob/master/webnotes.gif?raw=true" /></p> <p>C&#8217;est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué&nbsp;!</p> -<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Faire moins2018-01-25T00:00:00+01:002018-01-25T00:00:00+01:00tag:blog.notmyidea.org,2018-01-25:/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p><p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser un sujet en particulier) est l&#8217;occasion de contribuer à éviter notre société&nbsp;d&#8217;experts.</p> +<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Faire moins2018-01-25T00:00:00+01:002018-01-25T00:00:00+01:00tag:blog.notmyidea.org,2018-01-25:/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p><p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser un sujet en particulier) est l&#8217;occasion de contribuer à éviter notre société&nbsp;d&#8217;experts.</p> <p>Le hic, c&#8217;est que trop, c&#8217;est trop. J&#8217;ai donc décidé d&#8217;arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j&#8217;ai même arreté de faire des choses que j&#8217;avais commencé à faire (par exemple de l&#8217;escalade), me libérant du&nbsp;temps.</p> <p>Enfin ! Je retrouve ce précieux temps. Je retrouve ces moments d&#8217;ennui. Oui, je comprends bien que ça puisse parraître fou de voir quelqu&#8217;un se réjouir de son ennui… Cet ennui me permet de creuser de nouvelles idées, de reprendre ce bouquin qu&#8217;on avait laissé tomber sans trop de&nbsp;raison.</p> <p>Et surtout, c&#8217;est se retrouver à contrôler son&nbsp;engagement.</p>NEIPA #32017-12-29T00:00:00+01:002017-12-29T00:00:00+01:00tag:blog.notmyidea.org,2017-12-29:/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L&#8217;idée est de pouvoir les relire et m&#8217;améliorer au fur et à&nbsp;mesure.</em></p> @@ -2730,7 +2772,7 @@ ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez su coté pour avoir accès aux&nbsp;réponses.</li> </ul> <p>Bref, en espérant que ça vous serve ! Un petit pas dans la direction des données -rendues à leurs utilisateurs&nbsp;!</p>Cloisonnement des activités ?2016-05-25T00:00:00+02:002016-05-25T00:00:00+02:00tag:blog.notmyidea.org,2016-05-25:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques +rendues à leurs utilisateurs&nbsp;!</p>Cloisonnement des activités ?2016-05-25T00:00:00+02:002016-05-25T00:00:00+02:00tag:blog.notmyidea.org,2016-05-25:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques jours à l&#8217;occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas cette conférence, il s&#8217;agit d&#8217;un moment avec des gens chouettes qui se posent des questions sur leur metier, comment le vivre et …</p><p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques @@ -2922,7 +2964,7 @@ la lecture de <a href="https://www.indolering.com/okturtles-dnschain-unblock- et interventions du développeur du projet m&#8217;ont fait changer&nbsp;d&#8217;avis.</p> <p>Reste encore la piste de <em>Namecoin Control</em> que je n&#8217;ai pas encore creusée. Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la -bienvenue sur ces&nbsp;sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> +bienvenue sur ces&nbsp;sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> <p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. I need&nbsp;to.</p> <p>And this thing makes me feel uncomfortable at the end of the day, @@ -3069,7 +3111,7 @@ un tas de petites ressources (par catégorie par ex.). Les gros médias pourraie <h3 id="est-ce-quon-a-vraiment-besoin-dun-tracker">Est-ce qu&#8217;on à vraiment besoin d&#8217;un tracker&nbsp;?</h3> <p>Le support d&#8217;une <span class="caps">DHT</span> <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, mais pour l&#8217;instant pas encore implémenté. L&#8217;utilisation de la <span class="caps">DHT</span> BitTorrent -n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>L’horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00tag:blog.notmyidea.org,2016-03-02:/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. +n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>L’horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00tag:blog.notmyidea.org,2016-03-02:/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. image :&nbsp;images/horizon.jpg</p> <blockquote> <p>L&#8217;Utopie, c&#8217;est l&#8217;horizon. C&#8217;est ce qui permet d&#8217;avoir une direction, @@ -3223,7 +3265,7 @@ compatible avec&nbsp;HAProxy:</p> </ul> <p>Et voila ! <a href="https://github.com/almet/infra/">Le tout est dans un dépot github</a>, si jamais ça peut vous servir, -tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des +tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des outils pour faire face à la surveillance généralisée, et notamment en rapport au chiffrement des données. Une de mes envies de l&#8217;époque était l&#8217;animation&nbsp;d&#8217;ateliers.</p> @@ -3351,7 +3393,7 @@ formation sur le sujet, j&#8217;ai donc décidé de publier les nôtres, afi co-construire avec d&#8217;autres des plans de&nbsp;formation.</p> <p>Ils sont pour l&#8217;instant disponibles <a href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The Docs</a>. Tous les -retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> +retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> <p>Et même si j&#8217;arrive à convaincre certains de …</p><p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> <p>Et même si j&#8217;arrive à convaincre certains de mes proches à installer <span class="caps">PGP</span>, je ne suis pas satisfait du résultat: les méta-données (qui contacte qui à quel moment, et pour lui dire quoi) transitent de toute manière, elles, en clair, à la vue de&nbsp;tous.</p> @@ -3368,7 +3410,7 @@ mail&nbsp;fonctionnel.</p> incriminer l&#8217;emmeteur du message&nbsp;(deniability);</li> </ul> <p>Avec au moins ces besoins en tête, il semble qu&#8217;une revue de l&#8217;ensemble des projets existants pointe du doigt vers <a href="https://github.com/agl/pond">pond</a>, ou vers <a href="https://www.whispersystems.org">Signal</a>.</p> -<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I +<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I want to share with the crypto community to actually see if any solution exists to solve this particular&nbsp;problem.</em></p> <p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in @@ -3467,7 +3509,7 @@ User-Agent (or the distributor of the User-Agent), a little green icon could be presented to the User, so they know that they can be confident about&nbsp;this.</p> <p>A bit like User-Agents do for <span class="caps">SSL</span>, but for the actual signature of the -files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel +files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel lors de la conception&nbsp;d&#8217;APIs.</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p><strong>tldr; Cliquet est un toolkit Python pour construire des APIs, qui implémente @@ -3568,7 +3610,7 @@ pour des millions d&#8217;utilisateurs et des retours d&#8217;expérienc de <em>Firefox Sync</em> pour la gestion de la concurrence et de&nbsp;l&#8217;«offline-first».</p> <p>Il est <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/api/index.html">documenté en détail</a>.</p> <p>Dans un monde idéal, ce protocole serait versionné, et formalisé dans une <span class="caps">RFC</span>. -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.). <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a></p> <table class="docutils footnote" frame="void" id="footnote-1" rules="none"> <colgroup><col class="label" /><col /></colgroup> @@ -3640,7 +3682,7 @@ au fur et à mesure que ses besoins se&nbsp;précisent.</p> mais rien n&#8217;empêcherait d&#8217;implémenter le stockage dans un modèle&nbsp;relationnel.</p> <p>Comme les composants peuvent être remplacés depuis la configuration, il est tout à fait possible d&#8217;étendre <em>Cliquet</em> avec des notions métiers ou des -technologies exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation +codes exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation de l&#8217;éco-système</a>.</p> <p>Dans les prochaines semaines, nous allons introduire la notion d&#8217;«évènements» (ou signaux), qui permettraient aux extensions de s&#8217;interfacer beaucoup plus&nbsp;proprement.</p> @@ -3791,7 +3833,7 @@ projets en&nbsp;cascade.</li> <blockquote> Pourquoi Python ?</blockquote> <p>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&nbsp;!</p> <p>Et puis, après avoir passé près d&#8217;un an sur un projet Node.js, l&#8217;équipe avait bien envie de refaire du&nbsp;Python.</p> @@ -3861,7 +3903,7 @@ il y a de grandes chances que nous agissions pour s&#8217;assurer que les ab et les mécanismes d&#8217;extension fournis permettent de l&#8217;implémenter sous forme&nbsp;d&#8217;extension.</p> </div> </div> -Charte et événements non-mixtes au sein de l’Afpy2015-07-09T00:00:00+02:002015-07-09T00:00:00+02:00tag:blog.notmyidea.org,2015-07-09:/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html +Charte et événements non-mixtes au sein de l’Afpy2015-07-09T00:00:00+02:002015-07-09T00:00:00+02:00tag:blog.notmyidea.org,2015-07-09:/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html <p><em>Mail envoyé sur la liste de diffusion de l&#8217;<span class="caps">AFPY</span> en Juillet&nbsp;2015</em></p> <p>Bonjour à toutes et&nbsp;tous,</p> <p>Récemment, l&#8217;Afpy à pris la décision de ne pas relayer la tenue d&#8217;un @@ -4119,7 +4161,7 @@ qui explique comment configurer son installation&nbsp;correctement.</p> <p>Le <a href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils de chiffrement d&#8217;échanges de messages et de <span class="caps">VPN</span> simples à utiliser, encore quelque chose à&nbsp;regarder.</p> -<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00tag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<hr> +<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00tag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<hr> <blockquote> <p>Low-risk, low-pressure, and love: The 3 rules of side projects. &#8212; <a href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side&nbsp;projects</a></p> @@ -4223,7 +4265,7 @@ exportées sur des serveurs de clés existants. C&#8217;est quelque chose soulève des questions qui méritent qu&#8217;on s&#8217;y attarde un&nbsp;brin.</p> <p>Par ailleurs, <a href="https://leap.se/nicknym">d&#8217;autres projets qui visent des objectifs similaires</a> existent, via le projet <span class="caps">LEAP</span>, mais -je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html +je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html <ul> <li>headline<br> Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de @@ -4287,7 +4329,7 @@ personnelles, en utilisant des phrases de passe plus&nbsp;complexes.</p&g <p>Reste encore la question de la sauvegarde de ces clés privées de manière chiffrée, que je n&#8217;ai pas encore résolue. Bref, tout cela me semble bien compliqué pour réussir à l&#8217;expliquer à des novices, qui pour certains ne -sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00tag:blog.notmyidea.org,2015-05-08:/chiffrement.html +sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00tag:blog.notmyidea.org,2015-05-08:/chiffrement.html <ul> <li>headline<br> Face a la surveillance généralisée, une seule solution, le @@ -4352,8 +4394,6 @@ sphère privée ce qui devrait l&#8217;être à&nbsp;priori.</p> Enigmail et de le configurer correctement. Ce n&#8217;est pas très compliqué et permet d&#8217;avoir des échanges chiffrés. <a href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à&nbsp;pas.</p> -<p>La clé publique pour me contacter est -<a href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et vous&nbsp;?</p> <p>Je vous invite à aller voir le documentaire Citizen Four, qui passe en salles. Si vous ni avez pas accès, vous pouvez le visionner ici, et éventuellement faire un don aux auteurs ou associations qui gravitent @@ -4739,7 +4779,7 @@ Cloud Services</em>!</p> <li>Il existe le <a href="https://sharesome.5apps.com/">projet Sharesome</a> qui permet de partager publiquement des ressources de son <em>remote Storage</em>.</li> -</ol>Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00tag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html +</ol>Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00tag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html <p>Un enfant demande à son père&nbsp;:</p> <blockquote> <p>Dis papa, quel est le secret pour être heureux&nbsp;?</p> @@ -4969,7 +5009,7 @@ in case that helps you to integrate with your&nbsp;projects.</p> (that&#8217;s a pyramid / cornice)&nbsp;app.</li> <li>It&#8217;s also interesting to note that Kumar put together <a href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for the django rest&nbsp;framework</a></li> -</ul>Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html +</ul>Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html <p>Aujourd&#8217;hui, mon métier est d&#8217;être développeur d&#8217;applications. Imaginer des solutions techniques pour faire marcher des logiciels, puis écrire les lignes de code&nbsp;nécessaires.</p> @@ -5064,7 +5104,7 @@ de génération de formulaires en ligne, qui ne soit pas centré sur les services de&nbsp;google…</p> <p>Allez, au boulot&nbsp;!</p> <p><span class="caps">PS</span>: je me rends compte après relecture que ce billet fait echo à un -billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="%7Bfilename%7D2011.05.travailler-moins-mieux.rst">sur le +billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler.html">sur le sens du travail et de l&#8217;informatique</a>, ça fait du bien&nbsp;:)</p>Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html @@ -5081,7 +5121,7 @@ restent&nbsp;intacts.</p> <p>Deux ans ça parait énorme, c&#8217;est le temps le plus long que j&#8217;ai passé à travailler sur un projet, avec quasiment les mêmes personnes. Si vous suivez un peu ces carnets, vous savez surement que j&#8217;ai beaucoup -travaillé avec <a href="ziade.org">Tarek</a> par&nbsp;exemple.</p> +travaillé avec <a href="https://ziade.org">Tarek</a> par&nbsp;exemple.</p> <p>Ça a été (et c&#8217;est toujours) un réel plaisir de bosser avec la personne dont j&#8217;avais lu les livres pour apprendre le python, merci&nbsp;!</p> <h2 id="services">Services</h2> @@ -5323,7 +5363,7 @@ que je veux me garder de coté, des pensées que je souhaite partager… Un endroit ou je peux venir écrire quelque chose et le compléter plus&nbsp;tard.</p> <p>Du coup, le flux Atom contiens désormais quelques notes sur des sujets variés. Ces notes ne sont pas relayées sur la page d&#8217;accueil, mais vous -pouvez les trouver dans <a href="%7Ccategory%7Cnotes">la section notes</a>.</p> +pouvez les trouver dans <a href="/notes">la section notes</a>.</p> <p>Je ne sais pas encore si il s&#8217;agit du meilleur endroit pour ça, mais peu importe, essayons. A bas la pudeur&nbsp;rédactionelle.</p> <p>J&#8217;ai du au passage chambouler un peu vos agrégateurs, pardonnez moi&nbsp;:)</p> @@ -5848,7 +5888,7 @@ want to either understand how <span class="caps">CORS</span> works, </ul> <p>Of course, the <span class="caps">W3C</span> specification is the best resource to rely on. This specification isn&#8217;t hard to read, so you may want to go through it. -Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>New year python meme, 20122013-01-07T00:00:00+01:002013-01-07T00:00:00+01:00tag:blog.notmyidea.org,2013-01-07:/new-year-python-meme-2012.html +Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>New year python meme, 20122013-01-07T00:00:00+01:002013-01-07T00:00:00+01:00tag:blog.notmyidea.org,2013-01-07:/new-year-python-meme-2012.html <p>This series, also known as &#8220;<a href="http://ziade.org">Tarek Ziadé</a> strikes again&#8221;, is a good occasion to take a look back at 2012 and see what I&#8217;ve done related to python. So, let&#8217;s&nbsp;try.</p> @@ -6003,7 +6043,7 @@ J&#8217;utilisais haproxy + stunnel, et la négiciation <span class="caps fois <span class="caps">SSL</span> et <span class="caps">TLS</span> activés, et SSLv2 désactivé, tout fonctionne&nbsp;mieux.</p> <h2 id="et-voila">Et&nbsp;voilà</h2> <p>Finalement, j&#8217;ai mon joli status-board qui tourne à merveille sur -<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00tag:blog.notmyidea.org,2012-12-28:/habitat-collectif.html +<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00tag:blog.notmyidea.org,2012-12-28:/habitat-collectif.html <p>Habiter à plusieurs, partager un lieu de vie, monter une communauté, changer nos modes de vie et prendre plus de temps les uns pour les&nbsp;autres.</p> <p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez&nbsp;moi.</p> @@ -6077,7 +6117,7 @@ PATH=.:\$PATH nc -w1 $(echo %h | sed &#39;s/^.*+//;/:/!s/$/ %p/;s/:/ /&# user &lt;monuser(root)&gt; IdentityFile &lt;chemin vers ma clé ssh pour le serveur publique&gt; hostname ip_serveur_publique+ip_serveur_privé -</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html +</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html <p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de regarder du coté de gnome 3, à&nbsp;nouveau.</p> @@ -6120,7 +6160,7 @@ que je liste&nbsp;ici.</p> donc je ne sais pas encore si ça va rester, mais pourquoi&nbsp;pas.</li> </ul> <p>Vous pouvez aller faire un tour sur <a href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> pour -en trouver d&#8217;autres à votre&nbsp;gout.</p>“Groovy”2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/groovy.html +en trouver d&#8217;autres à votre&nbsp;gout.</p>“Groovy”2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/groovy.html <p>“Groovy”, c&#8217;est comme ça que je l&#8217;aime la musique: peut importe le style finalement, la bonne musique c&#8217;est celle qui sonne, celle qui groove, celle qui fait que tu tapes du pied (le droit chez moi) et que que ta @@ -6291,7 +6331,7 @@ use it, really quickly (these examples are how to interact with&nbsp;daybed) <p>Finally, we were out of cheese so everyone headed back to their respective houses and&nbsp;cities.</p> -<p>Until next&nbsp;time?</p>Bière maison !2012-10-04T00:00:00+02:002012-10-04T00:00:00+02:00tag:blog.notmyidea.org,2012-10-04:/biere-maison.html +<p>Until next&nbsp;time?</p>Bière maison !2012-10-04T00:00:00+02:002012-10-04T00:00:00+02:00tag:blog.notmyidea.org,2012-10-04:/biere-maison.html <p>Et voilà, c&#8217;est notre troisième brassin. On a commencé à faire notre propre bière (avec un ami, Fred) il y a quasiment un an maintenant, et après quelques dératés, même s&#8217;il nous reste encore bien du chemin à @@ -6570,7 +6610,7 @@ community again and discuss how Circus can evolve in ways that are interesting to&nbsp;everyone.</p> <p>Tarek and me are going to <a href="http://python.ie/pycon/2012/">Pycon ireland</a>, feel free to reach us if you&#8217;re going there, we&#8217;ll be happy to meet and -enjoy&nbsp;beers!</p>Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00tag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla.html +enjoy&nbsp;beers!</p>Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00tag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla.html <p>Depuis que j&#8217;ai commencé à bosser chez Mozilla, je me retrouve assez souvent à expliquer ce que j&#8217;y fais. J&#8217;aime bien raconter l&#8217;histoire de Mozilla, la mission, et comment je m&#8217;y&nbsp;rattache.</p> @@ -6988,7 +7028,7 @@ this service description tool: it looks at what&#8217;s described and build- the documentation from&nbsp;it.</p> <p>The resulting branch is not merged yet. Still, you can <a href="https://github.com/mozilla-services/cornice/tree/refactor-the-world">have a look at it</a>.</p> -<p>Any suggestions are of course welcome&nbsp;:-)</p>Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00tag:blog.notmyidea.org,2012-04-30:/bidouille.html +<p>Any suggestions are of course welcome&nbsp;:-)</p>Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00tag:blog.notmyidea.org,2012-04-30:/bidouille.html <p>Bidouille bidouille&nbsp;bidouille.</p> <p>Je pense que je suis un bidouilleur logiciel: j&#8217;aime bien aller farfouiller dans le code pour comprendre comment tel ou tel programme @@ -7104,7 +7144,7 @@ qu&#8217;ils mentent avec leur soit disant&nbsp;soleil).</p> <p>Et c&#8217;est sans parler de <a href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la brasucade</a>&nbsp;…</p> <p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une -présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html +présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html <p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> <p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même chose, à quelques détails près: une page web avec un formulaire qui @@ -7289,7 +7329,7 @@ solutions ou&nbsp;suggestions.</p> <a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. N&#8217;hésitez pas à l&#8217;éditer et à ajouter vos commentaires, c&#8217;est son&nbsp;objectif!</p> <p>Merci à <a href="http://sneakernet.fr/">Arnaud</a> pour la relecture et la -correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html +correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html <p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> <p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> <p>A bunch of friends asked me twice for quite the same thing: a webpage @@ -7449,7 +7489,7 @@ is written in stone yet. Comments and proposals are&nbsp;welcome!</p> <a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don&#8217;t hesitate to add your thoughts and edit it, that&#8217;s what it&#8217;s made&nbsp;for!</p> <p>Thanks to <a href="http://sneakernet.fr/">Arnaud</a> and -<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00tag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique.html +<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00tag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique.html <p>Le framablog vient de publier <a href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l&#8217;article de <span class="caps">RMS</span> à propos des dangers du livre électronique</a>. @@ -7697,7 +7737,7 @@ clients to discover services in a nice&nbsp;way.</p> <p>Of course, we are open to all your ideas and patches! If you feel haskish and want to see the sources, <a href="https://github.com/mozilla-services/cornice">go grab them on github</a> , commit and send -us a pull&nbsp;request!</p>Quels usages pour l’informatique ?2011-12-01T00:00:00+01:002011-12-01T00:00:00+01:00tag:blog.notmyidea.org,2011-12-01:/quels-usages-pour-linformatique.html +us a pull&nbsp;request!</p>Quels usages pour l’informatique ?2011-12-01T00:00:00+01:002011-12-01T00:00:00+01:00tag:blog.notmyidea.org,2011-12-01:/quels-usages-pour-linformatique.html <p>Quand on termine ses études, on s&#8217;en pose un tas, des questions. Sur le métier que l&#8217;on veut faire, sur ce que ça signifie, sur le sens et la valeur du travail. Et j&#8217;en suis arrivé à faire un constat simple: @@ -7875,7 +7915,7 @@ flask for this (and I should release&nbsp;it!).</p> and would be happy to work with new people and implement new ideas. If you have a nice idea about this, if you want to tweak it or to fill bugs. Don&#8217;t hesitate a second! The project lives at -<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>La simplicité volontaire contre le mythe de l’abondance2011-10-01T00:00:00+02:002011-10-01T00:00:00+02:00tag:blog.notmyidea.org,2011-10-01:/la-simplicite-volontaire-contre-le-mythe-de-labondance.html +<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>La simplicité volontaire contre le mythe de l’abondance2011-10-01T00:00:00+02:002011-10-01T00:00:00+02:00tag:blog.notmyidea.org,2011-10-01:/la-simplicite-volontaire-contre-le-mythe-de-labondance.html <p>Paul Ariès dans la préface de &#8220;<a href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de l&#8217;abondance</a>&#8221;</p> @@ -7939,7 +7979,7 @@ languages (and the resulting script would be easier) to do so, but the resulting graph would probably be way less&nbsp;readable.</p> <p>You can find the script <a href="https://github.com/ametaireau/experiments">on my github account</a>. Feel free to adapt -it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html +it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html <p>Back in October, I released <a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of code I wrote to power this weblog. I had simple needs: I wanted to be @@ -7961,7 +8001,7 @@ different services such as twitter or piwik, import from dotclear and rss, fixed a number of mistakes and improved a lot the codebase. This was a proof that there is a bunch of people that are willing to make better softwares just for the sake of&nbsp;fun.</p> -<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html +<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html <p>Java provides some interesting libraries that have no exact equivalent in python. In my case, the awesome boilerpipe library allows me to remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other @@ -8039,7 +8079,7 @@ similar, but from&nbsp;python</p> <p>I must say I didn&#8217;t thought it could work so easily. This will allow me to extract text content from URLs and remove the <em>boilerplate</em> text easily for infuse (my master thesis project), without having to write -java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html +java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html <p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais besoin d&#8217;un petit coup de&nbsp;main.</p> @@ -8072,7 +8112,7 @@ téléchargé et le compte créé il faut renseigner vos identifiants dans le plugin en question, et c&#8217;est&nbsp;tout!</p> <p>A votre bon cœur ! Je récupérerais probablement des données durant les 2 prochains mois pour ensuite les analyser&nbsp;correctement.</p> -<p>Merci pour votre aide&nbsp;!</p>Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00tag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler.html +<p>Merci pour votre aide&nbsp;!</p>Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00tag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler.html <p>Je viens de passer une semaine et demi quasiment hors-ligne et je dois dire que je suis assez impressionné du résultat: je suis de retour chez mes parents pour le &#8220;easter break&#8221; et j&#8217;en ai profité pour donner un @@ -8312,7 +8352,7 @@ complete novice in that&nbsp;field.</p> <li>Analyse web pages in order to categorize them. Processing their contents as well, to do some keyword based classification will be&nbsp;done.</li> </ul> -<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html +<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html <p>I have a server running freebsd since some time now, and was wondering about the possibility to directly have a development environment ready to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> @@ -8468,7 +8508,7 @@ its&nbsp;content.</p> <p>And it comes from <a href="http://ubuntuforums.org/showthread.php?p=10148738#post10148738">here</a>.</p> <p>A sync takes about 20s + the upload time on my machine, which stay -acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html +acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html <p>Finally, thanks to a bunch of people that helped me to pay my train and bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> <p>They have been a bit more than 10 people to come during the sprint, and @@ -8510,7 +8550,7 @@ the tubes, and will be ready for a release (hopefully) at the end of the&nbs providing us food, and to bearstech for providing some money for breakfast and&nbsp;bears^Wbeers.</p> <p>Again, a big thanks to all the people who gave me money to pay the -transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html +transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html <p>By now, there are two ways to retrieve data from PyPI (the Python Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several @@ -8599,7 +8639,7 @@ store in&nbsp;couchdb:</p> <p>The work I&#8217;ve done by now is available on <a href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it&#8217;s still a work in progress, and everything can break at any time. However, -any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html +any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html <p><strong>Edit: Thanks to logilab and some amazing people, I can make it to paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> <p>There will be a distutils2 sprint from the 27th to the 30th of january, @@ -8623,7 +8663,7 @@ help while&nbsp;needed.</p> <p>If you want to contribute some money to help me go there, feel free to use this chipin page: <a href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> -<p>Thanks for your support&nbsp;!</p>Fork you! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00tag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html +<p>Thanks for your support&nbsp;!</p>Fork you! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00tag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html <p>With <a href="http://github.com">github</a> and <a href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the developpers: it&#8217;s now easy to get feedback on your @@ -8786,7 +8826,7 @@ the command line tools curl, grep and tail (but really harder to&nbsp;read). <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> <span class="n">url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="o">.</span><span class="n">urljoin</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">boxurl</span><span class="p">,</span> <span class="n">REBOOT_URL</span><span class="p">)</span> <span class="n">reboot</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> -</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html +</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html <p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s not so easy, and you can&#8217;t just tell: use the pictures in this folder to do&nbsp;so.</p> @@ -8840,7 +8880,7 @@ $ pip install gnome-background-generator <span class="w"> </span><span class="o">-</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">set</span><span class="o">-</span><span class="n">background</span><span class="w"> </span><span class="s1">&#39;&#39;&#39;try to set the background using gnome-appearance-</span> <span class="s1"> properties</span> <span class="s1"> -b, --debug</span> -</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html +</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html <ul> <li> <p>date<br>&nbsp;2010-10-10</p> @@ -8908,7 +8948,7 @@ that will work without effort over&nbsp;time.</p> <span class="p">}</span> </code></pre></div> -<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html +<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html <p>Those days, I&#8217;ve wrote a little python application to fit my blogging needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> @@ -8975,7 +9015,7 @@ optional<span class="w"> </span>arguments: <span class="w"> </span>-b,<span class="w"> </span>--debug </code></pre></div> -<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html +<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html <p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It was a really amazing experience, for many&nbsp;reasons.</p> @@ -9103,7 +9143,7 @@ into their offices from time to time, to share they cheerfulness ! Many thanks too to the Google Summer of Code program for setting up such an initiative. If you&#8217;re a student, if you&#8217;re interested about <span class="caps">FOSS</span>, dont hesitate any second, it&#8217;s a really good opportunity to work on -interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html +interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html <ul> <li> <p>date<br>&nbsp;2010-07-06</p> @@ -9189,7 +9229,7 @@ seems to be a must-read, so, I know what to&nbsp;do.</p> <p>It was really great. Next time, we&#8217;ll need to focus a bit more on distutils2, and to have a bullet list of things to do, but days like this one are opportunities to catch ! We&#8217;ll probably do another sprint -in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html +in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html <p>I&#8217;m working for about a month for distutils2, even if I was being a bit busy (as I had some class courses and exams to work&nbsp;on)</p> <p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so @@ -9293,7 +9333,7 @@ avoid some changes on the <span class="caps">API</span>, and some lo <p>Also, I&#8217;ve set up <a href="http://wiki.notmyidea.org/distutils2_schedule">a schedule</a>, and the goal is to be sure everything will be ready in time, for the end of the -summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html +summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html <ul> <li> <p>date<br>&nbsp;2010-06-25</p> @@ -9338,7 +9378,7 @@ source</a>, used</a>, and the command line to generate the <span class="caps">PDF</span>:</p> <div class="highlight"><pre><span></span><code>rst2pdf couchdb.rst -b1 -s ../slides.style -</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html +</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html <p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> during the past week, taking part of the <a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short @@ -9400,7 +9440,7 @@ grabbed code, and do some software design work (to not expose all things as privates methods, have a clear <span class="caps">API</span>, and other things like this), then update the tests accordingly and write a documentation to make this&nbsp;clear.</p> <p>Next step is to a little client, as I&#8217;ve <a href="http://github.com/ametaireau/pypiclient">already started -here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html +here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html <p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> program, and will work on <a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> @@ -9429,7 +9469,7 @@ the <a href="http://www.python.org/dev/peps/pep-0376/"><span class="ca <li>PyPI <span class="caps">XML</span>-<span class="caps">RPC</span> client for distutils 2: <a href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> </ul> -<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00tag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y.html +<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00tag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y.html <p>Ouf, notre <a href="http://www.reseaugrappe.org">semaine de l&#8217;environnement</a> s&#8217;est terminée, après un peu de neige et un brin de soleil quand il en fallait&nbsp;!</p> @@ -9642,7 +9682,7 @@ python</a> sur mon profil, peut c&#8217;est ce qui m&#8217;agaçait avec <span class="caps">PHP</span> qui est un langage à typage faible&nbsp;dynamique.</li> </ul> <p>Cous pouvez également aller regarder <a href="http://video.pycon.fr/videos/free/53/">l&#8217;atelier donné par Victor Stinner -durant le Pyconfr 09</a>. Have fun&nbsp;!</p>AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00tag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e.html +durant le Pyconfr 09</a>. Have fun&nbsp;!</p>AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00tag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e.html <p>Le raccourci me semble un peu rapide. Et pourtant, il est emprunté bien trop souvent. La dernière <em>mes-utilisation</em> que j&#8217;ai à décrier est celle d&#8217;un reportage télé, passé sur France 2 vendredi 23 Octobre (<a href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la diff --git a/feeds/all-fr.atom.xml b/feeds/all-fr.atom.xml index 5ffa7e2..5047b3e 100644 --- a/feeds/all-fr.atom.xml +++ b/feeds/all-fr.atom.xml @@ -93,7 +93,7 @@ pourrait ressembler à ceci&nbsp;:</p> <span class="n">collection_hash</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> </pre></div> </div> -Service de nuages : Perspectives pour l’été2015-07-07T00:00:00+02:002015-07-07T00:00:00+02:00tag:blog.notmyidea.org,2015-07-07:/service-de-nuages-perspectives-pour-lete-fr.html<p class="first last">Le travail en cours et les fonctionnalités à venir pour les prochains&nbsp;mois.</p> +Service de nuages : Perspectives pour l’été2015-07-07T00:00:00+02:002015-07-07T00:00:00+02:00tag:blog.notmyidea.org,2015-07-07:/service-de-nuages-perspectives-pour-lete-fr.html<p class="first last">Le travail en cours et les fonctionnalités à venir pour les prochains&nbsp;mois.</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p>Mozilla a pour coutume d&#8217;organiser régulièrement des semaines de travail où tous les employés sont réunis physiquement. Pour cette dernière édition, nous avons pu retrouver @@ -258,7 +258,7 @@ construire une solution libre, générique, simple et auto-hébergeable pour le de données sur le Web&nbsp;:)</p> <img alt="Friday Night Party - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-top-roof.jpg" /> </div> -Service de nuages : Achievement unlocked2015-06-01T00:00:00+02:002015-06-01T00:00:00+02:00tag:blog.notmyidea.org,2015-06-01:/service-de-nuages-achievement-unlocked-fr.html<p class="first last">Après près de 3 mois intensifs, nous venons de <em>tagguer</em> Cliquet 2.0 +Service de nuages : Achievement unlocked2015-06-01T00:00:00+02:002015-06-01T00:00:00+02:00tag:blog.notmyidea.org,2015-06-01:/service-de-nuages-achievement-unlocked-fr.html<p class="first last">Après près de 3 mois intensifs, nous venons de <em>tagguer</em> Cliquet 2.0 et Kinto 1.0&nbsp;!</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p>Aujourd&#8217;hui, c&#8217;est jour de fête : nous venons de publier Cliquet <strong>2.0</strong> @@ -322,7 +322,7 @@ est <em>pluggable</em>).</td></tr> <tr><td class="label"><a class="fn-backref" href="#footnote-reference-4">[4]</a></td><td>La feuille de route de Kinto: <a class="reference external" href="https://github.com/mozilla-services/kinto/wiki/roadmap">https://github.com/mozilla-services/kinto/wiki/roadmap</a></td></tr> </tbody> </table> -Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> +Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p><strong>tl;dr: On a maintenant un super système de permission mais comment faire pour stocker et interroger ces permissions de manière efficace&nbsp;?</strong></p> <div class="section" id="la-problematique"> @@ -605,7 +605,7 @@ un objet et également de pouvoir récupérer tous les objets d&#8217;une collection pour un utilisateur si celui-ci n&#8217;a pas accès à tous les records de la collection, ou toutes les collections du&nbsp;bucket.</p> </div> -Service de nuages : La gestion des permissions2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00tag:blog.notmyidea.org,2015-05-01:/service-de-nuages-la-gestion-des-permissions-fr.html<p class="first last">Démystification du vocabulaire des permissions et proposition d&#8217;implémentation pour&nbsp;Kinto</p> +Service de nuages : La gestion des permissions2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00tag:blog.notmyidea.org,2015-05-01:/service-de-nuages-la-gestion-des-permissions-fr.html<p class="first last">Démystification du vocabulaire des permissions et proposition d&#8217;implémentation pour&nbsp;Kinto</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p>Dans le cadre de la création d&#8217;un service de stockage de données personnelles (Kinto), la gestion des permissions est un des gros challenges : qui doit avoir @@ -1210,7 +1210,7 @@ donner aux applications qui agissent en son&nbsp;nom.</p> réflexions, n&#8217;hésitez pas à nous interrompre pendant qu&#8217;il est encore temps&nbsp;!</p> </div> </div> -Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> +Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p>Pas mal de changements depuis le début de l&#8217;année pour l&#8217;équipe «cloud-services»&nbsp;francophone!</p> @@ -1281,4 +1281,4 @@ rassemblées dans le protocole (ou <em>Cliquet</em>), certains point et de vous présenter notre vision via des exemples et&nbsp;tutoriaux.</p> <p>À bientôt, donc&nbsp;!</p> </div> - \ No newline at end of file + \ No newline at end of file diff --git a/feeds/all.atom.xml b/feeds/all.atom.xml index f9e88c7..ea04a13 100644 --- a/feeds/all.atom.xml +++ b/feeds/all.atom.xml @@ -1,5 +1,39 @@ -Alexis Métaireauhttps://blog.notmyidea.org/2023-09-27T00:00:00+02:00llm command-line tips2023-09-27T00:00:00+02:002023-09-27T00:00:00+02:00tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p><p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to talk to a <span class="caps">SQLITE</span> database and answer in json, and <a href="https://github.com/jqlang/jq">jq</a> a command-line tool capable of doing requests for&nbsp;json.</p> +Alexis Métaireauhttps://blog.notmyidea.org/2023-09-29T00:00:00+02:002023, Semaine 392023-09-29T00:00:00+02:002023-09-29T00:00:00+02:00tag:blog.notmyidea.org,2023-09-29:/2023-semaine-39.html +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques …</dd></dl> +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques, pour finalement en changer et me questionner sur la partie <strong>metier</strong>, ce qui me semblait plus intéressant. A partir du moment où j&#8217;ai arrêté d&#8217;essayer d&#8217;appliquer une solution « déjà faite » j&#8217;ai pu me questionner sur le modèle de données et aller de l&#8217;avant. Étrangement c&#8217;est quand j&#8217;ai produit le moins de code que j&#8217;ai trouvé que j&#8217;étais le plus&nbsp;productif.</dd> +<dt>Notmyidea</dt> +<dd>Je n&#8217;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&nbsp;décider.</dd> +<dd>J&#8217;ai <del>procrastiné</del> passé beaucoup plus de temps que prévu sur la mise en place d&#8217;outils utiles pour moi, et à peaufiné mon site web. J&#8217;ai maintenant un bouncer <span class="caps">ZNC</span> et un <span class="caps">VPN</span> fait maison qui me permettent de travailler dans de meilleures conditions. Je suis à la fois content d&#8217;avoir pris le temps de mettre en place des outils, et en même temps j&#8217;ai une impression de&nbsp;procrastination.</dd> +</dl> +<h2 id="des-joies">Des&nbsp;joies</h2> +<ul> +<li>Avoir pris le temps d&#8217;aller « à la ville » pour passer du temps avec des amis et&nbsp;sociabiliser.</li> +<li>M&#8217;écouter et décider de dormir sur place pour travailler aussi sur Rennes le&nbsp;lendemain.</li> +<li>Aller à l&#8217;espace de coworkig à côté de chez&nbsp;moi.</li> +<li>Prendre le temps de faire des choses peu importantes entassées dans ma todolist depuis trop&nbsp;longtemps.</li> +<li>Récolter des fruits de discussions passées lors d&#8217;une soirée. Vive les todo-list&nbsp;!</li> +<li>Voir qu&#8217;une demande de modifications que j&#8217;ai faite soit appréciée et intégrée&nbsp;rapidement.</li> +<li>Dépanner le serveur de <a href="https://github.com/almet/copanier">copanier</a>, trouver le problème rapidement et le régler&nbsp;facilement.</li> +</ul> +<h2 id="des-peines">Des&nbsp;peines</h2> +<ul> +<li>Je suis retombé malade en fin de semaine, et donc bien fatigué. Ca impacte mon moral et ma capacité de&nbsp;concentration.</li> +<li>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&nbsp;autres.</li> +<li>Sentir que ma posture dans les conversations est plus ferme que par le passé. Je suis à la fois content de ne pas <strong>toujours</strong> me remettre en question, mais j&#8217;aimerai réussir à faire preuve de plus d&#8217;ouverture. Il faut trouver&nbsp;l&#8217;équilibre </li> +<li>Triste de voir des conflits escalader alors que ça pourrait être&nbsp;autrement.</li> +</ul> +<h2 id="vu-lu-ecoute">Vu, lu,&nbsp;écouté</h2> +<ul> +<li>🎮 J&#8217;ai continué <a href="https://fr.wikipedia.org/wiki/Baba_Is_You">Baba is you</a> avec Arthur. C&#8217;était sympa de se faire les reflexions à deux&nbsp;cerveaux.</li> +<li>▶︎ <a href="https://www.youtube.com/watch?app=desktop&amp;v=dVzfNZN9NKI&amp;list=PL8uoeex94UhFcwvAfWHybD7SfNgIUBRo-&amp;index=128">Vu une présentation sur DuckDB</a>, une base de données locale et minimaliste qui semble adaptée pour de la visualisation de données à grande&nbsp;échelle.</li> +</ul>llm command-line tips2023-09-27T00:00:00+02:002023-09-27T00:00:00+02:00tag:blog.notmyidea.org,2023-09-27:/llm-command-line-tips.html<p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to …</p><p>I&#8217;m using <a href="https://llm.datasette.io">llm</a> more and more, and today I had to find back prompts I used in the past. Here is a command I&#8217;ve been using, which allows me to filter the results based on what I want. It leverages <a href="https://sqlutils.datasette.io">sql-utils</a>, a cli tool which is able to talk to a <span class="caps">SQLITE</span> database and answer in json, and <a href="https://github.com/jqlang/jq">jq</a> a command-line tool capable of doing requests for&nbsp;json.</p> <p>All in all, it&#8217;s pretty satisfying to use. I finally got a simple way to query databases! I&#8217;m also using <a href="https://github.com/charmbracelet/glow">glow</a>, which is capable of transforming markdown into a better version on the&nbsp;terminal.</p> <div class="highlight"><pre><span></span><code>sqlite-utils<span class="w"> </span><span class="s2">&quot;</span><span class="k">$(</span>llm<span class="w"> </span>logs<span class="w"> </span>path<span class="k">)</span><span class="s2">&quot;</span><span class="w"> </span><span class="s2">&quot;SELECT * FROM responses WHERE prompt LIKE &#39;%search%&#39;&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>jq<span class="w"> </span><span class="s1">&#39;.[].response&#39;</span><span class="w"> </span>-r<span class="w"> </span><span class="p">|</span><span class="w"> </span>glow </code></pre></div> @@ -787,18 +821,22 @@ L&#8217;analyse, l’élaboration, la remise en question des relations de po <li>Clarifiez ce que vous voulez réellement : pour vous, pour les autres, et pour la&nbsp;relation.</li> <li>Demandez-vous ce que vous devriez faire pour aller vers ce que vous souhaitez réellement&nbsp;?</li> </ul> -<p><strong>Refusez le dualisme</strong> : -- 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&#8217;un <strong>et</strong> l&#8217;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&nbsp;sain.</p> +<p><strong>Refusez le dualisme</strong>&nbsp;:</p> +<ul> +<li>Alors que vous considérez ce que vous voulez, notez quand vous vous piégez vous-même dans un&nbsp;dualisme.</li> +<li>Cherchez comment faire l&#8217;un <strong>et</strong>&nbsp;l&#8217;autre.</li> +<li>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&nbsp;sain.</li> +</ul> <h3 id="decider-de-ses-histoires">Décider De Ses&nbsp;Histoires</h3> <p>Les histoires créent des émotions. Les émotions n&#8217;arrivent pas d&#8217;elles-mêmes, et sont liées à des histoires qu&#8217;on se&nbsp;raconte.</p> <p>Il peut être utile de séparer les faits des histoires qu&#8217;on se raconte pour pouvoir repenser nos&nbsp;émotions.</p> -<p>Le schéma peut être le suivant : -1. Voir et entendre (les faits) -2. Se raconter une histoire -3. Ressentir -4.&nbsp;Agir</p> +<p>Le schéma peut être le suivant&nbsp;:</p> +<ol> +<li>Voir et entendre (les&nbsp;faits)</li> +<li>Se raconter une&nbsp;histoire</li> +<li>Ressentir</li> +<li>Agir</li> +</ol> <h2 id="partie-2-comment-ouvrir-la-bouche">Partie 2 : Comment Ouvrir la&nbsp;Bouche</h2> <h3 id="apprendre-a-regarder">Apprendre à&nbsp;Regarder</h3> <p>Comment se rendre compte que la sécurité est mise en jeu ? Il faut apprendre à regarder et à capter les signes. Quand une conversation devient stressante, on a tendance à faire les mauvaises choses. Apprenez à regarder&nbsp;:</p> @@ -811,17 +849,21 @@ L&#8217;analyse, l’élaboration, la remise en question des relations de po </ul> <h3 id="securiser-la-conversation">Sécuriser la&nbsp;Conversation</h3> <p>Pour sécuriser la conversation, il faut réussir à sortir du contenu de la conversation d&#8217;abord. L&#8217;idée étant de se rendre compte quand les gens deviennent violents ou silencieux, pour renouer le dialogue. Une fois que c&#8217;est fait on peut reprendre la&nbsp;discussion.</p> -<p>Comprendre ce qui crée un risque pour la sécurité : -- <strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations ? -- <strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</p> +<p>Comprendre ce qui crée un risque pour la sécurité&nbsp;:</p> +<ul> +<li><strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations&nbsp;?</li> +<li><strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</li> +</ul> <p>Pour commencer la discussion, <strong>partagez vos bonnes intentions</strong> : qu&#8217;est-ce que vous voulez ? Pour vous et pour l&#8217;autre personne&nbsp;?</p> <p><strong>Excusez-vous</strong> lorsque c&#8217;est&nbsp;approprié.</p> <p><strong>Contrastez</strong> pour régler les incompréhensions : Commencez par ce que vous ne voulez pas dire, puis expliquez ce que vous voulez&nbsp;dire.</p> -<p>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 -- Brainstormez les nouvelles&nbsp;stratégies</p> +<p>Créez un objectif commun lorsque vous vous rendez compte que les choses sont compliquées&nbsp;:</p> +<ul> +<li>Dites que votre objectif est de trouver un but&nbsp;commun.</li> +<li>Reconnaissez les buts derrière les&nbsp;stratégies</li> +<li>Inventez un but&nbsp;commun</li> +<li>Brainstormez les nouvelles&nbsp;stratégies</li> +</ul> <h3 id="decrire-sa-vision-des-choses">Décrire Sa Vision Des&nbsp;Choses</h3> <h3 id="comprendre-les-visions-des-autres">Comprendre Les Visions Des&nbsp;Autres</h3> <h3 id="ecouter">Écouter</h3> @@ -1063,7 +1105,7 @@ sudo<span class="w"> </span>/bin/systemctl<span class="w"> < <div class="highlight"><pre><span></span><code>sudo certbot --nginx </code></pre></div> -<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Réveil difficile2022-05-30T00:00:00+02:002022-05-30T00:00:00+02:00tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p><p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente, venaient de&nbsp;bouger.</p> +<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Réveil difficile2022-05-30T00:00:00+02:002022-05-30T00:00:00+02:00tag:blog.notmyidea.org,2022-05-30:/reveil-difficile.html<p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente …</p><p>La discussion avait été transcendante. Difficile, même : mes repères s&#8217;estompaient, semblaient flous et d&#8217;un seul coup, se refermer sur moi-même. Je réalisais que ma place était ailleurs. Pas ailleurs physiquement, mais ailleurs <em>mentalement</em>. Je réalisais que les préceptes qui « dirigeaient » ma vie, de manière tellement certaine, tellement évidente, venaient de&nbsp;bouger.</p> <p>Comme si je sortais d&#8217;un ensorcellement, que mon comportement — ma perception, même — avaient étés durant des années différents, et que, enfin, je me réveillais. Avec un arrière-goût amer dans le fond du&nbsp;palais.</p> <p>L&#8217;incantation ne commençait pas : ses effets finissaient par disparaître. Comme sorti du brouillard, une certitude : bien que je n&#8217;étais pas le seul à réaliser le sort qui m&#8217;avait été réservé, beaucoup d&#8217;autres n&#8217;en avaient pas du tout conscience. Voire même : ceux qui n&#8217;en avaient pas conscience semblaient évoluer dans ce qui me semblait maintenant une béatitude <em>malaisante</em>.</p> <p>Certain⋅e⋅s s&#8217;injectaient même volontairement des <em>doses</em> de cette <em>potion</em> pour que le brouillard ne se dissipe pas. Et je comprends pourquoi : les effets sont puissants, ils rendent les frontières lisses, colorent les interstices, remplacent les malaises par des joies&nbsp;candides.</p> @@ -2296,9 +2338,9 @@ L&#8217;avantage de ce matériel c&#8217;est que c&#8217;est la < <p>Et quand on passe des tests à l’échelle, (de 20L à 1500L), on est moyennement rassurés&nbsp;!</p> <p>Après quelques brassins validés, on est un peu plus relax sur le sujet, et on a mis en place de quoi faire des expérimentations à petite échelle de manière simple : vu qu&#8217;on produit du moût toutes les semaines, on en utilise une partie pour faire quelques tests : changement de levure, adjonctions, changement des températures de fermentation,&nbsp;etc.</p> <p>Ah ça, c’est pas les idées qui nous manquent :-) Et c&#8217;est une super manière&nbsp;d&#8217;expérimenter.</p> -<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/experimentations/sobacha.png"></p> -<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/experimentations/monstrueuse-normalite.png"></p> -<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/experimentations/chainon-manquant.png"></p> +<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/un-an/sobacha.png"></p> +<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/un-an/monstrueuse-normalite.png"></p> +<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/un-an/chainon-manquant.png"></p> <h2 id="ouverture-au-public-evenements-et-equilibre">Ouverture au public, évènements et&nbsp;équilibre</h2> <p>On a pris le parti d&#8217;ouvrir le magasin toutes les fins de semaine (le jeudi et vendredi de 17h à 19h) et on est hyper contents de faire visiter la brasserie aux personnes qui passent de temps à autre. Pour nous, ça fait partie des plaisirs du métier. Par contre, on avait clairement sous estimé le temps que ça nous prendrait. On accueille beaucoup et les gens sont curieux. La fabrication de bière reste encore aujourd’hui quelque chose de nouveau pour la plupart, et il faut satisfaire cette curiosité (il faut plus de brasseries&nbsp;!).</p> <p>Ce qui se passe en ce moment sur la scène brassicole est génial : beaucoup de nouvelles brasseries proposent des produits exceptionnels, et les évènements se multiplient aux quatre coins de la France. On adore partager, goûter, discuter, mais on ne pensait pas être autant sollicités par des évènements extérieurs, souvent sur des week-end, et parfois loin. <strong>On souhaite garder un équilibre entre notre vie personnelle et notre vie professionnelle</strong>. Aller aux évènements aussi par plaisir. Être partout est probablement un des maux de notre temps ;-) À force de voir des brasseurs exténués, il y a de quoi se poser des questions sur la pérennité sur le long terme d’un rythme aussi&nbsp;effréné.</p> @@ -2392,7 +2434,7 @@ paiements s&#8217;effectuent directement entre&nbsp;nous.</p> <li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des&nbsp;chèques</a></li> <li><a href="https://docs.google.com/spreadsheets/d/1bnPRSvf2Q2RDxKerWnEqUyJjuCFePnVMq6pWo8LeA_k/edit?usp=sharing">une version « à remplir » de notre tableau de commandes</a> (le mieux est d&#8217;en faire une copie&nbsp;!).</li> </ul> -<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> +<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> <ul> <li>enregistrer une sélection de texte ainsi que son contexte: heure, site&nbsp;web.</li> <li>fonctionner sur&nbsp;Firefox;</li> @@ -2403,7 +2445,7 @@ paiements s&#8217;effectuent directement entre&nbsp;nous.</p> <p>J&#8217;ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j&#8217;ai baptisé « Webnotes ». C&#8217;est <a href="https://addons.mozilla.org/en-US/firefox/addon/wwebnotes/">une extension Firefox</a>, qui se configure assez simplement, et qui stocke les données dans une instance de <a href="http://kinto-storage.org/">Kinto</a>.</p> <p><img src="https://github.com/almet/webnotes/blob/master/webnotes.gif?raw=true" /></p> <p>C&#8217;est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué&nbsp;!</p> -<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Faire moins2018-01-25T00:00:00+01:002018-01-25T00:00:00+01:00tag:blog.notmyidea.org,2018-01-25:/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p><p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser un sujet en particulier) est l&#8217;occasion de contribuer à éviter notre société&nbsp;d&#8217;experts.</p> +<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Faire moins2018-01-25T00:00:00+01:002018-01-25T00:00:00+01:00tag:blog.notmyidea.org,2018-01-25:/faire-moins.html<p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser …</p><p>L&#8217;an dernier, j&#8217;ai décidé de faire moins de choses, ou plus exactement d&#8217;arrêter de faire de nouvelles choses. Choix assez difficile: j&#8217;aime découvrir de nouvelles pratiques, échanger sur des sujets que je connais pas, et surtout je crois que découvrir de nouvelles pratiques (sans nécessairement creuser un sujet en particulier) est l&#8217;occasion de contribuer à éviter notre société&nbsp;d&#8217;experts.</p> <p>Le hic, c&#8217;est que trop, c&#8217;est trop. J&#8217;ai donc décidé d&#8217;arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j&#8217;ai même arreté de faire des choses que j&#8217;avais commencé à faire (par exemple de l&#8217;escalade), me libérant du&nbsp;temps.</p> <p>Enfin ! Je retrouve ce précieux temps. Je retrouve ces moments d&#8217;ennui. Oui, je comprends bien que ça puisse parraître fou de voir quelqu&#8217;un se réjouir de son ennui… Cet ennui me permet de creuser de nouvelles idées, de reprendre ce bouquin qu&#8217;on avait laissé tomber sans trop de&nbsp;raison.</p> <p>Et surtout, c&#8217;est se retrouver à contrôler son&nbsp;engagement.</p>NEIPA #32017-12-29T00:00:00+01:002017-12-29T00:00:00+01:00tag:blog.notmyidea.org,2017-12-29:/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L&#8217;idée est de pouvoir les relire et m&#8217;améliorer au fur et à&nbsp;mesure.</em></p> @@ -2730,7 +2772,7 @@ ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez su coté pour avoir accès aux&nbsp;réponses.</li> </ul> <p>Bref, en espérant que ça vous serve ! Un petit pas dans la direction des données -rendues à leurs utilisateurs&nbsp;!</p>Cloisonnement des activités ?2016-05-25T00:00:00+02:002016-05-25T00:00:00+02:00tag:blog.notmyidea.org,2016-05-25:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques +rendues à leurs utilisateurs&nbsp;!</p>Cloisonnement des activités ?2016-05-25T00:00:00+02:002016-05-25T00:00:00+02:00tag:blog.notmyidea.org,2016-05-25:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques jours à l&#8217;occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas cette conférence, il s&#8217;agit d&#8217;un moment avec des gens chouettes qui se posent des questions sur leur metier, comment le vivre et …</p><p>Je vous écris depuis un train, en rentrant de Bordeaux où j&#8217;ai passé quelques @@ -2922,7 +2964,7 @@ la lecture de <a href="https://www.indolering.com/okturtles-dnschain-unblock- et interventions du développeur du projet m&#8217;ont fait changer&nbsp;d&#8217;avis.</p> <p>Reste encore la piste de <em>Namecoin Control</em> que je n&#8217;ai pas encore creusée. Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la -bienvenue sur ces&nbsp;sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> +bienvenue sur ces&nbsp;sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with&nbsp;information.</p> <p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. I need&nbsp;to.</p> <p>And this thing makes me feel uncomfortable at the end of the day, @@ -3069,7 +3111,7 @@ un tas de petites ressources (par catégorie par ex.). Les gros médias pourraie <h3 id="est-ce-quon-a-vraiment-besoin-dun-tracker">Est-ce qu&#8217;on à vraiment besoin d&#8217;un tracker&nbsp;?</h3> <p>Le support d&#8217;une <span class="caps">DHT</span> <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, mais pour l&#8217;instant pas encore implémenté. L&#8217;utilisation de la <span class="caps">DHT</span> BitTorrent -n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>L’horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00tag:blog.notmyidea.org,2016-03-02:/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. +n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>L’horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00tag:blog.notmyidea.org,2016-03-02:/lhorizon.html<p>headline : Temps de changer d&#8217;horizon. Mon départ de Mozilla et le début d&#8217;une nouvelle histoire. image :&nbsp;images/horizon.jpg</p> <blockquote> <p>L&#8217;Utopie, c&#8217;est l&#8217;horizon. C&#8217;est ce qui permet d&#8217;avoir une direction, @@ -3209,7 +3251,7 @@ pourrait ressembler à ceci&nbsp;:</p> <span class="n">collection_hash</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> </pre></div> </div> -Let’s Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> +Let’s Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> <blockquote> <p>It’s time for the Web to take a big step forward in terms …</p></blockquote><p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> <blockquote> @@ -3317,7 +3359,7 @@ compatible avec&nbsp;HAProxy:</p> </ul> <p>Et voila ! <a href="https://github.com/almet/infra/">Le tout est dans un dépot github</a>, si jamais ça peut vous servir, -tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des +tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des outils pour faire face à la surveillance généralisée, et notamment en rapport au chiffrement des données. Une de mes envies de l&#8217;époque était l&#8217;animation&nbsp;d&#8217;ateliers.</p> @@ -3445,7 +3487,7 @@ formation sur le sujet, j&#8217;ai donc décidé de publier les nôtres, afi co-construire avec d&#8217;autres des plans de&nbsp;formation.</p> <p>Ils sont pour l&#8217;instant disponibles <a href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The Docs</a>. Tous les -retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> +retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> <p>Et même si j&#8217;arrive à convaincre certains de …</p><p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> <p>Et même si j&#8217;arrive à convaincre certains de mes proches à installer <span class="caps">PGP</span>, je ne suis pas satisfait du résultat: les méta-données (qui contacte qui à quel moment, et pour lui dire quoi) transitent de toute manière, elles, en clair, à la vue de&nbsp;tous.</p> @@ -3462,7 +3504,7 @@ mail&nbsp;fonctionnel.</p> incriminer l&#8217;emmeteur du message&nbsp;(deniability);</li> </ul> <p>Avec au moins ces besoins en tête, il semble qu&#8217;une revue de l&#8217;ensemble des projets existants pointe du doigt vers <a href="https://github.com/agl/pond">pond</a>, ou vers <a href="https://www.whispersystems.org">Signal</a>.</p> -<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I +<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I want to share with the crypto community to actually see if any solution exists to solve this particular&nbsp;problem.</em></p> <p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in @@ -3561,7 +3603,7 @@ User-Agent (or the distributor of the User-Agent), a little green icon could be presented to the User, so they know that they can be confident about&nbsp;this.</p> <p>A bit like User-Agents do for <span class="caps">SSL</span>, but for the actual signature of the -files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel +files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel lors de la conception&nbsp;d&#8217;APIs.</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p><strong>tldr; Cliquet est un toolkit Python pour construire des APIs, qui implémente @@ -3662,7 +3704,7 @@ pour des millions d&#8217;utilisateurs et des retours d&#8217;expérienc de <em>Firefox Sync</em> pour la gestion de la concurrence et de&nbsp;l&#8217;«offline-first».</p> <p>Il est <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/api/index.html">documenté en détail</a>.</p> <p>Dans un monde idéal, ce protocole serait versionné, et formalisé dans une <span class="caps">RFC</span>. -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.). <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a></p> <table class="docutils footnote" frame="void" id="footnote-1" rules="none"> <colgroup><col class="label" /><col /></colgroup> @@ -3734,7 +3776,7 @@ au fur et à mesure que ses besoins se&nbsp;précisent.</p> mais rien n&#8217;empêcherait d&#8217;implémenter le stockage dans un modèle&nbsp;relationnel.</p> <p>Comme les composants peuvent être remplacés depuis la configuration, il est tout à fait possible d&#8217;étendre <em>Cliquet</em> avec des notions métiers ou des -technologies exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation +codes exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation de l&#8217;éco-système</a>.</p> <p>Dans les prochaines semaines, nous allons introduire la notion d&#8217;«évènements» (ou signaux), qui permettraient aux extensions de s&#8217;interfacer beaucoup plus&nbsp;proprement.</p> @@ -3885,7 +3927,7 @@ projets en&nbsp;cascade.</li> <blockquote> Pourquoi Python ?</blockquote> <p>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&nbsp;!</p> <p>Et puis, après avoir passé près d&#8217;un an sur un projet Node.js, l&#8217;équipe avait bien envie de refaire du&nbsp;Python.</p> @@ -3955,7 +3997,7 @@ il y a de grandes chances que nous agissions pour s&#8217;assurer que les ab et les mécanismes d&#8217;extension fournis permettent de l&#8217;implémenter sous forme&nbsp;d&#8217;extension.</p> </div> </div> -Charte et événements non-mixtes au sein de l’Afpy2015-07-09T00:00:00+02:002015-07-09T00:00:00+02:00tag:blog.notmyidea.org,2015-07-09:/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html +Charte et événements non-mixtes au sein de l’Afpy2015-07-09T00:00:00+02:002015-07-09T00:00:00+02:00tag:blog.notmyidea.org,2015-07-09:/charte-et-evenements-non-mixtes-au-sein-de-lafpy.html <p><em>Mail envoyé sur la liste de diffusion de l&#8217;<span class="caps">AFPY</span> en Juillet&nbsp;2015</em></p> <p>Bonjour à toutes et&nbsp;tous,</p> <p>Récemment, l&#8217;Afpy à pris la décision de ne pas relayer la tenue d&#8217;un @@ -4176,7 +4218,7 @@ construire une solution libre, générique, simple et auto-hébergeable pour le de données sur le Web&nbsp;:)</p> <img alt="Friday Night Party - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-top-roof.jpg" /> </div> -Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00tag:blog.notmyidea.org,2015-06-29:/roles.html<p>Headline : De l&#8217;importance des rôles informels et de leur partage au sein d&#8217;un&nbsp;groupe.</p> +Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00tag:blog.notmyidea.org,2015-06-29:/roles.html<p>Headline : De l&#8217;importance des rôles informels et de leur partage au sein d&#8217;un&nbsp;groupe.</p> <blockquote> <p>Un […] dispositif consiste à tenter de faire bouger les rôles (pré)acquis ou qui se fixent dans le groupe, les pousser ailleurs que @@ -4373,7 +4415,7 @@ est <em>pluggable</em>).</td></tr> <tr><td class="label"><a class="fn-backref" href="#footnote-reference-4">[4]</a></td><td>La feuille de route de Kinto: <a class="reference external" href="https://github.com/mozilla-services/kinto/wiki/roadmap">https://github.com/mozilla-services/kinto/wiki/roadmap</a></td></tr> </tbody> </table> -Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> +Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p><strong>tl;dr: On a maintenant un super système de permission mais comment faire pour stocker et interroger ces permissions de manière efficace&nbsp;?</strong></p> <div class="section" id="la-problematique"> @@ -4656,7 +4698,7 @@ un objet et également de pouvoir récupérer tous les objets d&#8217;une collection pour un utilisateur si celui-ci n&#8217;a pas accès à tous les records de la collection, ou toutes les collections du&nbsp;bucket.</p> </div> -Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote> +Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote> <p>Flip a bit in the communication between sender and recipient and they will experience decryption or verification errors. How high are the chances they will start to exchange the data in the clear rather than @@ -4725,7 +4767,7 @@ qui explique comment configurer son installation&nbsp;correctement.</p> <p>Le <a href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils de chiffrement d&#8217;échanges de messages et de <span class="caps">VPN</span> simples à utiliser, encore quelque chose à&nbsp;regarder.</p> -<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00tag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<hr> +<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00tag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<hr> <blockquote> <p>Low-risk, low-pressure, and love: The 3 rules of side projects. &#8212; <a href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side&nbsp;projects</a></p> @@ -4829,7 +4871,7 @@ exportées sur des serveurs de clés existants. C&#8217;est quelque chose soulève des questions qui méritent qu&#8217;on s&#8217;y attarde un&nbsp;brin.</p> <p>Par ailleurs, <a href="https://leap.se/nicknym">d&#8217;autres projets qui visent des objectifs similaires</a> existent, via le projet <span class="caps">LEAP</span>, mais -je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html +je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html <ul> <li>headline<br> Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de @@ -4893,7 +4935,7 @@ personnelles, en utilisant des phrases de passe plus&nbsp;complexes.</p&g <p>Reste encore la question de la sauvegarde de ces clés privées de manière chiffrée, que je n&#8217;ai pas encore résolue. Bref, tout cela me semble bien compliqué pour réussir à l&#8217;expliquer à des novices, qui pour certains ne -sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00tag:blog.notmyidea.org,2015-05-08:/chiffrement.html +sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00tag:blog.notmyidea.org,2015-05-08:/chiffrement.html <ul> <li>headline<br> Face a la surveillance généralisée, une seule solution, le @@ -4958,8 +5000,6 @@ sphère privée ce qui devrait l&#8217;être à&nbsp;priori.</p> Enigmail et de le configurer correctement. Ce n&#8217;est pas très compliqué et permet d&#8217;avoir des échanges chiffrés. <a href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à&nbsp;pas.</p> -<p>La clé publique pour me contacter est -<a href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et vous&nbsp;?</p> <p>Je vous invite à aller voir le documentaire Citizen Four, qui passe en salles. Si vous ni avez pas accès, vous pouvez le visionner ici, et éventuellement faire un don aux auteurs ou associations qui gravitent @@ -5624,7 +5664,7 @@ donner aux applications qui agissent en son&nbsp;nom.</p> réflexions, n&#8217;hésitez pas à nous interrompre pendant qu&#8217;il est encore temps&nbsp;!</p> </div> </div> -Eco-système et stockage générique2015-04-30T00:00:00+02:002015-04-30T00:00:00+02:00tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.html +Eco-système et stockage générique2015-04-30T00:00:00+02:002015-04-30T00:00:00+02:00tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.html <p><strong>tl;dr Nous devons construire un service de suivi de paiements, et nous hésitons à continuer à nous entêter avec notre propre solution de&nbsp;stockage/synchronisation.</strong></p> <p>Comme nous l&#8217;écrivions <a href="https://blog.notmyidea.org/service-de-nuages-fr.html">dans l&#8217;article @@ -5950,7 +5990,7 @@ Cloud Services</em>!</p> <li>Il existe le <a href="https://sharesome.5apps.com/">projet Sharesome</a> qui permet de partager publiquement des ressources de son <em>remote Storage</em>.</li> -</ol>Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> +</ol>Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> <p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> <p>Pas mal de changements depuis le début de l&#8217;année pour l&#8217;équipe «cloud-services»&nbsp;francophone!</p> @@ -6021,7 +6061,7 @@ rassemblées dans le protocole (ou <em>Cliquet</em>), certains point et de vous présenter notre vision via des exemples et&nbsp;tutoriaux.</p> <p>À bientôt, donc&nbsp;!</p> </div> -Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00tag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html +Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00tag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html <p>Un enfant demande à son père&nbsp;:</p> <blockquote> <p>Dis papa, quel est le secret pour être heureux&nbsp;?</p> @@ -6251,7 +6291,7 @@ in case that helps you to integrate with your&nbsp;projects.</p> (that&#8217;s a pyramid / cornice)&nbsp;app.</li> <li>It&#8217;s also interesting to note that Kumar put together <a href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for the django rest&nbsp;framework</a></li> -</ul>Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html +</ul>Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html <p>Aujourd&#8217;hui, mon métier est d&#8217;être développeur d&#8217;applications. Imaginer des solutions techniques pour faire marcher des logiciels, puis écrire les lignes de code&nbsp;nécessaires.</p> @@ -6346,7 +6386,7 @@ de génération de formulaires en ligne, qui ne soit pas centré sur les services de&nbsp;google…</p> <p>Allez, au boulot&nbsp;!</p> <p><span class="caps">PS</span>: je me rends compte après relecture que ce billet fait echo à un -billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="%7Bfilename%7D2011.05.travailler-moins-mieux.rst">sur le +billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler.html">sur le sens du travail et de l&#8217;informatique</a>, ça fait du bien&nbsp;:)</p>Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html @@ -6363,7 +6403,7 @@ restent&nbsp;intacts.</p> <p>Deux ans ça parait énorme, c&#8217;est le temps le plus long que j&#8217;ai passé à travailler sur un projet, avec quasiment les mêmes personnes. Si vous suivez un peu ces carnets, vous savez surement que j&#8217;ai beaucoup -travaillé avec <a href="ziade.org">Tarek</a> par&nbsp;exemple.</p> +travaillé avec <a href="https://ziade.org">Tarek</a> par&nbsp;exemple.</p> <p>Ça a été (et c&#8217;est toujours) un réel plaisir de bosser avec la personne dont j&#8217;avais lu les livres pour apprendre le python, merci&nbsp;!</p> <h2 id="services">Services</h2> @@ -6605,7 +6645,7 @@ que je veux me garder de coté, des pensées que je souhaite partager… Un endroit ou je peux venir écrire quelque chose et le compléter plus&nbsp;tard.</p> <p>Du coup, le flux Atom contiens désormais quelques notes sur des sujets variés. Ces notes ne sont pas relayées sur la page d&#8217;accueil, mais vous -pouvez les trouver dans <a href="%7Ccategory%7Cnotes">la section notes</a>.</p> +pouvez les trouver dans <a href="/notes">la section notes</a>.</p> <p>Je ne sais pas encore si il s&#8217;agit du meilleur endroit pour ça, mais peu importe, essayons. A bas la pudeur&nbsp;rédactionelle.</p> <p>J&#8217;ai du au passage chambouler un peu vos agrégateurs, pardonnez moi&nbsp;:)</p> @@ -7130,7 +7170,7 @@ want to either understand how <span class="caps">CORS</span> works, </ul> <p>Of course, the <span class="caps">W3C</span> specification is the best resource to rely on. This specification isn&#8217;t hard to read, so you may want to go through it. -Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>New year python meme, 20122013-01-07T00:00:00+01:002013-01-07T00:00:00+01:00tag:blog.notmyidea.org,2013-01-07:/new-year-python-meme-2012.html +Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>New year python meme, 20122013-01-07T00:00:00+01:002013-01-07T00:00:00+01:00tag:blog.notmyidea.org,2013-01-07:/new-year-python-meme-2012.html <p>This series, also known as &#8220;<a href="http://ziade.org">Tarek Ziadé</a> strikes again&#8221;, is a good occasion to take a look back at 2012 and see what I&#8217;ve done related to python. So, let&#8217;s&nbsp;try.</p> @@ -7285,7 +7325,7 @@ J&#8217;utilisais haproxy + stunnel, et la négiciation <span class="caps fois <span class="caps">SSL</span> et <span class="caps">TLS</span> activés, et SSLv2 désactivé, tout fonctionne&nbsp;mieux.</p> <h2 id="et-voila">Et&nbsp;voilà</h2> <p>Finalement, j&#8217;ai mon joli status-board qui tourne à merveille sur -<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00tag:blog.notmyidea.org,2012-12-28:/habitat-collectif.html +<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00tag:blog.notmyidea.org,2012-12-28:/habitat-collectif.html <p>Habiter à plusieurs, partager un lieu de vie, monter une communauté, changer nos modes de vie et prendre plus de temps les uns pour les&nbsp;autres.</p> <p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez&nbsp;moi.</p> @@ -7359,7 +7399,7 @@ PATH=.:\$PATH nc -w1 $(echo %h | sed &#39;s/^.*+//;/:/!s/$/ %p/;s/:/ /&# user &lt;monuser(root)&gt; IdentityFile &lt;chemin vers ma clé ssh pour le serveur publique&gt; hostname ip_serveur_publique+ip_serveur_privé -</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html +</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html <p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de regarder du coté de gnome 3, à&nbsp;nouveau.</p> @@ -7402,7 +7442,7 @@ que je liste&nbsp;ici.</p> donc je ne sais pas encore si ça va rester, mais pourquoi&nbsp;pas.</li> </ul> <p>Vous pouvez aller faire un tour sur <a href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> pour -en trouver d&#8217;autres à votre&nbsp;gout.</p>“Groovy”2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/groovy.html +en trouver d&#8217;autres à votre&nbsp;gout.</p>“Groovy”2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/groovy.html <p>“Groovy”, c&#8217;est comme ça que je l&#8217;aime la musique: peut importe le style finalement, la bonne musique c&#8217;est celle qui sonne, celle qui groove, celle qui fait que tu tapes du pied (le droit chez moi) et que que ta @@ -7573,7 +7613,7 @@ use it, really quickly (these examples are how to interact with&nbsp;daybed) <p>Finally, we were out of cheese so everyone headed back to their respective houses and&nbsp;cities.</p> -<p>Until next&nbsp;time?</p>Bière maison !2012-10-04T00:00:00+02:002012-10-04T00:00:00+02:00tag:blog.notmyidea.org,2012-10-04:/biere-maison.html +<p>Until next&nbsp;time?</p>Bière maison !2012-10-04T00:00:00+02:002012-10-04T00:00:00+02:00tag:blog.notmyidea.org,2012-10-04:/biere-maison.html <p>Et voilà, c&#8217;est notre troisième brassin. On a commencé à faire notre propre bière (avec un ami, Fred) il y a quasiment un an maintenant, et après quelques dératés, même s&#8217;il nous reste encore bien du chemin à @@ -7852,7 +7892,7 @@ community again and discuss how Circus can evolve in ways that are interesting to&nbsp;everyone.</p> <p>Tarek and me are going to <a href="http://python.ie/pycon/2012/">Pycon ireland</a>, feel free to reach us if you&#8217;re going there, we&#8217;ll be happy to meet and -enjoy&nbsp;beers!</p>Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00tag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla.html +enjoy&nbsp;beers!</p>Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00tag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla.html <p>Depuis que j&#8217;ai commencé à bosser chez Mozilla, je me retrouve assez souvent à expliquer ce que j&#8217;y fais. J&#8217;aime bien raconter l&#8217;histoire de Mozilla, la mission, et comment je m&#8217;y&nbsp;rattache.</p> @@ -8270,7 +8310,7 @@ this service description tool: it looks at what&#8217;s described and build- the documentation from&nbsp;it.</p> <p>The resulting branch is not merged yet. Still, you can <a href="https://github.com/mozilla-services/cornice/tree/refactor-the-world">have a look at it</a>.</p> -<p>Any suggestions are of course welcome&nbsp;:-)</p>Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00tag:blog.notmyidea.org,2012-04-30:/bidouille.html +<p>Any suggestions are of course welcome&nbsp;:-)</p>Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00tag:blog.notmyidea.org,2012-04-30:/bidouille.html <p>Bidouille bidouille&nbsp;bidouille.</p> <p>Je pense que je suis un bidouilleur logiciel: j&#8217;aime bien aller farfouiller dans le code pour comprendre comment tel ou tel programme @@ -8386,7 +8426,7 @@ qu&#8217;ils mentent avec leur soit disant&nbsp;soleil).</p> <p>Et c&#8217;est sans parler de <a href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la brasucade</a>&nbsp;…</p> <p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une -présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html +présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html <p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> <p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même chose, à quelques détails près: une page web avec un formulaire qui @@ -8571,7 +8611,7 @@ solutions ou&nbsp;suggestions.</p> <a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. N&#8217;hésitez pas à l&#8217;éditer et à ajouter vos commentaires, c&#8217;est son&nbsp;objectif!</p> <p>Merci à <a href="http://sneakernet.fr/">Arnaud</a> pour la relecture et la -correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html +correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html <p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> <p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> <p>A bunch of friends asked me twice for quite the same thing: a webpage @@ -8731,7 +8771,7 @@ is written in stone yet. Comments and proposals are&nbsp;welcome!</p> <a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don&#8217;t hesitate to add your thoughts and edit it, that&#8217;s what it&#8217;s made&nbsp;for!</p> <p>Thanks to <a href="http://sneakernet.fr/">Arnaud</a> and -<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00tag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique.html +<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00tag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique.html <p>Le framablog vient de publier <a href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l&#8217;article de <span class="caps">RMS</span> à propos des dangers du livre électronique</a>. @@ -8979,7 +9019,7 @@ clients to discover services in a nice&nbsp;way.</p> <p>Of course, we are open to all your ideas and patches! If you feel haskish and want to see the sources, <a href="https://github.com/mozilla-services/cornice">go grab them on github</a> , commit and send -us a pull&nbsp;request!</p>Quels usages pour l’informatique ?2011-12-01T00:00:00+01:002011-12-01T00:00:00+01:00tag:blog.notmyidea.org,2011-12-01:/quels-usages-pour-linformatique.html +us a pull&nbsp;request!</p>Quels usages pour l’informatique ?2011-12-01T00:00:00+01:002011-12-01T00:00:00+01:00tag:blog.notmyidea.org,2011-12-01:/quels-usages-pour-linformatique.html <p>Quand on termine ses études, on s&#8217;en pose un tas, des questions. Sur le métier que l&#8217;on veut faire, sur ce que ça signifie, sur le sens et la valeur du travail. Et j&#8217;en suis arrivé à faire un constat simple: @@ -9157,7 +9197,7 @@ flask for this (and I should release&nbsp;it!).</p> and would be happy to work with new people and implement new ideas. If you have a nice idea about this, if you want to tweak it or to fill bugs. Don&#8217;t hesitate a second! The project lives at -<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>La simplicité volontaire contre le mythe de l’abondance2011-10-01T00:00:00+02:002011-10-01T00:00:00+02:00tag:blog.notmyidea.org,2011-10-01:/la-simplicite-volontaire-contre-le-mythe-de-labondance.html +<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>La simplicité volontaire contre le mythe de l’abondance2011-10-01T00:00:00+02:002011-10-01T00:00:00+02:00tag:blog.notmyidea.org,2011-10-01:/la-simplicite-volontaire-contre-le-mythe-de-labondance.html <p>Paul Ariès dans la préface de &#8220;<a href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de l&#8217;abondance</a>&#8221;</p> @@ -9221,7 +9261,7 @@ languages (and the resulting script would be easier) to do so, but the resulting graph would probably be way less&nbsp;readable.</p> <p>You can find the script <a href="https://github.com/ametaireau/experiments">on my github account</a>. Feel free to adapt -it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html +it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html <p>Back in October, I released <a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of code I wrote to power this weblog. I had simple needs: I wanted to be @@ -9243,7 +9283,7 @@ different services such as twitter or piwik, import from dotclear and rss, fixed a number of mistakes and improved a lot the codebase. This was a proof that there is a bunch of people that are willing to make better softwares just for the sake of&nbsp;fun.</p> -<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html +<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html <p>Java provides some interesting libraries that have no exact equivalent in python. In my case, the awesome boilerpipe library allows me to remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other @@ -9321,7 +9361,7 @@ similar, but from&nbsp;python</p> <p>I must say I didn&#8217;t thought it could work so easily. This will allow me to extract text content from URLs and remove the <em>boilerplate</em> text easily for infuse (my master thesis project), without having to write -java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html +java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html <p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais besoin d&#8217;un petit coup de&nbsp;main.</p> @@ -9354,7 +9394,7 @@ téléchargé et le compte créé il faut renseigner vos identifiants dans le plugin en question, et c&#8217;est&nbsp;tout!</p> <p>A votre bon cœur ! Je récupérerais probablement des données durant les 2 prochains mois pour ensuite les analyser&nbsp;correctement.</p> -<p>Merci pour votre aide&nbsp;!</p>Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00tag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler.html +<p>Merci pour votre aide&nbsp;!</p>Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00tag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler.html <p>Je viens de passer une semaine et demi quasiment hors-ligne et je dois dire que je suis assez impressionné du résultat: je suis de retour chez mes parents pour le &#8220;easter break&#8221; et j&#8217;en ai profité pour donner un @@ -9594,7 +9634,7 @@ complete novice in that&nbsp;field.</p> <li>Analyse web pages in order to categorize them. Processing their contents as well, to do some keyword based classification will be&nbsp;done.</li> </ul> -<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html +<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html <p>I have a server running freebsd since some time now, and was wondering about the possibility to directly have a development environment ready to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> @@ -9750,7 +9790,7 @@ its&nbsp;content.</p> <p>And it comes from <a href="http://ubuntuforums.org/showthread.php?p=10148738#post10148738">here</a>.</p> <p>A sync takes about 20s + the upload time on my machine, which stay -acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html +acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html <p>Finally, thanks to a bunch of people that helped me to pay my train and bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> <p>They have been a bit more than 10 people to come during the sprint, and @@ -9792,7 +9832,7 @@ the tubes, and will be ready for a release (hopefully) at the end of the&nbs providing us food, and to bearstech for providing some money for breakfast and&nbsp;bears^Wbeers.</p> <p>Again, a big thanks to all the people who gave me money to pay the -transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html +transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html <p>By now, there are two ways to retrieve data from PyPI (the Python Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several @@ -9881,7 +9921,7 @@ store in&nbsp;couchdb:</p> <p>The work I&#8217;ve done by now is available on <a href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it&#8217;s still a work in progress, and everything can break at any time. However, -any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html +any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html <p><strong>Edit: Thanks to logilab and some amazing people, I can make it to paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> <p>There will be a distutils2 sprint from the 27th to the 30th of january, @@ -9905,7 +9945,7 @@ help while&nbsp;needed.</p> <p>If you want to contribute some money to help me go there, feel free to use this chipin page: <a href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> -<p>Thanks for your support&nbsp;!</p>Fork you! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00tag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html +<p>Thanks for your support&nbsp;!</p>Fork you! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00tag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html <p>With <a href="http://github.com">github</a> and <a href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the developpers: it&#8217;s now easy to get feedback on your @@ -10068,7 +10108,7 @@ the command line tools curl, grep and tail (but really harder to&nbsp;read). <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> <span class="n">url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="o">.</span><span class="n">urljoin</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">boxurl</span><span class="p">,</span> <span class="n">REBOOT_URL</span><span class="p">)</span> <span class="n">reboot</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> -</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html +</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html <p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s not so easy, and you can&#8217;t just tell: use the pictures in this folder to do&nbsp;so.</p> @@ -10122,7 +10162,7 @@ $ pip install gnome-background-generator <span class="w"> </span><span class="o">-</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">set</span><span class="o">-</span><span class="n">background</span><span class="w"> </span><span class="s1">&#39;&#39;&#39;try to set the background using gnome-appearance-</span> <span class="s1"> properties</span> <span class="s1"> -b, --debug</span> -</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html +</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html <ul> <li> <p>date<br>&nbsp;2010-10-10</p> @@ -10190,7 +10230,7 @@ that will work without effort over&nbsp;time.</p> <span class="p">}</span> </code></pre></div> -<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html +<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html <p>Those days, I&#8217;ve wrote a little python application to fit my blogging needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> @@ -10257,7 +10297,7 @@ optional<span class="w"> </span>arguments: <span class="w"> </span>-b,<span class="w"> </span>--debug </code></pre></div> -<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html +<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html <p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It was a really amazing experience, for many&nbsp;reasons.</p> @@ -10385,7 +10425,7 @@ into their offices from time to time, to share they cheerfulness ! Many thanks too to the Google Summer of Code program for setting up such an initiative. If you&#8217;re a student, if you&#8217;re interested about <span class="caps">FOSS</span>, dont hesitate any second, it&#8217;s a really good opportunity to work on -interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html +interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html <ul> <li> <p>date<br>&nbsp;2010-07-06</p> @@ -10471,7 +10511,7 @@ seems to be a must-read, so, I know what to&nbsp;do.</p> <p>It was really great. Next time, we&#8217;ll need to focus a bit more on distutils2, and to have a bullet list of things to do, but days like this one are opportunities to catch ! We&#8217;ll probably do another sprint -in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html +in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html <p>I&#8217;m working for about a month for distutils2, even if I was being a bit busy (as I had some class courses and exams to work&nbsp;on)</p> <p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so @@ -10575,7 +10615,7 @@ avoid some changes on the <span class="caps">API</span>, and some lo <p>Also, I&#8217;ve set up <a href="http://wiki.notmyidea.org/distutils2_schedule">a schedule</a>, and the goal is to be sure everything will be ready in time, for the end of the -summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html +summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html <ul> <li> <p>date<br>&nbsp;2010-06-25</p> @@ -10620,7 +10660,7 @@ source</a>, used</a>, and the command line to generate the <span class="caps">PDF</span>:</p> <div class="highlight"><pre><span></span><code>rst2pdf couchdb.rst -b1 -s ../slides.style -</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html +</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html <p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> during the past week, taking part of the <a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short @@ -10682,7 +10722,7 @@ grabbed code, and do some software design work (to not expose all things as privates methods, have a clear <span class="caps">API</span>, and other things like this), then update the tests accordingly and write a documentation to make this&nbsp;clear.</p> <p>Next step is to a little client, as I&#8217;ve <a href="http://github.com/ametaireau/pypiclient">already started -here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html +here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html <p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> program, and will work on <a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> @@ -10711,7 +10751,7 @@ the <a href="http://www.python.org/dev/peps/pep-0376/"><span class="ca <li>PyPI <span class="caps">XML</span>-<span class="caps">RPC</span> client for distutils 2: <a href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> </ul> -<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00tag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y.html +<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00tag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y.html <p>Ouf, notre <a href="http://www.reseaugrappe.org">semaine de l&#8217;environnement</a> s&#8217;est terminée, après un peu de neige et un brin de soleil quand il en fallait&nbsp;!</p> @@ -10924,7 +10964,7 @@ python</a> sur mon profil, peut c&#8217;est ce qui m&#8217;agaçait avec <span class="caps">PHP</span> qui est un langage à typage faible&nbsp;dynamique.</li> </ul> <p>Cous pouvez également aller regarder <a href="http://video.pycon.fr/videos/free/53/">l&#8217;atelier donné par Victor Stinner -durant le Pyconfr 09</a>. Have fun&nbsp;!</p>AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00tag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e.html +durant le Pyconfr 09</a>. Have fun&nbsp;!</p>AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00tag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e.html <p>Le raccourci me semble un peu rapide. Et pourtant, il est emprunté bien trop souvent. La dernière <em>mes-utilisation</em> que j&#8217;ai à décrier est celle d&#8217;un reportage télé, passé sur France 2 vendredi 23 Octobre (<a href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la diff --git a/feeds/code.atom.xml b/feeds/code.atom.xml index a10ded2..d7e63d0 100644 --- a/feeds/code.atom.xml +++ b/feeds/code.atom.xml @@ -483,4 +483,6236 @@ local domain were tooking&nbsp;5s.</p> <p>If the answer to <code>scutil --get LocalHostName</code>, <code>hostname</code> and <code>scutil --get HostName</code> differ, then you might be in this case. Here is the fix&nbsp;:</p> <div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>scutil<span class="w"> </span>--set<span class="w"> </span>HostName<span class="w"> </span>&lt;YourHostName&gt; -</code></pre></div> \ No newline at end of file +</code></pre></div>Installation de Mosquitto, InfluxDB, Telegraf et Grafana2022-08-29T00:00:00+02:002022-08-29T00:00:00+02:00tag:blog.notmyidea.org,2022-08-29:/installation-de-mosquitto-influxdb-telegraf-et-grafana.html<p>Récemment, on a m&#8217;a demandé un petit coup de main pour aider à l&#8217;installation d&#8217;une pile logicielle qui permet de stocker des données temporelles et en faire des&nbsp;graphiques.</p> +<p>Voici donc quelques notes prises durant l&#8217;installation du système, concues pour que des personnes qui n&#8217;y …</p><p>Récemment, on a m&#8217;a demandé un petit coup de main pour aider à l&#8217;installation d&#8217;une pile logicielle qui permet de stocker des données temporelles et en faire des&nbsp;graphiques.</p> +<p>Voici donc quelques notes prises durant l&#8217;installation du système, concues pour que des personnes qui n&#8217;y connaissent pas grand chose puissent s&#8217;y&nbsp;retrouver.</p> +<p>L&#8217;objectif, c&#8217;est d&#8217;avoir des cartes Arduino qui envoient des données de manière régulière sur un système qui va nous permettre de les stocker et d&#8217;en faire des&nbsp;graphiques.</p> +<p>Pour ça, nous allons utiliser&nbsp;:</p> +<ul> +<li>Un <em>Broker</em> <a href="https://mosquitto.org/">Mosquitto</a> qui va permettre de receptionner les données depuis les différents <em>clients</em>, puis de les dispatcher à qui en a besoin&nbsp;;</li> +<li>Une base de données <a href="https://www.influxdata.com/products/influxdb-overview/">InfluxDB</a>, qui permet de stocker des données temporelles&nbsp;;</li> +<li>Un <em>agent</em> <a href="https://www.influxdata.com/time-series-platform/telegraf/">Telegraf</a> qui va prendre les données du broker et les stocker dans la base de données&nbsp;InfluxDB.</li> +<li><a href="https://grafana.com/">Grafana</a>, une <em>application web</em> qui permet de visualiser les données stockées dans&nbsp;InfluxDB.</li> +</ul> +<p>Voici donc un document qui résume les étapes que j&#8217;ai suivies pour mettre en place les différents élements utiles&nbsp;:</p> +<h2 id="installer-et-se-connecter-au-serveur">Installer et se connecter au&nbsp;serveur</h2> +<p>Dans notre cas, on est passé par un <span class="caps">VPS</span> chez <span class="caps">OVH</span>, qui tourne sous <a href="https://www.debian.org/">Debian 11</a>, qui a le mérite d&#8217;être une distribution Linux stable, reconnue et (relativement) simple à&nbsp;utiliser.</p> +<p>Dans un terminal, vous pouvez vous connecter en utilisant la ligne de commande suivante&nbsp;:</p> +<p><em>Les lignes suivantes sont des lignes d&#8217;invite de commande, on les rencontre assez souvent dans les documentations sur le web. Le signe <code>$</code> signifie le début de la ligne de commande. Le signe <code>#</code> signifie le début des&nbsp;commentaires.</em></p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>utilisateur@adresseip +</code></pre></div> + +<p>Une fois connecté, on va mettre à jour les logiciels qui sont présents sur le&nbsp;serveur. </p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>update<span class="w"> </span><span class="c1"># mise à jour des dépôts (la liste des logiciels).</span> +$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>upgrade<span class="w"> </span><span class="c1"># mise à jour des logiciels.</span> +</code></pre></div> + +<h2 id="configurer-les-dns">Configurer les <span class="caps">DNS</span></h2> +<p>Nous allons avoir besoin de deux sous domaines qui redirigent vers le serveur. Bien sur, il faut adapter <code>ndd.tld</code> et le remplacer par votre nom de domaine&nbsp;:</p> +<ol> +<li>moquitto.ndd.tld</li> +<li>graphs.ndd.tld</li> +</ol> +<p>Pour faire ça, chez <span class="caps">OVH</span> ça se passe dans la console de « <span class="caps">OVH</span> Cloud », direction « Noms de domaines », et puis il faut rajouter deux enregistrements de type « A » qui pointent vers l&#8217;adresse <span class="caps">IP</span> du&nbsp;serveur.</p> +<p>En temps normal, l&#8217;adresse <span class="caps">IP</span> vous est fournie par <span class="caps">OVH</span>. Si vous avez un doute, vous pouvez l&#8217;obtenir depuis le serveur avec la commande <code>ip a</code>.</p> +<h2 id="installer-mosquitto">Installer&nbsp;Mosquitto</h2> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>mosquitto<span class="w"> </span><span class="c1"># installation depuis les dépots officiels</span> +</code></pre></div> + +<p>Une fois installé, <a href="https://mosquitto.org/documentation/authentication-methods/">il faut sécuriser l&#8217;installation avec un utilisateur et un mot de passe</a>.</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>mosquitto_passwd<span class="w"> </span>-c<span class="w"> </span>/etc/mosquitto/passwd<span class="w"> </span>&lt;username&gt; +</code></pre></div> + +<p>Ensuite dans le fichier de configuration il faut spécifier où est le fichier qui contient les mots de passe. Pour éditer je recommande l&#8217;utilisation de l&#8217;éditeur de texte <code>nano</code>. </p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>nano<span class="w"> </span>/etc/mosquitto/mosquitto.conf +</code></pre></div> + +<p>Voici les lignes à rajouter&nbsp;:</p> +<div class="highlight"><pre><span></span><code>listener 1883 +password_file /etc/mosquitto/passwd +</code></pre></div> + +<p>Puis il faut relancer le service mosquitto&nbsp;:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span>restart<span class="w"> </span>mosquitto +</code></pre></div> + +<p>Avant de pouvoir utiliser mosquitto, il faut <a href="https://docs.ovh.com/gb/en/dedicated/firewall-network/">régler le firewall</a> de chez <span class="caps">OVH</span> pour qu&#8217;il accepte de laisser passer les messages pour le broker <span class="caps">MQTT</span>.</p> +<p>Il faut ajouter une règle dans le Firewall qui laisse passer toutes les connections <span class="caps">TCP</span>, avec l&#8217;option « établie&nbsp;».</p> +<h3 id="verifions-que-tout-fonctionne-comme-prevu">Vérifions que tout fonctionne comme prévu&nbsp;:</h3> +<p>Dans une console,&nbsp;écoutons…</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>mosquitto_sub<span class="w"> </span>-h<span class="w"> </span>mosquitto.ndd.tld<span class="w"> </span>-p<span class="w"> </span><span class="m">1883</span><span class="w"> </span>-u<span class="w"> </span>&lt;username&gt;<span class="w"> </span>-P<span class="w"> </span>&lt;password&gt;<span class="w"> </span>-t<span class="w"> </span>topic +</code></pre></div> + +<p>Et dans une autre envoyons un message&nbsp;:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>mosquitto_pub<span class="w"> </span>-h<span class="w"> </span>mosquitto.ndd.tld<span class="w"> </span>-p<span class="w"> </span><span class="m">1883</span><span class="w"> </span>-u<span class="w"> </span>&lt;username&gt;<span class="w"> </span>-P<span class="w"> </span>&lt;password&gt;<span class="w"> </span>-t<span class="w"> </span>topic<span class="w"> </span>-m<span class="w"> </span><span class="m">30</span> +</code></pre></div> + +<p>Vous deviez voir « 30 » apparaitre dans la première console. Si c&#8217;est bon, tout fonctionne&nbsp;!</p> +<h2 id="installation-dinfluxdb-et-telegraf">Installation d&#8217;InfluxDB et&nbsp;Telegraf</h2> +<p>Coup de bol, InfluxDB propose directement des packets pour Debian, sur leur dépot, qu&#8217;il faut donc ajouter en suivant ces quelques lignes&nbsp;:</p> +<div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>gnupg2<span class="w"> </span>curl<span class="w"> </span>wget +wget<span class="w"> </span>-qO-<span class="w"> </span>https://repos.influxdata.com/influxdb.key<span class="w"> </span><span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>apt-key<span class="w"> </span>add<span class="w"> </span>- +<span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;deb https://repos.influxdata.com/debian </span><span class="k">$(</span>lsb_release<span class="w"> </span>-cs<span class="k">)</span><span class="s2"> stable&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>tee<span class="w"> </span>/etc/apt/sources.list.d/influxdb.list +sudo<span class="w"> </span>apt<span class="w"> </span>update +</code></pre></div> + +<p>Puis <code>sudo apt install influxdb telegraf</code> pour&nbsp;l&#8217;installer.</p> +<p>Ensuite, vous pouvez le lancer maintenant et indiquer au système de le lancer tout seul au démarrage&nbsp;:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>--now<span class="w"> </span>influxdb +$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>--now<span class="w"> </span>telegraf +</code></pre></div> + +<h3 id="configuration-de-telegraf">Configuration de&nbsp;Telegraf</h3> +<p>Telegraf permet de faire le lien entre les messages envoyés sur le broker <span class="caps">MQTT</span> et la base de données&nbsp;InfluxDB.</p> +<p>Ici, il faut rentrer un peu plus dans le vif du sujet, et ça dépends des messages que vous avez à&nbsp;stocker.</p> +<p>Dans notre cas, nous avons trois types de messages&nbsp;:</p> +<ul> +<li>/BatVoltage,&nbsp;int</li> +<li>/Temperature,&nbsp;int</li> +<li>/<span class="caps">GPS</span>,&nbsp;string</li> +</ul> +<p>Voici un fichier de configuration, qui reste à modifier en fonction des&nbsp;données.</p> +<div class="highlight"><pre><span></span><code><span class="k">[global_tags]</span> +<span class="k">[agent]</span> +<span class="w"> </span><span class="na">interval</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;10s&quot;</span> +<span class="w"> </span><span class="na">round_interval</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span> +<span class="w"> </span><span class="na">metric_batch_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">1000</span> +<span class="w"> </span><span class="na">metric_buffer_limit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">10000</span> +<span class="w"> </span><span class="na">collection_jitter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0s&quot;</span> +<span class="w"> </span><span class="na">flush_interval</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;10s&quot;</span> +<span class="w"> </span><span class="na">flush_jitter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0s&quot;</span> +<span class="w"> </span><span class="na">precision</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0s&quot;</span> +<span class="w"> </span><span class="na">hostname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;&quot;</span> +<span class="w"> </span><span class="na">omit_hostname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span> + +<span class="k">[[outputs.influxdb]]</span> +<span class="w"> </span><span class="na">urls</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">[&quot;http://127.0.0.1:8086&quot;]</span> +<span class="w"> </span><span class="na">database</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;telegraf&quot;</span> + +<span class="k">[[inputs.mqtt_consumer]]</span> +<span class="w"> </span><span class="na">servers</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">[&quot;tcp://127.0.0.1:1883&quot;]</span> +<span class="w"> </span><span class="na">name_override</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;mqtt_consumer_float&quot;</span> +<span class="w"> </span><span class="na">topics</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">[</span> +<span class="w"> </span><span class="na">&quot;Topic/BatVoltage&quot;,</span> +<span class="w"> </span><span class="na">&quot;Topic/Temperature&quot;,</span> +<span class="w"> </span><span class="na">]</span> +<span class="w"> </span><span class="na">username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;&lt;username&gt;&quot;</span> +<span class="w"> </span><span class="na">password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;&lt;password&gt;&quot;</span> +<span class="w"> </span><span class="na">data_format</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;value&quot;</span> +<span class="w"> </span><span class="na">data_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;integer&quot;</span> +</code></pre></div> + +<h2 id="installation-de-grafana">Installation de&nbsp;Grafana</h2> +<div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>apt-transport-https +sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>software-properties-common<span class="w"> </span>wget +sudo<span class="w"> </span>wget<span class="w"> </span>-q<span class="w"> </span>-O<span class="w"> </span>/usr/share/keyrings/grafana.key<span class="w"> </span>https://packages.grafana.com/gpg.key +<span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>tee<span class="w"> </span>-a<span class="w"> </span>/etc/apt/sources.list.d/grafana.list +sudo<span class="w"> </span>apt<span class="w"> </span>update +sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>grafana +sudo<span class="w"> </span>/bin/systemctl<span class="w"> </span>daemon-reload +sudo<span class="w"> </span>/bin/systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>grafana-server +sudo<span class="w"> </span>/bin/systemctl<span class="w"> </span>start<span class="w"> </span>grafana-server +</code></pre></div> + +<h3 id="nginx">Nginx</h3> +<div class="highlight"><pre><span></span><code>sudo apt install nginx certbot python3-certbot-nginx +</code></pre></div> + +<p>Puis il faut créer un fichier de configuration dans <code>/etc/nginx/sites-enabled/graphs.ndd.tld</code> avec le contenu suivant&nbsp;:</p> +<div class="highlight"><pre><span></span><code><span class="k">map</span><span class="w"> </span><span class="nv">$http_upgrade</span><span class="w"> </span><span class="nv">$connection_upgrade</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="kn">default</span><span class="w"> </span><span class="s">upgrade</span><span class="p">;</span> +<span class="w"> </span><span class="kn">&#39;&#39;</span><span class="w"> </span><span class="s">close</span><span class="p">;</span> +<span class="p">}</span> + +<span class="k">upstream</span><span class="w"> </span><span class="s">grafana</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="kn">server</span><span class="w"> </span><span class="n">localhost</span><span class="p">:</span><span class="mi">3000</span><span class="p">;</span> +<span class="p">}</span> + +<span class="k">server</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="kn">listen</span><span class="w"> </span><span class="mi">80</span><span class="p">;</span> +<span class="w"> </span><span class="kn">server_name</span><span class="w"> </span><span class="s">graphs.ndd.tld</span><span class="p">;</span> +<span class="w"> </span><span class="kn">root</span><span class="w"> </span><span class="s">/usr/share/nginx/html</span><span class="p">;</span> +<span class="w"> </span><span class="kn">index</span><span class="w"> </span><span class="s">index.html</span><span class="w"> </span><span class="s">index.htm</span><span class="p">;</span> + +<span class="w"> </span><span class="kn">location</span><span class="w"> </span><span class="s">/</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Host</span><span class="w"> </span><span class="nv">$http_host</span><span class="p">;</span> +<span class="w"> </span><span class="kn">proxy_pass</span><span class="w"> </span><span class="s">http://grafana</span><span class="p">;</span> +<span class="w"> </span><span class="p">}</span> + +<span class="w"> </span><span class="c1"># Proxy Grafana Live WebSocket connections.</span> +<span class="w"> </span><span class="kn">location</span><span class="w"> </span><span class="s">/api/live/</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="kn">proxy_http_version</span><span class="w"> </span><span class="mi">1</span><span class="s">.1</span><span class="p">;</span> +<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Upgrade</span><span class="w"> </span><span class="nv">$http_upgrade</span><span class="p">;</span> +<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Connection</span><span class="w"> </span><span class="nv">$connection_upgrade</span><span class="p">;</span> +<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Host</span><span class="w"> </span><span class="nv">$http_host</span><span class="p">;</span> +<span class="w"> </span><span class="kn">proxy_pass</span><span class="w"> </span><span class="s">http://grafana</span><span class="p">;</span> +<span class="w"> </span><span class="p">}</span> +<span class="p">}</span> +</code></pre></div> + +<p>Une fois ces fichiers de configuration en place, il faut penser à la mise en place du <span class="caps">SSL</span> qui permet d&#8217;avoir une connexion sécurisée&nbsp;(https).</p> +<p>Il suffit de lancer cette ligne de commande et de suivre les questions posées&nbsp;:</p> +<div class="highlight"><pre><span></span><code>sudo certbot --nginx +</code></pre></div> + +<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Groupement d’achats & partage d’expérience2018-03-03T00:00:00+01:002018-03-03T00:00:00+01:00tag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.html<p>Il y a quelques années, on s&#8217;est motivé entre copains copines pour créer un groupement&nbsp;d&#8217;achat.</p> +<p>L&#8217;idée est&nbsp;simple:</p> +<ul> +<li>commander en gros, pour faire baisser les&nbsp;prix</li> +<li>se passer d&#8217;intermédiaires et favoriser les circuits&nbsp;courts</li> +<li>aller à la rencontre des producteurs locaux et&nbsp;échanger</li> +</ul> +<p>Notre groupement …</p><p>Il y a quelques années, on s&#8217;est motivé entre copains copines pour créer un groupement&nbsp;d&#8217;achat.</p> +<p>L&#8217;idée est&nbsp;simple:</p> +<ul> +<li>commander en gros, pour faire baisser les&nbsp;prix</li> +<li>se passer d&#8217;intermédiaires et favoriser les circuits&nbsp;courts</li> +<li>aller à la rencontre des producteurs locaux et&nbsp;échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers et une 60aine de&nbsp;personnes.</p> +<p>Au fur et à mesure de la vie du groupement, on a développé quelques outils pour se simplifier la vie. Voici un retour d&#8217;expérience et quelques astuces / outils, au cas où l&#8217;envie vous prenne à vous aussi&nbsp;:)</p> +<h1 id="organisation">Organisation</h1> +<p>On organise environs trois ou quatre distributions par an. Le <em>modus operandi</em> est le&nbsp;suivant:</p> +<ul> +<li>chaque product·eur·rice à un·e référent·e, qui s&#8217;occupe de faire le&nbsp;lien;</li> +<li>une personne est désignée pour coordonner la&nbsp;distribution;</li> +<li>4 semaines avant la distribution, les référent·e·s mettent à jour les prix / produits dans le tableau de&nbsp;commandes;·e·</li> +<li>3 semaines avant la distribution, les commandes sont&nbsp;ouvertes;</li> +<li>2 semaines avant la distribution, les commandes sont&nbsp;closes;</li> +<li>Les référent·e·s ont ensuite deux semaines pour récupérer les commandes pour la&nbsp;distribution</li> +</ul> +<h1 id="quels-produits">Quels produits&nbsp;?</h1> +<p>On essaye d&#8217;avoir uniquement des produits qui se conservent (on a également quelques autres produits plus frais, mais avec d&#8217;autres&nbsp;modalités).</p> +<p>Entre autres: bières, légumes secs, conserves, jus, miel, pâtes, semoule, café, vinaigres, pommes de terre, oignons, huiles,&nbsp;farines.</p> +<p>On essaye de faire du local puis du bio au plus proche plutôt que de trouver nécessairement les prix les plus bas. C&#8217;est une discussion qui revient assez +souvent, et donc un point à évoquer lors de la création pour avoir une posture +claire sur le sujet (tout le monde n&#8217;est pas animé par la même éthique&nbsp;!).</p> +<h1 id="paiements">Paiements</h1> +<p>Pour les paiements, on utilise autant que possible des chèques. Chaque référent·e paye la·le product·rice·eur en son nom, et lui demande d&#8217;attendre la date de la distribution pour l&#8217;encaissement. La plupart des producteurs acceptent d&#8217;être payés sous&nbsp;quinzaine.</p> +<p>Le jour de la distribution, tout le monde apporte son chéquier. Nous avons mis +en place une moulinette qui s&#8217;occupe de faire la répartition des chèques automatiquement, chaque membre se retrouve à faire en moyenne un ou deux&nbsp;chèques.</p> +<p>Chaque référent·e est ainsi remboursé·e de la somme avancée, et chaque +membre du groupement d&#8217;achat paye ce qu&#8217;il doit payer. Nous n&#8217;avons +volontairement pas de structure juridique et pas de compte en banque. Les +paiements s&#8217;effectuent directement entre&nbsp;nous.</p> +<h1 id="transports">Transports</h1> +<p>Chaque référent·e commande les produits, puis ensuite s&#8217;occupe de les rapatrier. À Rennes, on a la chance d&#8217;avoir pas mal de producteurs aux alentours, donc c&#8217;est assez&nbsp;simple.</p> +<p>Le mieux est de ramener les produits juste un peu avant la distribution au lieu de distribution, ça permet d&#8217;éviter de les stocker trop longtemps, et d&#8217;éviter aux producteurs d&#8217;attendre trop longtemps avant d&#8217;encaisser les&nbsp;chèques.</p> +<p>Pour les grosses commandes, les voitures se remplissent bien, mais ma petite Clio suffit, que ce soit dit&nbsp;!</p> +<h1 id="la-distribution">La&nbsp;distribution</h1> +<p>Un peu en amont de la distribution, il faut organiser l&#8217;espace. Des tas par membre sont constitués pour faciliter les choses le jour de la&nbsp;distribution.</p> +<p>Le jour même, on se retrouve, on charge ses marchandises, on échange quelques chèques et on papote ! On en profite&nbsp;pour:</p> +<ul> +<li>discuter de la date de la prochaine&nbsp;distribution;</li> +<li>trouver une nouvelle personne pour la&nbsp;coordonner;</li> +<li>discuter de nouveaux&nbsp;produits;</li> +<li>refaire le&nbsp;monde;</li> +<li>changer de référents pour les&nbsp;producteurs.</li> +</ul> +<p>Et c&#8217;est reparti pour un tour&nbsp;;)</p> +<h1 id="nos-outils">Nos&nbsp;outils</h1> +<p>On utilise un tableur en ligne pour partager les prix et prendre les commandes. On a essayé d&#8217;utiliser <em>ethercalc</em> au début mais ça ne fonctionnait pas pour nous à l&#8217;époque (trop de petits bugs). On a donc préféré utiliser Google docs&nbsp;(ouch).</p> +<p>Il est d&#8217;ailleurs possible d&#8217;y intégrer de nouvelles fonctionnalités assez facilement, du coup Fred et Rémy ont planché sur un moyen d&#8217;automatiser la répartition des chèques (qu&#8217;on faisait dans un premier temps à la main - assez&nbsp;péniblement).</p> +<p>Le système n&#8217;est pas parfait mais fonctionne quand même assez bien&nbsp;!</p> +<p>Quelques ressources,&nbsp;donc:</p> +<ul> +<li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des&nbsp;chèques</a></li> +<li><a href="https://docs.google.com/spreadsheets/d/1bnPRSvf2Q2RDxKerWnEqUyJjuCFePnVMq6pWo8LeA_k/edit?usp=sharing">une version « à remplir » de notre tableau de commandes</a> (le mieux est d&#8217;en faire une copie&nbsp;!).</li> +</ul> +<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> +<ul> +<li>enregistrer une sélection de texte ainsi que son contexte: heure, site&nbsp;web.</li> +<li>fonctionner sur&nbsp;Firefox;</li> +<li>stocker mes notes à un endroit que je contrôle (ce sont mes données, après tout&nbsp;!)</li> +<li>rester en dehors de mon chemin: je suis en train de lire, pas en train d&#8217;organiser mes&nbsp;notes.</li> +<li>automatiquement partager les notes sur une page&nbsp;web.</li> +</ul> +<p>J&#8217;ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j&#8217;ai baptisé « Webnotes ». C&#8217;est <a href="https://addons.mozilla.org/en-US/firefox/addon/wwebnotes/">une extension Firefox</a>, qui se configure assez simplement, et qui stocke les données dans une instance de <a href="http://kinto-storage.org/">Kinto</a>.</p> +<p><img src="https://github.com/almet/webnotes/blob/master/webnotes.gif?raw=true" /></p> +<p>C&#8217;est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué&nbsp;!</p> +<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Comment est-ce que vous générez vos formulaires ?2016-05-31T00:00:00+02:002016-05-31T00:00:00+02:00tag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.html<p><span class="caps">TL</span>; <span class="caps">DR</span>: Je viens à peine de <em>releaser</em> la première version d&#8217;un service de génération de formulaires. +Allez jeter un coup d&#8217;œil sur <a href="https://www.fourmilieres.net">https://www.fourmilieres.net</a></p> +<p><em>En février 2012, je parlais ici <a href="https://blog.notmyidea.org/carto-forms.html">d&#8217;un service de génération de formulaires</a>. +Depuis, pas mal d&#8217;eau à coulé sous …</em></p><p><span class="caps">TL</span>; <span class="caps">DR</span>: Je viens à peine de <em>releaser</em> la première version d&#8217;un service de génération de formulaires. +Allez jeter un coup d&#8217;œil sur <a href="https://www.fourmilieres.net">https://www.fourmilieres.net</a></p> +<p><em>En février 2012, je parlais ici <a href="https://blog.notmyidea.org/carto-forms.html">d&#8217;un service de génération de formulaires</a>. +Depuis, pas mal d&#8217;eau à coulé sous les ponts, on est passé par pas mal d&#8217;étapes pour +finalement arriver à une première version de ce service de génération de +formulaires (à la </em>google forms<em>).</em></p> +<p>En tant qu&#8217;organisateurs d&#8217;évènements (petits et gros), je me retrouve souvent +dans une situation ou je dois créer des formulaires pour recueillir des +informations. Actuellement, la meilleure solution disponible est <em>Google Forms</em>, +mais celle ci à plusieurs problèmes, à commencer par le fait que le code n&#8217;est +pas libre et que les données sont stockées chez&nbsp;Google.</p> +<p>La plupart du temps, le besoin est assez simple: je veux spécifier quelques +questions, et donner un lien à mes amis pour qu&#8217;ils puissent y répondre. +Je reviens ensuite plus tard pour voir la liste des réponses&nbsp;apportées.</p> +<p><img alt="Capture de l'interface de création du formulaire" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-build.png"></p> +<h2 id="fonctionnalites">Fonctionnalités</h2> +<p>Il existe pas mal de solutions techniques qui essayent de répondre à la même +problématique, mais la plupart d&#8217;entre elles sont assez souvent compliquées, +nécessitent de se créer un compte, et/ou ne vous laisse pas la main libre sur +les données générées, voire le code est assez difficile à faire évoluer ou à&nbsp;déployer.</p> +<p>Je voulais donc quelque chose de simple à utiliser <em>et</em> pour les créateurs de +formulaires <em>et</em> pour les utilisateurs finaux. Pas de chichis, juste quelques +vues, et des URLs à sauvegarder une fois l&#8217;opération&nbsp;terminée.</p> +<p><img alt="Capture de l'écran avec les URLs générées" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-created.png"> +<img alt="Capture d'écran d'un exemple de formulaire" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-form.png"></p> +<h3 id="pas-de-compte">Pas de&nbsp;compte</h3> +<p>Vous n&#8217;avez pas besoin d&#8217;avoir un compte sur le site pour commencer à l&#8217;utiliser. +Vous créez simplement un nouveau formulaire puis envoyez le lien à vos amis pour +qu&#8217;eux puissent à leur tour le&nbsp;remplir.</p> +<p><img alt="Capture de la page d'accueil, ou aucun compte n'est requis" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-welcome.png"></p> +<h3 id="gardez-la-main-sur-vos-donnees">Gardez la main sur vos&nbsp;données</h3> +<p>Une fois que vous avez récupéré les réponses à vos questions, vous pouvez +récupérer les données sur votre machines dans un fichier <code>.csv</code>.</p> +<p><img alt="Capture de la page de resultats, il est possible de télécharger en CSV." src="https://blog.notmyidea.org/images/formbuilder/formbuilder-results.png"></p> +<h3 id="api"><span class="caps">API</span></h3> +<p>L&#8217;ensemble des données sont en fait stockées dans <a href="https://kinto.readthedocs.org">Kinto</a> +qui est interrogeable très facilement en <span class="caps">HTTP</span>. Ce qui fait qu&#8217;il est très facile de +réutiliser les formulaires que vous avez construits (ou leurs réponses) depuis +d&#8217;autres&nbsp;outils.</p> +<h3 id="auto-hebergeable">Auto-hébergeable</h3> +<p>Un des objectifs de ce projet est de vous redonner la main sur vos données. +Bien sur, vous pouvez utiliser l&#8217;instance qui est mise à votre disposition sur +<a href="https://www.fourmilieres.net">wwww.fourmilieres.net</a>, mais vous pouvez +également l&#8217;héberger vous même très +simplement, et vous êtes d&#8217;ailleurs fortement encouragés à le faire ! Notre +objectif n&#8217;est pas de stocker l&#8217;ensemble des formulaires du monde, mais de +(re)donner le contrôle aux utilisateurs&nbsp;!</p> +<h2 id="on-commence-petit">On commence&nbsp;petit…</h2> +<p>Cette <em>release</em> n&#8217;est (bien sur) pas parfaite, et il reste encore pas mal de +travail sur cet outil, mais je pense qu&#8217;il s&#8217;agit d&#8217;une base de travail +intéressante pour un futur où Google n&#8217;a pas la main sur toutes nos&nbsp;données.</p> +<p>La liste des champs supportés est pour l&#8217;instant assez faible (Texte court, +Texte long, Oui/Non, choix dans une liste) mais elle à vocation à s&#8217;étendre, en +fonction des besoins de&nbsp;chacun.</p> +<p>J&#8217;ai d&#8217;ailleurs créé <a href="https://www.fourmilieres.net/#/form/cfd878264cec4ed2">un formulaire pour que vous puissiez me faire part de vos +retours</a>, n&#8217;hésitez pas&nbsp;!</p> +<h2 id="et-euh-comment-ca-marche">Et, euh, comment ça marche&nbsp;?</h2> +<p>Le <em>formbuilder</em>, comme j&#8217;aime l&#8217;appeler se compose en fin de compte de deux +parties&nbsp;distinctes:</p> +<ul> +<li><a href="https://kinto.readthedocs.org">Kinto</a>, un service qui stocke + des données coté serveur et qui les expose via des <strong>APIs <span class="caps">HTTP</span></strong></li> +<li><a href="https://github.com/kinto/formbuilder">Le formbuilder</a>, une application + JavaScript qui ne tourne que coté client (dans votre navigateur) qui permet + de construire les formulaires et d&#8217;envoyer les données sur les <em>APIs</em> coté&nbsp;serveur.</li> +</ul> +<p>Au niveau de la <em>stack</em> technique, le <strong>formbuilder</strong> est codé en ReactJS. Un +des points techniques intéressants du projet est qu&#8217;il génère en fin de compte du +<a href="http://jsonschema.net/"><span class="caps">JSON</span> Schema</a>, un format de validation de données <em><span class="caps">JSON</span></em>.</p> +<p>Donc, reprenons! Vous arrivez sur la page d&#8217;accueil puis cliquez sur +&#8220;Create a new form&#8221;, puis vous vous retrouvez face à une interface ou vous pouvez +ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez sur +&#8220;Create the&nbsp;form&#8221;.</p> +<ul> +<li>Le <span class="caps">JSON</span> Schema est alors envoyé au serveur Kinto, qui l&#8217;utilisera pour valider + les données qu&#8217;il recevra par la&nbsp;suite.</li> +<li>Ce <span class="caps">JSON</span> Schema sera aussi utilisé lors de l&#8217;affichage du formulaire aux + personnes qui le&nbsp;remplissent.</li> +<li>Un jeton d&#8217;accès est généré et ajouté à l&#8217;<span class="caps">URL</span>, il s&#8217;agit de l&#8217;identifiant du&nbsp;formulaire.</li> +<li>Un second jeton d&#8217;accès administrateur et généré, il vous faut le garder de + coté pour avoir accès aux&nbsp;réponses.</li> +</ul> +<p>Bref, en espérant que ça vous serve ! Un petit pas dans la direction des données +rendues à leurs utilisateurs&nbsp;!</p>Avez vous confiance en SSL?2016-03-25T00:00:00+01:002016-03-25T00:00:00+01:00tag:blog.notmyidea.org,2016-03-25:/avez-vous-confiance-en-ssl.html<p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d&#8217;autodéfense numérique</a>, +j&#8217;ai passé un peu de temps à creuser sur l&#8217;utilisation de <span class="caps">SSL</span> puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu&#8217;une connexion <span class="caps">SSL</span> est en cours) n&#8217;est …</p><p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d&#8217;autodéfense numérique</a>, +j&#8217;ai passé un peu de temps à creuser sur l&#8217;utilisation de <span class="caps">SSL</span> puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu&#8217;une connexion <span class="caps">SSL</span> est en cours) n&#8217;est +<strong>absolument</strong> pas&nbsp;suffisant.</p> +<p>Allez hop, c&#8217;est parti&nbsp;pour:</p> +<ul> +<li>un tour d&#8217;horizon du fonctionnement de&nbsp;SSl</li> +<li>quelques moyens contourner cette &#8220;protection&#8221; en faisant une attaque en&nbsp;pratique</li> +<li>un tour des solutions existantes actuellement et de pourquoi je ne les trouve + pas vraiment&nbsp;satisfaisantes.</li> +</ul> +<h2 id="comment-fonctionne-ssl">Comment fonctionne <span class="caps">SSL</span>?</h2> +<p>Pour expliquer les problèmes de <span class="caps">SSL</span>, j&#8217;ai d&#8217;abord besoin d&#8217;expliquer comment +tout ça&nbsp;fonctionne.</p> +<p><span class="caps">SSL</span> repose sur l&#8217;utilisation de certificats, qui sont générés par des autorités +de certification (<em>Certificate Authority</em> que je nomme <em><span class="caps">CA</span></em> dans la suite de&nbsp;l&#8217;article).</p> +<p>Les certificats <span class="caps">SSL</span> permettent deux&nbsp;choses:</p> +<ul> +<li>De garantir que les communications entre les navigateurs (vous) et les sites + Web ne sont connues que du détenteur du certificat du site et de vous&nbsp;même.</li> +<li>De garantir que le site sur lequel vous vous connectez est bien celui que + vous&nbsp;imaginez.</li> +</ul> +<p>Le navigateur, lors d&#8217;une visite d&#8217;un site, va télécharger le certificat +associé puis vérifier que le certificat en question a bien été généré par un +des <em><span class="caps">CA</span></em> en qui il a&nbsp;confiance.</p> +<p>Imaginons maintenant qu&#8217;une des <em><span class="caps">CA</span></em> essaye de savoir ce qui s&#8217;échange entre +mon navigateur et le site de ma banque (protégé par <span class="caps">SSL</span>). Comment cela se +passerait il&nbsp;?</p> +<p>N&#8217;importe quel <em><span class="caps">CA</span></em> peut donc générer des certificats pour n&#8217;importe quel site, +et le navigateur vérifierait, lui, que le certificat a bien été généré par une +<em><span class="caps">CA</span></em>.</p> +<p>Tout cela ne poserait pas de soucis si les <em><span class="caps">CA</span></em> étaient gérés de manière fiable, +mais il s&#8217;agit d&#8217;un travail compliqué, et certains <em><span class="caps">CA</span></em> ont par le passé montré +des&nbsp;faiblesses.</p> +<p>Par exemple, <a href="https://en.wikipedia.org/wiki/DigiNotar">DigiNotar</a> (un <em><span class="caps">CA</span></em> des Pays-Bas) +a été compromise et les attaquant.e.s ont pu générer des certificats <span class="caps">SSL</span> +frauduleux, ce qui leur a permis d&#8217;attaquer des sites tels que Facebook ou&nbsp;GMail.</p> +<p>Vous pouvez retrouver une liste des risques et menaces autour des <em><span class="caps">CA</span></em> <a href="http://wiki.cacert.org/Risk/History">sur le +wiki de CACert</a>.</p> +<h2 id="attaque-de-lhomme-du-milieu-avec-ssl">Attaque de l&#8217;homme du milieu avec <span class="caps">SSL</span></h2> +<p>A force de dire que c&#8217;était très facile à faire, j&#8217;ai eu envie d&#8217;essayer +d&#8217;espionner des connections protégées par <span class="caps">SSL</span>, et effectivement c&#8217;est +carrément flippant tellement c&#8217;est&nbsp;simple.</p> +<p>En l&#8217;espace de quelques minutes, il est possible de faire une <em>attaque de +l&#8217;homme du milieu</em> en utilisant par exemple un outil nommé <a href="http://docs.mitmproxy.org/en/stable">mitm-proxy</a>.</p> +<p>Pour déchiffrer l&#8217;ensemble du trafic <span class="caps">SSL</span>, j&#8217;ai simplement eu à lancer quelques +commandes et avoir un <em><span class="caps">CA</span></em> dans lequel le navigateur de la victime a confiance. +Je l&#8217;ai ajouté dans le navigateur cible pour simuler que je l&#8217;avais déjà +(c&#8217;est le cas si un des 1200 <span class="caps">CA</span> se fait pirater, ce qui me semble une surface +d&#8217;attaque assez&nbsp;large).</p> +<p>Je les colle ici si ça vous&nbsp;intéresse:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>aptitude<span class="w"> </span>install<span class="w"> </span>mitmproxy +$<span class="w"> </span>mitm-proxy<span class="w"> </span>-T<span class="w"> </span>--host +</code></pre></div> + +<p>Il faut faire croire à votre victime que vous êtes la passerelle vers +l&#8217;extérieur et à la passerelle que vous êtes la&nbsp;victime:</p> +<div class="highlight"><pre><span></span><code>arpspoof<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-t<span class="w"> </span>victime<span class="w"> </span>gateway +arpspoof<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-t<span class="w"> </span>gateway<span class="w"> </span>victime +</code></pre></div> + +<p>Puis dire à notre fausse passerelle de rediriger le trafic des ports 80 et 443 +vers notre&nbsp;proxy:</p> +<div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>sysctl<span class="w"> </span>-w<span class="w"> </span>net.ipv4.ip_forward<span class="o">=</span><span class="m">1</span> +sudo<span class="w"> </span>iptables<span class="w"> </span>-t<span class="w"> </span>nat<span class="w"> </span>-A<span class="w"> </span>PREROUTING<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-p<span class="w"> </span>tcp<span class="w"> </span>--dport<span class="w"> </span><span class="m">443</span><span class="w"> </span>-j<span class="w"> </span>REDIRECT<span class="w"> </span>--to-port<span class="w"> </span><span class="m">4443</span> +sudo<span class="w"> </span>iptables<span class="w"> </span>-t<span class="w"> </span>nat<span class="w"> </span>-A<span class="w"> </span>PREROUTING<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-p<span class="w"> </span>tcp<span class="w"> </span>--dport<span class="w"> </span><span class="m">80</span><span class="w"> </span>-j<span class="w"> </span>REDIRECT<span class="w"> </span>--to-port<span class="w"> </span><span class="m">4443</span> +</code></pre></div> + +<p>Et paf, <strong>on voit tout ce qui passe entre la machine et le serveur <span class="caps">SSL</span></strong>. On peut +d&#8217;ailleurs même imaginer faire tourner ces quelques commandes sur un +raspberry pi, pour aller encore plus&nbsp;vite…</p> +<h3 id="key-pinning-dans-les-navigateurs">Key-pinning dans les&nbsp;navigateurs</h3> +<p>Actuellement, n&#8217;importe quel <em><span class="caps">CA</span></em> peut générer des certificats pour +n&#8217;importe quel site, et c&#8217;est en grande partie ce qui pose souci. Une des +manières de faire évoluer la situation est d&#8217;épingler les certificats de +certains sites directement dans les&nbsp;navigateurs.</p> +<p>Cette approche a le mérite de fonctionner très bien <a href="https://dxr.mozilla.org/mozilla-central/source/security/manager/ssl/StaticHPKPins.h?from=StaticHPKPins.h">pour un petit nombre de +sites critiques (Google, Facebook, etc)</a>.</p> +<h3 id="http-public-key-pinning-hpkp"><span class="caps">HTTP</span> Public Key Pinning (<span class="caps">HPKP</span>)</h3> +<p><a href="https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning"><em><span class="caps">HTTP</span> Public Key Pinning</em></a> +est également une solution de <em>pinning</em> qui permet d&#8217;établir une confiance lors +de la première connexion avec le site. C&#8217;est ce qu&#8217;on appelle du <em>Trust on First +Use</em> ou <em><span class="caps">TOFU</span></em>.</p> +<p>Le navigateur va alors mettre ces informations dans un cache et vérifiera que +les certificats correspondent bien lors des prochaines&nbsp;visites.</p> +<p><em><span class="caps">HPKP</span></em> est disponible dans Firefox depuis Janvier 2015 et dans Chrome +depuis Octobre&nbsp;2015.</p> +<h3 id="certificate-transparency-des-journaux-auditables">Certificate transparency: des journaux&nbsp;auditables</h3> +<p>Une autre approche est celle proposée par <em>certificate transparency</em>:</p> +<blockquote> +<p>Certificate Transparency aims to remedy these certificate-based threats by +making the issuance and existence of <span class="caps">SSL</span> certificates open to scrutiny by +domain owners, CAs, and domain&nbsp;users.</p> +<p>&#8212; <a href="https://www.certificate-transparency.org/what-is-ct">Certificate&nbsp;Transparency</a></p> +</blockquote> +<p>Autrement dit, avec ce système les <em><span class="caps">CA</span></em> doivent rendre public le fait qu&#8217;ils +aient signé de nouveaux certificats intermédiaires. La signature est ajoutée à +un journal sur lequel il n&#8217;est possible que&nbsp;d&#8217;écrire.</p> +<p>Les navigateurs vont alors vérifier que les certificats utilisés sont bien des +certificats qui ont été ajoutés au&nbsp;journal.</p> +<p>Ici, toute l&#8217;intelligence est dans la vérification de ces journaux, qui +permettent donc de valider/invalider des certificats racines ou&nbsp;intermédiaires.</p> +<p>Il me semble donc qu&#8217;il serait possible d&#8217;ajouter un certificat frauduleux le +temps d&#8217;une attaque (et celui ci serait détecté et supprimé&nbsp;ensuite).</p> +<p><em>Certificate-Transparency</em> n&#8217;est donc pas une solution contre une écoute +globale mise en place par les gouvernements par&nbsp;exemple.</p> +<p>Si vous lisez bien l&#8217;anglais, je vous invite à aller lire +<a href="http://security.stackexchange.com/a/52838">cette description du problème et de la solution</a> +que je trouve très bien&nbsp;écrite.</p> +<h3 id="dane-dnssec"><span class="caps">DANE</span> + <span class="caps">DNSSEC</span></h3> +<blockquote> +<p>The <span class="caps">DANE</span> working group has developed a framework for securely +retrieving keying information from the <span class="caps">DNS</span> [<span class="caps">RFC6698</span>]. This +framework allows secure storing and looking up server public key +information in the <span class="caps">DNS</span>. This provides a binding between a domain +name providing a particular service and the key that can be used +to establish encrypted connection to that&nbsp;service.</p> +<p>&#8212; <a href="https://datatracker.ietf.org/wg/dane/charter/">Dane <span class="caps">WG</span></a></p> +</blockquote> +<p>Une autre solution est appelée &#8220;<span class="caps">DANE</span>&#8221; et repose par dessus le protocole +<em><span class="caps">DNSSEC</span></em>.</p> +<p>Je connais assez mal <em><span class="caps">DNSSEC</span></em> donc j&#8217;ai passé un peu de temps à lire des +documents. L&#8217;impression finale que ça me laisse est que le problème est +exactement le même que pour <span class="caps">SSL</span>: un certain nombre de personnes détiennent les +clés et toute la sécurité repose sur cette confiance. Or il est possible que +ces clés soient détenues par des personnes non dignes de&nbsp;confiance.</p> +<blockquote> +<p>Secure <span class="caps">DNS</span> (<span class="caps">DNSSEC</span>) uses cryptographic digital signatures signed with a +trusted public key certificate to determine the authenticity of data. +&#8212;&nbsp;https://en.wikipedia.org/wiki/DNS_spoofing</p> +</blockquote> +<p>Et&nbsp;aussi:</p> +<blockquote> +<p>It is widely believed[1] that securing the <span class="caps">DNS</span> is critically important for +securing the Internet as a whole, but deployment of <span class="caps">DNSSEC</span> specifically has +been hampered (As of 22 January 2010) by several&nbsp;difficulties:</p> +<ul> +<li>The need to design a backward-compatible standard that can scale to the + size of the&nbsp;Internet</li> +<li>Prevention of &#8220;zone enumeration&#8221; (see below) where&nbsp;desired</li> +<li>Deployment of <span class="caps">DNSSEC</span> implementations across a wide variety of <span class="caps">DNS</span> servers + and resolvers&nbsp;(clients)</li> +<li>Disagreement among implementers over who should own the top-level domain + root keys Overcoming the perceived complexity of <span class="caps">DNSSEC</span> and <span class="caps">DNSSEC</span>&nbsp;deployment</li> +</ul> +</blockquote> +<h2 id="solutions-basees-sur-la-blockchain">Solutions basées sur la&nbsp;blockchain</h2> +<p>Une dernière piste semble être l&#8217;utilisation de la <em>blockchain</em> pour distribuer +des clés par&nbsp;site.</p> +<p>La solution <em>DNSChain</em> me paraissait tout d&#8217;abord un bon point de départ mais +la lecture de <a href="https://www.indolering.com/okturtles-dnschain-unblock-us">quelques critiques</a> +et interventions du développeur du projet m&#8217;ont fait changer&nbsp;d&#8217;avis.</p> +<p>Reste encore la piste de <em>Namecoin Control</em> que je n&#8217;ai pas encore creusée. +Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la +bienvenue sur ces&nbsp;sujets!</p>Retours sur un atelier ZeroNet2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/retours-sur-un-atelier-zeronet.html<p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> dans les locaux de l&#8217;<span class="caps">INSA</span> de&nbsp;Rennes.</p> +<p>L&#8217;évènement s&#8217;étant rempli au delà de toutes les espérances, on m&#8217;a proposé de +venir y tenir un atelier, que j&#8217;ai proposé sur <a href="https://zeronet.io">ZeroNet</a>, un +petit projet fort sympathique qui pourrait devenir une …</p><p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> dans les locaux de l&#8217;<span class="caps">INSA</span> de&nbsp;Rennes.</p> +<p>L&#8217;évènement s&#8217;étant rempli au delà de toutes les espérances, on m&#8217;a proposé de +venir y tenir un atelier, que j&#8217;ai proposé sur <a href="https://zeronet.io">ZeroNet</a>, un +petit projet fort sympathique qui pourrait devenir une nouvelle manière de +distribuer le Web, permettant notamment d&#8217;éviter la&nbsp;censure.</p> +<p>Avant toute autre chose, merci énormément à l&#8217;équipe de la bibliothèque de +l&#8217;<span class="caps">INSA</span> pour l&#8217;organisation de cet évènement qui à une réelle portée&nbsp;politique.</p> +<h2 id="un-peu-dhistoire">Un peu&nbsp;d&#8217;histoire</h2> +<p>Il me semble que Tim Bernes Lee (l&#8217;inventeur du Web) avait prévu le Web comme un +protocole décentralisé. Chacun hébergerait ses données et les servirait aux +autres, qui pourraient alors y&nbsp;accéder.</p> +<p>Avec ce fonctionnement, impossible alors d&#8217;accéder à des sites si leur auteur +n&#8217;est pas en ligne. Qu&#8217;à cela ne tienne, on s&#8217;est mis à avoir des machines qui +restent connectées au réseau 24 heures par jour. Et puis une machine ne +suffisant plus, on a eu des fermes de machines dans des <em>data centers</em> etc afin +de supporter les milliers d&#8217;utilisateurs des&nbsp;sites.</p> +<h2 id="un-web-decentralise">Un Web&nbsp;décentralisé</h2> +<p>ZeroNet permet (entre autres) de répondre à ce problème en proposant une manière alternative de <strong>distribuer le Web</strong>, en pair à pair. Lors d&#8217;une visite d&#8217;un&nbsp;site:</p> +<ol> +<li>Vous contactez un <em>tracker</em> BitTorrent pour connaitre la liste des autres + visiteurs du site (les <em>pairs</em>).</li> +<li>Vous demandez aux <em>pairs</em> de vous donner les fichiers du&nbsp;site.</li> +<li>Vous validez que les fichiers servis sont bien les bons (en vérifiant la + signature&nbsp;attachée).</li> +</ol> +<p>N&#8217;importe quel visiteur devient alors un <em>pair</em>, qui sert le site aux autres&nbsp;visiteurs.</p> +<p>Parmi les nombreux avantages de cette approche, je note particulièrement&nbsp;que:</p> +<ul> +<li>Il est très difficile de censurer un site — Il est sur l&#8217;ensemble des machines + des&nbsp;visiteurs.</li> +<li>Les attaques par <em>fingerprinting</em> sont impossibles: le navigateur Web se + connecte à un serveur <em>proxy</em>&nbsp;local.</li> +<li>Vous détenez directement vos données et (par design) ne les donnez pas à des + silos (Facebook, Google,&nbsp;etc.)</li> +</ul> +<p>Si vous êtes interessés par une démonstration rapide, j&#8217;ai enregistré une vidéo +de 10 minutes où je parle en anglais avec une voix très&nbsp;grave.</p> +<video controls="" src="http://alexis.notmyidea.org/zeronet.webm" width=800></video> + +<h2 id="atelier">Atelier</h2> +<p>Pour l&#8217;atelier, j&#8217;ai choisi de faire une présentation rapide du projet (<a href="https://blog.notmyidea.org/docs/zeronet-presentation-fr.pdf">j&#8217;ai +traduit les slides</a> anglais +pour l&#8217;occasion — <a href="https://docs.google.com/presentation/d/158C_-V1ueNaaKHMBMBgGOVhunb9xrXzB3hC_g1N53c0/edit?usp=sharing">accès aux sources</a>) +avant d&#8217;installer ZeroNet sur les machines et de l&#8217;utiliser pour publier un&nbsp;site.</p> +<h3 id="partager-sur-le-reseau-local">Partager sur le réseau&nbsp;local</h3> +<p>Nous avons eu des soucis à cause du réseau (un peu congestionné) sur lequel +les ports utilisés pour la discussion entre <em>pairs</em> étaient fermés. Il est bien +sur possible de faire tourner le tout de manière indépendante du reste du réseau, +mais je n&#8217;avais pas prévu le&nbsp;coup.</p> +<p>Voici donc comment faire pour contourner le&nbsp;souci:</p> +<ol> +<li>Installer et lancer un <em>tracker</em> BitTorrent (De manière surprenante, + <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=685575">rien n&#8217;est packagé pour debian pour l&#8217;instant</a>) + J&#8217;ai choisi d&#8217;installer <a href="http://erdgeist.org/arts/software/opentracker/#build-instructions">OpenTracker</a></li> +<li>Ensuite lancer ZeroNet avec des options&nbsp;spécifiques.</li> +</ol> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>python<span class="w"> </span>zeronet.py<span class="w"> </span>--trackers<span class="w"> </span>udp://localhost:6969<span class="w"> </span>--ip_external<span class="w"> </span><span class="m">192</span>.168.43.207 +$<span class="w"> </span>python<span class="w"> </span>zeronet.py<span class="w"> </span>--trackers<span class="w"> </span>udp://192.168.43.207:6969<span class="w"> </span>--ip_external<span class="w"> </span><span class="m">192</span>.168.43.172 +</code></pre></div> + +<p>Il est nécessaire de spécifier l&#8217;adresse <span class="caps">IP</span> externe que chaque nœud expose pour +éviter qu&#8217;elle n&#8217;essaye d&#8217;aller la trouver par elle même: nous voulons l&#8217;adresse +du réseau local, et non pas l&#8217;adresse&nbsp;internet.</p> +<p>La prochaine fois je tenterais de venir avec un HotSpot Wifi et un tracker +BitTorrent dans la&nbsp;poche!</p> +<h2 id="questions-reponses">Questions /&nbsp;Réponses</h2> +<p>Il y avait quelques questions intéressantes auxquelles je n&#8217;ai pas toujours su +répondre sur le moment. Après quelques recherches, je rajoute des détails&nbsp;ici.</p> +<h3 id="torrent-tor-breche-de-secu">Torrent + Tor = brèche de sécu&nbsp;?</h3> +<p>Il me semblait avoir entendu parler de problèmes de <em>dé-anonymisation</em> +<a href="https://hal.inria.fr/file/index/docid/471556/filename/TorBT.pdf">lors de l&#8217;utilisation de BitTorrent par dessus Tor</a>.</p> +<blockquote> +<p>Dans certains cas, certains clients torrents (uTorrent, BitSpirit, etc) +écrivent directement votre adresse <span class="caps">IP</span> dans l&#8217;information qui est envoyée +au tracker et/ou aux autres pairs. +—&nbsp;https://blog.torproject.org/blog/bittorrent-over-tor-isnt-good-idea</p> +</blockquote> +<p><a href="https://github.com/HelloZeroNet/ZeroNet/issues/274">Ce n&#8217;est pas le cas de ZeroNet</a>, ce qui évacue le&nbsp;souci.</p> +<h3 id="zeromail-cest-lent-non">ZeroMail, c&#8217;est lent non&nbsp;?</h3> +<p>Une des applications de démo, <em>ZeroMail</em>, propose un mécanisme qui permet de +s&#8217;envoyer des messages chiffrés sur un réseau pair à pair. L&#8217;approche choisie +est de chiffrer les messages avec la clé du destinataire et de le mettre dans +un <em>pot commun</em>. Tout le monde essaye de déchiffrer tous les messages, mais ne +peut déchiffrer que les&nbsp;siens.</p> +<p>Cela permet de ne <strong>pas</strong> fuiter de méta-données, <a href="https://blog.notmyidea.org/les-problemes-de-pgp.html">à l&#8217;inverse de <span class="caps">PGP</span></a>.</p> +<p>Je n&#8217;ai en fait pas de réponse claire à donner à cette question: l&#8217;auteur de +ZeroNet me disait que <span class="caps">10MB</span> (la limite de taille d&#8217;un site, par défaut) +correspondait à beaucoup de place pour stocker des messages, et qu&#8217;il était +possible de supprimer les anciens messages une fois qu&#8217;ils sont lus par&nbsp;exemple.</p> +<p>Une autre solution à laquelle je pensait était de créer un <em>ZeroSite</em> pour +chaque récipient, mais on connait à ce moment là le nombre de messages qu&#8217;un +utilisateur peut&nbsp;recevoir.</p> +<p>Je vois plusieurs problèmes avec le design actuel de ZeroMail (il me semble +assez facile d&#8217;y faire un déni de service par exemple). A&nbsp;creuser.</p> +<h3 id="comment-heberger-des-tres-gros-sites">Comment héberger des très gros sites&nbsp;?</h3> +<p>Par exemple, comment faire pour héberger Wikipedia&nbsp;?</p> +<p>Il semble que la meilleure manière de faire serait de séparer Wikipedia en +un tas de petites ressources (par catégorie par ex.). Les gros médias pourraient +être considérés optionnels (et donc téléchargés uniquement à la&nbsp;demande)</p> +<h3 id="est-ce-quon-a-vraiment-besoin-dun-tracker">Est-ce qu&#8217;on à vraiment besoin d&#8217;un tracker&nbsp;?</h3> +<p>Le support d&#8217;une <span class="caps">DHT</span> <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, +mais pour l&#8217;instant pas encore implémenté. L&#8217;utilisation de la <span class="caps">DHT</span> BitTorrent +n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>Service de nuages : Garantir l’intégrité des données via des signatures2016-03-01T00:00:00+01:002016-03-01T00:00:00+01:00tag:blog.notmyidea.org,2016-03-01:/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.html<p class="first last">Comment garantir l&#8217;intégrité des données en utilisant les&nbsp;signatures.</p> +<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> +<p>Dans le cadre du projet <a class="reference external" href="https://wiki.mozilla.org/Firefox/Go_Faster">Go Faster</a>, nous souhaitons distribuer des +mises à jour de parties de <em>Firefox</em> de manière séparée des mises à jour majeures +(qui ont lieu toutes les 6&nbsp;semaines).</p> +<p>Les données que nous souhaitons mettre à jour sur les clients sont multiples. +Entre autres, nous souhaitons gérer <a class="reference external" href="https://blog.mozilla.org/security/2015/03/03/revoking-intermediate-certificates-introducing-onecrl/">la mise à jour des listes de révocation +(<span class="caps">CRL</span>) de certificats <span class="caps">SSL</span></a>.</p> +<p>Il est évidemment nécessaire de s&#8217;assurer que les données qui sont téléchargées +sur les client sont légitimes : que personne ne tente d&#8217;invalider des +certificats alors qu&#8217;ils sont valides, et que l&#8217;ensemble des mises à jour sont +bel et bien récupérées sur le&nbsp;client.</p> +<p>La signature garantit qu&#8217;une mise à jour contient tous les enregistrements, mais il +est toujours possible de bloquer l&#8217;accès au service (par exemple avec le <em>china +great firewall</em>).</p> +<p>Ce mécanisme fonctionne pour les listes de certificats à révoquer, mais pas +uniquement. Nous comptons réutiliser ce même fonctionnement dans le futur pour +la mise à jour d&#8217;autres parties de Firefox, et vous pouvez également en tirer +parti pour d&#8217;autres cas&nbsp;d&#8217;utilisation.</p> +<p>Nous souhaitons utiliser <a class="reference external" href="https://kinto.readthedocs.org">Kinto</a> afin +de distribuer ces jeux de données. Un des avantages est que l&#8217;on peut +facilement <em>cacher</em> les collections derrière un <span class="caps">CDN</span>.</p> +<p>Par contre, nous ne souhaitons pas que les clients fassent +confiance aveuglément, ni au serveur Kinto, ni au <span class="caps">CDN</span>.</p> +<p>Effectivement, un attaquant, contrôlant l&#8217;un ou l&#8217;autre, pourrait +alors envoyer les mises à jour qu&#8217;il souhaite à l&#8217;ensemble des clients +ou supprimer des certificats révoqués. Imaginez le carnage&nbsp;!</p> +<p>Afin de résoudre ce problème, considérons les conditions&nbsp;suivantes:</p> +<ul class="simple"> +<li>La personne qui a le pouvoir de mettre à jour les <span class="caps">CRL</span> (<em>l&#8217;updater</em>) +a accès à une cle de signature (ou mieux, <a class="reference external" href="https://fr.wikipedia.org/wiki/Hardware_Security_Module">un <span class="caps">HSM</span></a>) qui lui permet de +signer la&nbsp;collection;</li> +<li>Le pendant public de ce certificat est stocké et distribué dans&nbsp;Firefox;</li> +<li>Le <em>hashing</em> et la <em>signature</em> sont faits côté client pour éviter certains +vecteurs d&#8217;attaque (si un attaquant a la main sur le serveur Kinto par&nbsp;exemple).</li> +</ul> +<p>Le chiffrement à sens unique, aussi appellé <em>hashing</em> est un moyen de toujours +obtenir le même résultat à partir de la même&nbsp;entrée.</p> +<div class="section" id="premier-envoi-de-donnees-sur-kinto"> +<h2>Premier envoi de données sur&nbsp;Kinto</h2> +<p>L&#8217;ensemble des données est récupéré depuis une source <em>sécurisée</em> puis mis dans +une collection <span class="caps">JSON</span>. Chaque élément contient un identifiant unique généré sur +le&nbsp;client.</p> +<p>Par exemple, un enregistrement peut ressembler à&nbsp;:</p> +<div class="highlight"><pre><span></span><span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;b7dded96-8df0-8af8-449a-8bc47f71b4c4&quot;</span><span class="p">,</span> +<span class="w"> </span><span class="s2">&quot;fingerprint&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;11:D5:D2:0A:9A:F8:D9:FC:23:6E:5C:5C:30:EC:AF:68:F5:68:FB:A3&quot;</span><span class="p">}</span> +</pre></div> +<p>Le <em>hash</em> de la collection est ensuite calculé, signé puis envoyé au serveur +(voir plus bas pour les&nbsp;détails).</p> +<p>La signature est déportée sur un service qui ne s&#8217;occupe que de ça, puisque la +sécurité du certificat qui s&#8217;occupe des signatures est extrêmement&nbsp;importante.</p> +</div> +<div class="section" id="comment-verifier-l-integrite-des-donnees"> +<h2>Comment vérifier l&#8217;intégrité des données&nbsp;?</h2> +<p>Premièrement, il faut récupérer l&#8217;ensemble des enregistrements présents sur +le serveur, ainsi que le <em>hash</em> et la signature&nbsp;associée.</p> +<p>Ensuite, vérifier la signature du <em>hash</em>, pour s&#8217;assurer que celui-ci provient +bien d&#8217;un tiers de&nbsp;confiance.</p> +<p>Finalement, recalculer le <em>hash</em> localement et valider qu&#8217;il correspond bien à +celui qui a été&nbsp;signé.</p> +</div> +<div class="section" id="ajouter-de-nouvelles-donnees"> +<h2>Ajouter de nouvelles&nbsp;données</h2> +<p>Pour l&#8217;ajout de nouvelles données, il est nécessaire de s&#8217;assurer que les +données que l&#8217;on a localement sont valides avant de faire quoi que ce soit&nbsp;d&#8217;autre.</p> +<p>Une fois ces données validées, il suffit de procéder comme la première fois, et +d&#8217;envoyer à nouveau le <em>hash</em> de la collection au&nbsp;serveur.</p> +</div> +<div class="section" id="comment-calculer-ce-hash"> +<h2>Comment calculer ce hash&nbsp;?</h2> +<p>Pour calculer le <em>hash</em> de la collection, il est nécessaire&nbsp;:</p> +<ol class="arabic simple"> +<li>D&#8217;ordonner l&#8217;ensemble des éléments de la collection (par leur id)&nbsp;;</li> +<li>Pour chaque élément, sérialiser les champs qui nous intéressent (les +concaténer clé +&nbsp;valeur)</li> +<li>Calculer le <em>hash</em> depuis la&nbsp;sérialisation.</li> +</ol> +<p>Nous sommes encore incertains de la manière dont le hash va être calculé. Les <a class="reference external" href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41"><span class="caps">JSON</span> Web Signature</a> semblent +une piste intéressante. En attendant, une implementation naïve en python +pourrait ressembler à ceci&nbsp;:</p> +<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">json</span> +<span class="kn">import</span> <span class="nn">hashlib</span> + +<span class="n">data</span> <span class="o">=</span> <span class="p">[</span> + <span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;b7dded96-8df0-8af8-449a-8bc47f71b4c4&quot;</span><span class="p">,</span> + <span class="s2">&quot;fingerprint&quot;</span><span class="p">:</span> <span class="s2">&quot;11:D5:D2:0A:9A:F8:D9:FC:23:6E:5C:5C:30:EC:AF:68:F5:68:FB:A3&quot;</span><span class="p">},</span> + <span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;dded96b7-8f0d-8f8a-49a4-7f771b4c4bc4&quot;</span><span class="p">,</span> + <span class="s2">&quot;fingerprint&quot;</span><span class="p">:</span> <span class="s2">&quot;33:6E:5C:5C:30:EC:AF:68:F5:68:FB:A3:11:D5:D2:0A:9A:F8:D9:FC&quot;</span><span class="p">}]</span> + +<span class="n">m</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">()</span> +<span class="n">m</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">sort_keys</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span> +<span class="n">collection_hash</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> +</pre></div> +</div> +Let’s Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> +<blockquote> +<p>It’s time for the Web to take a big step forward in terms …</p></blockquote><p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> +<blockquote> +<p>It’s time for the Web to take a big step forward in terms of security +and privacy. We want to see <span class="caps">HTTPS</span> become the default. Let’s Encrypt +was built to enable that by making it as easy as possible to get and +manage&nbsp;certificates.</p> +<p>&#8212; <a href="https://letsencrypt.org/">Let&#8217;s&nbsp;Encrypt</a></p> +</blockquote> +<p>Depuis début Décembre, la nouvelle <em>autorité de certification</em> Let&#8217;s +Encrypt est passée en version <em>Beta</em>. Les certificats <span class="caps">SSL</span> sont un moyen +de 1. chiffrer la communication entre votre navigateur et le serveur et +2. un moyen d&#8217;être sur que le site Web auquel vous accédez est celui +auquel vous pensez vous connecter (pour éviter des <a href="https://fr.wikipedia.org/wiki/Attaque_de_l'homme_du_milieu">attaques de l&#8217;homme +du milieu</a>).</p> +<p>Jusqu&#8217;à maintenant, il était nécessaire de payer une entreprise pour +faire en sorte d&#8217;avoir des certificats qui évitent d&#8217;avoir ce genre +d&#8217;erreurs dans vos&nbsp;navigateurs:</p> +<p><img alt="Message de firefox lorsque une connexion n'est pas +sécurisée." src="%7Bfilename%7D/static/unsecure-connection.png"></p> +<p>Maintenant, grâce à Let&#8217;s Encrypt il est possible d&#8217;avoir des +certificats <span class="caps">SSL</span> <strong>gratuits</strong>, ce qui représente un grand pas en avant +pour la sécurité de nos&nbsp;communications.</p> +<p>Je viens de mettre en place un procédé (assez simple) qui permet de +configurer votre serveur pour générer des certificats <span class="caps">SSL</span> valides avec +Let&#8217;s Encrypt et le répartiteur de charge +<a href="http://www.haproxy.org/">HAProxy</a>.</p> +<p>Je me suis basé pour cet article sur +d&#8217;<a href="https://blog.infomee.fr/p/letsencrypt-haproxy">autres</a> +<a href="http://blog.victor-hery.com/article22/utiliser-let-s-encrypt-avec-haproxy">articles</a>, +dont je vous recommande la lecture pour un complément&nbsp;d&#8217;information.</p> +<h2 id="validation-des-domaines-par-lets-encrypt">Validation des domaines par Let&#8217;s&nbsp;Encrypt</h2> +<p>Je vous passe les détails d&#8217;installation du client de Let&#8217;s Encrypt, qui +sont <a href="https://github.com/letsencrypt/letsencrypt#installation">très bien expliqués sur leur +documentation</a>.</p> +<p>Une fois installé, vous allez taper une commande qui va ressembler&nbsp;à:</p> +<div class="highlight"><pre><span></span><code>letsencrypt-auto certonly --renew-by-default +--webroot -w /home/www/letsencrypt-requests/ \ +-d hurl.kinto-storage.org \ +-d forums.kinto-storage.org +</code></pre></div> + +<p>Le <em>webroot</em> est l&#8217;endroit ou les preuves de détention du domaine vont +être&nbsp;déposées.</p> +<p>Lorsque les serveurs de Let&#8217;s Encrypt vont vouloir vérifier que vous +êtes bien à l&#8217;origine des demandes de certificats, ils vont envoyer une +requête <span class="caps">HTTP</span> sur <code>http://domaine.org/.well-known/acme-challenge</code>, ou il +voudra trouver des informations qu&#8217;il aura généré via la commande +<code>letsencrypt-auto</code>.</p> +<p>J&#8217;ai choisi de faire une règle dans haproxy pour diriger toutes les +requêtes avec le chemin <code>.well-known/acme-challenge</code> vers un <em>backend</em> +nginx qui sert des fichiers statiques (ceux contenus dans +<code>/home/www/letsencrypt-requests/</code>).</p> +<p>Voici la section de la configuration de HAProxy (et <a href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L63-L72">la configuration +complete</a> +si ça peut être&nbsp;utile):</p> +<div class="highlight"><pre><span></span><code><span class="nv">frontend</span><span class="w"> </span><span class="nv">http</span> +<span class="w"> </span><span class="nv">bind</span><span class="w"> </span><span class="mi">0</span>.<span class="mi">0</span>.<span class="mi">0</span>.<span class="mi">0</span>:<span class="mi">80</span> +<span class="w"> </span><span class="nv">mode</span><span class="w"> </span><span class="nv">http</span> +<span class="w"> </span><span class="nv">default_backend</span><span class="w"> </span><span class="nv">nginx_server</span> + +<span class="w"> </span><span class="nv">acl</span><span class="w"> </span><span class="nv">letsencrypt_check</span><span class="w"> </span><span class="nv">path_beg</span><span class="w"> </span><span class="o">/</span>.<span class="nv">well</span><span class="o">-</span><span class="nv">known</span><span class="o">/</span><span class="nv">acme</span><span class="o">-</span><span class="nv">challenge</span> +<span class="w"> </span><span class="nv">use_backend</span><span class="w"> </span><span class="nv">letsencrypt_backend</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nv">letsencrypt_check</span> + +<span class="w"> </span><span class="nv">redirect</span><span class="w"> </span><span class="nv">scheme</span><span class="w"> </span><span class="nv">https</span><span class="w"> </span><span class="nv">code</span><span class="w"> </span><span class="mi">301</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">!</span>{<span class="w"> </span><span class="nv">ssl_fc</span><span class="w"> </span>}<span class="w"> </span><span class="o">!</span><span class="nv">letsencrypt_check</span> + +<span class="nv">backend</span><span class="w"> </span><span class="nv">letsencrypt_backend</span> +<span class="w"> </span><span class="nv">http</span><span class="o">-</span><span class="nv">request</span><span class="w"> </span><span class="nv">set</span><span class="o">-</span><span class="nv">header</span><span class="w"> </span><span class="nv">Host</span><span class="w"> </span><span class="nv">letsencrypt</span>.<span class="nv">requests</span> +<span class="w"> </span><span class="nv">dispatch</span><span class="w"> </span><span class="mi">127</span>.<span class="mi">0</span>.<span class="mi">0</span>.<span class="mi">1</span>:<span class="mi">8000</span> +</code></pre></div> + +<p>Et celle de <span class="caps">NGINX</span>:</p> +<div class="highlight"><pre><span></span><code>server { + listen 8000; + server_name letsencrypt.requests; + root /home/www/letsencrypt-requests; +} +</code></pre></div> + +<h2 id="installation-des-certificats-dans-haproxy">Installation des certificats dans&nbsp;HAProxy</h2> +<p>Vos certificats <span class="caps">SSL</span> devraient être générés dans <code>/etc/letsencrypt/live</code>, +mais ils ne sont pas au format attendu par haproxy. Rien de grave, la +commande suivant convertit l&#8217;ensemble des certificats en une version +compatible avec&nbsp;HAProxy:</p> +<div class="highlight"><pre><span></span><code>cat /etc/letsencrypt/live/domaine.org/privkey.pem /etc/letsencrypt/live/domaine.org/fullchain.pem &gt; /etc/ssl/letsencrypt/domaine.org.pem +</code></pre></div> + +<p>Et ensuite dans la configuration de haproxy, pour le (nouveau) +<em>frontend</em>&nbsp;https:</p> +<div class="highlight"><pre><span></span><code>bind 0.0.0.0:443 ssl no-sslv3 crt /etc/ssl/letsencrypt +</code></pre></div> + +<p>Faites bien attention à avoir un <em>frontend</em> https pour tous vos sites en +<span class="caps">HTTPS</span>. <a href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L38-L60">Pour moi cela ressemble à +ça</a>.</p> +<p>Une fois tout ceci fait, redémarrez votre service haproxy et zou&nbsp;!</p> +<h2 id="automatisation">Automatisation</h2> +<p>Pour automatiser un peu tout ça, j&#8217;ai choisi de faire ça comme&nbsp;suit:</p> +<ul> +<li>Un fichier domaine dans <code>letsencrypt/domains/domain.org</code> qui + contient le script <code>letsencrypt</code>.</li> +<li>Un fichier d&#8217;installation de certificats dans + <code>letsencrypt/install-certs.sh</code> qui s&#8217;occupe d&#8217;installer les + certificats déjà&nbsp;générés.</li> +</ul> +<p>Et voila ! <a href="https://github.com/almet/infra/">Le tout est dans un dépot +github</a>, si jamais ça peut vous servir, +tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des +outils pour faire face à la surveillance généralisée, et notamment en +rapport au chiffrement des données. Une de mes envies de l&#8217;époque était +l&#8217;animation&nbsp;d&#8217;ateliers.</p> +<blockquote> +<p>Je compte&nbsp;donc:</p> +<ul> +<li>Organiser des ateliers de …</li></ul></blockquote><p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des +outils pour faire face à la surveillance généralisée, et notamment en +rapport au chiffrement des données. Une de mes envies de l&#8217;époque était +l&#8217;animation&nbsp;d&#8217;ateliers.</p> +<blockquote> +<p>Je compte&nbsp;donc:</p> +<ul> +<li>Organiser des ateliers de sensibilisation aux outils de + communication, envers mes&nbsp;proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au + moins pour rendre le déchiffrement des messages plus longue, + &#8220;noyer le&nbsp;poisson&#8221;.</li> +</ul> +<p>&#8212; <a href="http://blog.notmyidea.org/chiffrement.html">Chiffrement</a></p> +</blockquote> +<p>J&#8217;ai mis un peu de temps à mettre le pied à l&#8217;étrier, mais je ressors +finalement du premier atelier que j&#8217;ai co-animé avec geb, auprès d&#8217;un +public de&nbsp;journalistes.</p> +<p>Pour cette première édition l&#8217;idée était à la fois d&#8217;aller à la +rencontre d&#8217;un public que je connais mal, de leur donner des outils pour +solutionner les problèmes auxquels ils font parfois face, et de me faire +une idée de ce que pouvait être un atelier sur l&#8217;autodéfense&nbsp;numérique.</p> +<p>L&#8217;objectif pour ce premier atelier était&nbsp;de:</p> +<ol> +<li>Échanger autour des besoins et <strong>faire ressortir des histoires</strong> ou + le manque d&#8217;outillage / connaissances à posé problème, dans des + situations&nbsp;concrètes;</li> +<li>Se rendre compte des &#8220;conduites à risque&#8221;, <strong>faire peur</strong> aux + personnes formées pour qu&#8217;elles se rendent compte de l&#8217;état actuel + des&nbsp;choses;</li> +<li><strong>Proposer des solutions concrètes</strong> aux problèmes soulevés, ainsi + que le minimum de connaissance théorique pour les&nbsp;appréhender.</li> +</ol> +<h2 id="1-faire-ressortir-les-problemes">1. Faire ressortir les&nbsp;problèmes</h2> +<p>Afin de faire ressortir les problèmes, nous avons choisi de constituer +des petits groupes de discussion, afin de faire des &#8220;Groupes d&#8217;Interview +Mutuels&#8221;, ou &#8220;<span class="caps">GIM</span>&#8221;:</p> +<blockquote> +<p>l’animateur invite les participants à se regrouper par trois, avec des +personnes qu’on connaît moins puis invite chacun à livrer une +expérience vécue en lien avec le thème de la réunion et les deux +autres à poser des questions leur permettant de bien saisir ce qui a +été&nbsp;vécu.</p> +<p>&#8212; «<a href="http://www.scoplepave.org/pour-s-ecouter">Pour s&#8217;écouter</a>», <span class="caps">SCOP</span> +Le&nbsp;Pavé.</p> +</blockquote> +<p>De ces <em>GIMs</em> nous avons pu ressortir quelques histoires, gravitant +autour&nbsp;de:</p> +<ul> +<li><strong>La protection des sources (d&#8217;information)</strong>: Comment faire pour + aider quelqu&#8217;un à faire &#8220;fuiter&#8221; des données depuis l&#8217;intérieur + d&#8217;une entreprise&nbsp;?</li> +<li><strong>Le chiffrement de ses données</strong>: Comment éviter de faire &#8220;fuiter&#8221; + des données importantes lors d&#8217;une perquisition de matériel&nbsp;?</li> +</ul> +<h2 id="2-faire-peur">2. Faire&nbsp;peur</h2> +<p>Un des premiers objectifs est de faire peur, afin que tout le monde se +rende compte à quel point il est facile d&#8217;accéder à certaines données. +<a href="http://blog.barbayellow.com/">Grégoire</a> m&#8217;avait conseillé quelques +petites accroches qui ont ma foi bien&nbsp;marché:</p> +<p>J&#8217;ai demandé aux présent.e.s&nbsp;de:</p> +<ul> +<li>donner leur mot de passe à voix haute devant les autres: a priori + personne ne le&nbsp;fera;</li> +<li>venir se connecter à leur compte email depuis mon ordinateur. J&#8217;ai + piégé une personne, qui est venu pour taper son mot de&nbsp;passe.</li> +</ul> +<p>Cela à été un bon moyen de parler de l&#8217;importance des traces que l&#8217;on +peut laisser sur un ordinateur, et de la confiance qu&#8217;il faut avoir dans +le matériel que l&#8217;on utilise, à fortiori si ce ne sont pas les&nbsp;vôtres.</p> +<p>Pour continuer à leur faire peur, après une brève explication de ce +qu&#8217;est <span class="caps">SSL</span> nous avons montré comment il était facile de scruter le +réseau à la recherche de mots de passe en&nbsp;clair.</p> +<h2 id="3-proposer-des-solutions-concretes">3. Proposer des solutions&nbsp;concrêtes</h2> +<p>Une fois que tout le monde avait pleinement pris sonscience des +problématiques et n&#8217;osait plus utiliser son ordinateur ou son +téléphone, on à commencé à parler de quelques solutions. Plusieurs +approches étaient possibles ici, nous avons choisi de présenter quelques +outils qui nous semblaient répondre aux&nbsp;attentes:</p> +<ul> +<li>On a expliqué ce qu&#8217;était <a href="https://tails.boum.org">Tails</a>, et + comment l&#8217;utiliser et le&nbsp;dupliquer.</li> +<li>On a pu faire un tour des outils existants sur Tails, notamment + autour de l&#8217;<em>anonymisation</em> de fichiers et la suppression effective + de&nbsp;contenus.</li> +<li>Certaines personnes ont pu créer une clé tails avec la persistance + de&nbsp;configurée.</li> +<li>Nous nous sommes connectés au réseau + <a href="https://www.torproject.org">Tor</a> et testé que nos adresses <span class="caps">IP</span> + changeaient bien à la&nbsp;demande.</li> +<li>Nous avons utilisé <a href="https://crypto.cat">CryptoCat</a> par dessus Tor, + afin de voir comment avoir une conversation confidentielle dans + laquelle il est possible d&#8217;échanger des&nbsp;fichiers.</li> +</ul> +<h2 id="retours">Retours</h2> +<p>D&#8217;une manière générale, pour une formation de trois heures et demi, je +suis assez content de l&#8217;exercice, et de l&#8217;ensemble des sujets que nous +avons pu couvrir. Il y a beaucoup de place pour l&#8217;amélioration, +notamment en amont (j&#8217;avais par exemple oublié d&#8217;amener avec moi +suffisamment de clés <span class="caps">USB</span> pour utiliser&nbsp;Tails).</p> +<p>La plupart des retours qu&#8217;on a pu avoir jusqu&#8217;à maintenant sont +positifs, et il y a l&#8217;envie d&#8217;aller plus loin sur l&#8217;ensemble de ces&nbsp;sujets.</p> +<h2 id="la-suite">La&nbsp;suite</h2> +<p>Il y a beaucoup de sujets que nous n&#8217;avons pas abordés, ou uniquement +survolés, à cause du manque de temps disponible. Idéalement, il faudrait +au moins une journée entière pour couvrir quelques sujets plus en détail +(on peut imaginer avoir une partie théorique le matin et une partie +pratique l&#8217;après-midi par&nbsp;exemple).</p> +<p>J&#8217;ai choisi volontairement de ne pas aborder le chiffrement des messages +via <span class="caps">PGP</span> parce que <a href="%7Bfilename%7D2015.05.pgp-problemes.rst">je pense que la protection que ce média propose n&#8217;est +pas suffisante</a>, mais je suis +en train de revenir sur ma décision: il pourrait être utile de présenter +l&#8217;outil, à minima, en insistant sur certaines de ses&nbsp;faiblesses.</p> +<p>Un compte twitter à été créé recemment autour des crypto-party à Rennes, +si vous êtes interessés, <a href="https://twitter.com/CryptoPartyRNS">allez jeter un coup +d&#8217;œil</a>!</p> +<p>Je n&#8217;ai pas trouvé de ressources disponibles par rapport à des plans de +formation sur le sujet, j&#8217;ai donc décidé de publier les nôtres, afin de +co-construire avec d&#8217;autres des plans de&nbsp;formation.</p> +<p>Ils sont pour l&#8217;instant disponibles <a href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The +Docs</a>. Tous les +retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> +<p>Et même si j&#8217;arrive à convaincre certains de …</p><p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> +<p>Et même si j&#8217;arrive à convaincre certains de mes proches à installer <span class="caps">PGP</span>, je ne suis pas satisfait du résultat: les méta-données (qui contacte qui à quel +moment, et pour lui dire quoi) transitent de toute manière, elles, en clair, à la vue de&nbsp;tous.</p> +<p>Ce problème est lié directement au protocole email: il est <em>necessaire</em> de faire fuiter ces meta-données (au moins le destinataire) pour avoir un protocole +mail&nbsp;fonctionnel.</p> +<p>Le mail répond à un besoin de communication asynchrone qui permet des conversations plus réfléchies qu&#8217;un simple chat (miaou). Il est tout à fait possible d&#8217;utiliser certaines technologies existantes afin de construire le futur de l&#8217;email, pour&nbsp;lequel:</p> +<ul> +<li>Les méta-données seraient chiffrées — Il n&#8217;est pas possible de savoir qui + communique avec qui, et&nbsp;quand;</li> +<li>Le chiffrement serait fort (et protégé d&#8217;une phrase de passe&nbsp;?);</li> +<li>La fuite d&#8217;une clé de chiffrement utilisée dans un échange ne permette pas de + déchiffrer l&#8217;ensemble des échanges (forward&nbsp;secrecy);</li> +<li>Il ne soit pas possible de réutiliser les données comme preuve pour + incriminer l&#8217;emmeteur du message&nbsp;(deniability);</li> +</ul> +<p>Avec au moins ces besoins en tête, il semble qu&#8217;une revue de l&#8217;ensemble des projets existants pointe du doigt vers <a href="https://github.com/agl/pond">pond</a>, ou vers <a href="https://www.whispersystems.org">Signal</a>.</p> +<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I +want to share with the crypto community to actually see if any solution +exists to solve this particular&nbsp;problem.</em></p> +<p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in +web-based cryptographic applications is the fact that there is no way …</p><p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I +want to share with the crypto community to actually see if any solution +exists to solve this particular&nbsp;problem.</em></p> +<p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in +web-based cryptographic applications is the fact that there is no way to +trust online software distributions. Put differently, you don&#8217;t actually +trust the software authors but are rather trusting the software +distributors and certificate authorities&nbsp;(CAs).</p> +<p>I&#8217;ve been talking with a few folks in the past months about that and +they suggested me to publish something to discuss the matter. So here I&nbsp;come!</p> +<h2 id="the-problem-attack-vectors">The problem (Attack&nbsp;vectors)</h2> +<p>Let&#8217;s try to describe a few potential&nbsp;attacks:</p> +<p><em>Application Authors</em> just released a new version of their open source +web crypto messaging application. An <em>Indie Hoster</em> installs it on their +servers so a wide audience can actually use&nbsp;it.</p> +<p>Someone alters the files on <em>Indie Hoster</em> servers, effectively +replacing them with other <em>altered files</em> with less security properties +/ a backdoor. This someone could either be an <em>Evil Attacker</em> which +found its way trough, the <em>Indie Hoster</em> or a <span class="caps">CDN</span> which delivers the&nbsp;files,</p> +<p>Trusted <em>Certificate Authorities</em> (&#8220;governments&#8221; or &#8220;hacking team&#8221;) can +also trick the User Agents (i.e. Firefox) into thinking they&#8217;re talking +to <em>Indie Hoster</em> even though they&#8217;re actually talking to a different&nbsp;server.</p> +<p><strong>Altered files</strong> are then being served to the User Agents, and <em>Evil +Attacker</em> now has a way to actually attack the end&nbsp;users.</p> +<h2 id="problem-mitigation">Problem&nbsp;Mitigation</h2> +<p>Part of the problem is solved by the recently introduced <a href="https://w3c.github.io/webappsec/specs/subresourceintegrity/">Sub Resource +Integrity</a> +(<span class="caps">SRI</span>). To quote them: &#8220;[it] defines a mechanism by which user agents +may verify that a fetched resource has been delivered without unexpected&nbsp;manipulation.&#8221;.</p> +<p><span class="caps">SRI</span> is a good start, but isn&#8217;t enough: it ensures the assets (JavaScript +files, mainly) loaded from a specific <span class="caps">HTML</span> page are the ones the author +of the <span class="caps">HTML</span> page intends. However, <span class="caps">SRI</span> doesn&#8217;t allow the User Agent to +ensure the <span class="caps">HTML</span> page is the one he&nbsp;wants.</p> +<p>In other words, we miss a way to create trust between <em>Application +Authors</em> and <em>User Agents</em>. The User-Agent currently has to trust the +<em>Certificate Authorities</em> and the delivery (<em>Indie Hoster</em>).</p> +<p>For desktop software distribution: <em>Crypto Experts</em> audit the software, +sign it somehow and then this signature can be checked locally during +installation or runtime. It&#8217;s not automated, but at least it&#8217;s&nbsp;possible.</p> +<p>For web applications, we don&#8217;t have such a mechanism, but it should be +possible. Consider the&nbsp;following:</p> +<ul> +<li><em>App Authors</em> publish a new version of their software; They provide + a hash of each of their distributed files (including the <span class="caps">HTML</span>&nbsp;files);</li> +<li><em>Crypto Experts</em> audit these files and sign the hashes&nbsp;somehow;</li> +<li><em>User Agents</em> can chose to trust some specific <em>Crypto Experts</em>;</li> +<li>When a <em>User Agent</em> downloads files, it checks if they&#8217;re signed by + a trusted&nbsp;party.</li> +</ul> +<h2 id="chosing-who-you-trust">Chosing who you&nbsp;trust</h2> +<p>In terms of user experience, handling certificates is hard, and that&#8217;s +where the community matters. Distributions such as +<a href="https://tails.boom.org">Tails</a> could chose who they trust to verify the +files, and issue warnings / refuse to run the application in case files +aren&#8217;t&nbsp;verified.</p> +<p>But, as highligted earlier, CAs are hard to trust. A new instance of the +same <span class="caps">CA</span> system wouldn&#8217;t make that much differences, expect the fact that +distributions could ship with a set of trusted authorities (for which +revocation would still need to be taken care&nbsp;of).</p> +<blockquote> +<p>[&#8230;] users are vulnerable to MitM attacks by the authority, which +can vouch for, or be coerced to vouch for, false keys. This weakness +has been highlighted by recent <span class="caps">CA</span> scandals. Both schemes can also be +attacked if the authority does not verify keys before vouching for&nbsp;them.</p> +<p>&#8212; <a href="http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf">SoK : Secure +Messaging</a>;</p> +</blockquote> +<p>It seems that some other systems could allow for something more&nbsp;reliable:</p> +<blockquote> +<p>Melara et al proposed <span class="caps">CONIKS</span>, using a series of chained commitments to +Merkle prefix trees to build a key directory [&#8230;] for which +individual users can efficiently verify the consistency of their own +entry in the directory without relying on a third&nbsp;party.</p> +<p>This “self- auditing log” approach makes the system partially have no +auditing required (as general auditing of non-equivocation is still +required) and also enables the system to be privacy preserving as the +entries in the directory need not be made public. This comes at a mild +bandwidth cost not reflected in our table, estimated to be about 10 +kilobytes per client per day for&nbsp;self-auditing.</p> +<p>&#8212; <a href="http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf">SoK : Secure +Messaging</a>;</p> +</blockquote> +<p>Now, I honestly have no idea if this thing solves the whole problem, and +I&#8217;m pretty sure this design has many security problems attached to&nbsp;it.</p> +<p>However, that&#8217;s a problem I would really like to see solved one day, so +here the start of the discussion, don&#8217;t hesitate to <a href="/pages/about.html">get in +touch</a>!</p> +<h2 id="addendum">Addendum</h2> +<p>It seems possible to increase the level a user has in a Web Application +by adding indicators in the User-Agent. For instance, when using an +application that&#8217;s actually signed by someone considered trustful by the +User-Agent (or the distributor of the User-Agent), a little green icon +could be presented to the User, so they know that they can be confident +about&nbsp;this.</p> +<p>A bit like User-Agents do for <span class="caps">SSL</span>, but for the actual signature of the +files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel +lors de la conception&nbsp;d&#8217;APIs.</p> +<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> +<p><strong>tldr; Cliquet est un toolkit Python pour construire des APIs, qui implémente +les bonnes pratiques en terme de mise en production et de protocole <span class="caps">HTTP</span>.</strong></p> +<div class="section" id="les-origines"> +<h2>Les&nbsp;origines</h2> +<p>L&#8217;objectif pour le premier trimestre 2015 était de construire un service de +stockage et de <a class="reference external" href="https://blog.notmyidea.org/service-de-nuages-fr.html">synchronisation de listes de lecture</a>.</p> +<p>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&nbsp;déployés.</p> +<p>De même, nous voulions tirer parti du protocole de <em>Firefox Sync</em>, robuste et éprouvé, +pour la synchronisation des données&nbsp;«offline».</p> +<p>Plutôt qu&#8217;écrire un <a class="reference external" href="http://blog.octo.com/en/design-a-rest-api/">énième</a> +<a class="reference external" href="http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api">article</a> de blog, +nous avons préféré les rassembler dans ce qu&#8217;on a appellé «un&nbsp;protocole».</p> +<p>Comme pour l&#8217;architecture envisagée nous avions deux projets à construire, qui +devaient obéir globalement à ces mêmes règles, nous avons décidé de mettre en +commun l&#8217;implémentation de ce protocole et de ces bonnes pratiques dans un&nbsp;«toolkit».</p> +<p><em>Cliquet</em> est&nbsp;né.</p> +<img alt="Cliquet logo" class="align-center" src="https://blog.notmyidea.org/images/cliquet/cliquet-logo.png" /> +<div class="section" id="les-intentions"> +<h3>Les&nbsp;intentions</h3> +<blockquote class="epigraph"> +Quelle structure <span class="caps">JSON</span> pour mon <span class="caps">API</span> ? Quelle syntaxe pour filtrer la liste +via la querystring ? Comment gérer les écritures concurrentes ? +Et synchroniser les données dans mon application cliente ?</blockquote> +<p>Désormais, quand un projet souhaite bénéficier d&#8217;une <span class="caps">API</span> <span class="caps">REST</span> pour stocker et consommer +des données, il est possible d&#8217;utiliser le <strong>protocole <span class="caps">HTTP</span></strong> proposé +et de se concentrer sur l&#8217;essentiel. Cela vaut aussi pour les clients, où +la majorité du code d&#8217;interaction avec le serveur est&nbsp;réutilisable.</p> +<blockquote class="epigraph"> +Comment pouvons-nous vérifier que le service est opérationnel ? Quels indicateurs StatsD ? +Est-ce que Sentry est bien configuré ? Comment déployer une nouvelle version +sans casser les applications clientes ?</blockquote> +<p>Comme <em>Cliquet</em> fournit tout ce qui est nécessaire pour être conforme avec les +exigences de la <strong>mise en production</strong>, le passage du prototype au service opérationnel +est très rapide ! De base le service répondra aux attentes en terme supervision, configuration, +déploiement et dépréciation de version. Et si celles-ci évoluent, il suffira +de faire évoluer le&nbsp;toolkit.</p> +<blockquote class="epigraph"> +Quel backend de stockage pour des documents <span class="caps">JSON</span> ? Comment faire si l&#8217;équipe +de production impose PostgreSQL ? Et si on voulait passer à Redis ou en +mémoire pour lancer les tests ?</blockquote> +<p>En terme d&#8217;implémentation, nous avons choisi de <strong>fournir des abstractions</strong>. +En effet, nous avions deux services dont le coeur consistait +à exposer un <em><span class="caps">CRUD</span></em> en <em><span class="caps">REST</span></em>, persistant des données <span class="caps">JSON</span> dans un backend. +Comme <em>Pyramid</em> et <em>Cornice</em> ne fournissent rien de tout prêt pour ça, +nous avons voulu introduire des classes de bases pour abstraire les notions +de resource <span class="caps">REST</span> et de backend de&nbsp;stockage.</p> +<p>Dans le but de tout rendre optionnel et «pluggable», <strong>tout est configurable</strong> +depuis le fichier <tt class="docutils literal">.ini</tt> de l&#8217;application. Ainsi tous les projets qui utilisent +le toolkit se déploieront de la même manière : seuls quelques éléments de configuration +les&nbsp;distingueront.</p> +<img alt="Une réunion à Paris..." class="align-center" src="https://blog.notmyidea.org/images/cliquet/cliquet-notes-whiteboard.jpg" /> +</div> +</div> +<div class="section" id="le-protocole"> +<h2>Le&nbsp;protocole</h2> +<blockquote class="epigraph"> +Est-ce suffisant de parler d&#8217;«<span class="caps">API</span> <span class="caps">REST</span>» ? Est-ce bien nécessaire de +relire la spec <span class="caps">HTTP</span> à chaque fois ? Pourquoi réinventer un protocole complet +à chaque fois ?</blockquote> +<p>Quand nous développons un (micro)service Web, nous dépensons généralement beaucoup +trop d&#8217;énergie à (re)faire des choix&nbsp;(arbitraires).</p> +<p>Nul besoin de lister ici tout ce qui concerne la dimension +de la spécification <span class="caps">HTTP</span> pure, qui nous impose le format des headers, +le support de <span class="caps">CORS</span>, la négocation de contenus (types mime), la différence entre +authentification et autorisation, la cohérence des code&nbsp;status&#8230;</p> +<p>Les choix principaux du protocole concernent surtout&nbsp;:</p> +<ul class="simple"> +<li><strong>Les resources <span class="caps">REST</span></strong> : Les deux URLs d&#8217;une resource (pour la collection +et les enregistrements) acceptent des verbes et des headers&nbsp;précis.</li> +<li><strong>Les formats</strong> : le format et la structure <span class="caps">JSON</span> des réponses est imposé, ainsi +que la pagination des listes ou la syntaxe pour filtrer/trier les resources via la <a class="reference external" href="https://en.wikipedia.org/wiki/Query_string">querystring</a>.</li> +<li><strong>Les timestamps</strong> : un numéro de révision qui s&#8217;incrémente à chaque opération +d&#8217;écriture sur une collection&nbsp;d&#8217;enregistrements.</li> +<li><strong>La synchronisation</strong> : une série de leviers pour récupérer et renvoyer des +changements sur les données, sans perte ni collision, en utilisant les&nbsp;timestamps.</li> +<li><strong>Les permissions</strong> : les droits d&#8217;un utilisateur sur une collection ou un enregistrement +(<em>encore frais et sur le point d&#8217;être documenté</em>) <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a>.</li> +<li><strong>Opérations par lot</strong>: une <span class="caps">URL</span> qui permet d&#8217;envoyer une série de requêtes +décrites en <span class="caps">JSON</span> et d&#8217;obtenir les réponses&nbsp;respectives.</li> +</ul> +<p>Dans la dimension opérationnelle du protocole, on trouve&nbsp;:</p> +<ul class="simple"> +<li><strong>La gestion de version</strong> : cohabitation de plusieurs versions en production, +avec alertes dans les entêtes pour la fin de vie des anciennes&nbsp;versions.</li> +<li><strong>Le report des requêtes</strong> : entêtes interprétées par les clients, activées en cas de +maintenance ou de surchage, pour ménager le&nbsp;serveur.</li> +<li><strong>Le canal d&#8217;erreurs</strong> : toutes les erreurs renvoyées par le serveur ont le même +format <span class="caps">JSON</span> et ont un numéro&nbsp;précis.</li> +<li><strong>Les utilitaires</strong> : URLs diverses pour répondre aux besoins exprimés par +l&#8217;équipe d&#8217;administrateurs (monitoring, metadonnées, paramètres&nbsp;publiques).</li> +</ul> +<p>Ce protocole est une compilation des bonnes pratiques pour les APIs <span class="caps">HTTP</span> (<em>c&#8217;est notre métier !</em>), +des conseils des administrateurs système dont c&#8217;est le métier de mettre à disposition des services +pour des millions d&#8217;utilisateurs et des retours d&#8217;expérience de l&#8217;équipe +de <em>Firefox Sync</em> pour la gestion de la concurrence et de&nbsp;l&#8217;«offline-first».</p> +<p>Il est <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/api/index.html">documenté en détail</a>.</p> +<p>Dans un monde idéal, ce protocole serait versionné, et formalisé dans une <span class="caps">RFC</span>. +En rêve, il existerait même plusieurs implémentations avec des codes différentes +(Python, Go, Node, etc.). <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a></p> +<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>Voir notre <a class="reference external" href="https://blog.notmyidea.org/service-de-nuages-la-gestion-des-permissions-fr.html">article dédié sur les permissions</a></td></tr> +</tbody> +</table> +<table class="docutils footnote" frame="void" id="footnote-2" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td>Rappel: nous sommes une toute petite équipe !</td></tr> +</tbody> +</table> +</div> +<div class="section" id="le-toolkit"> +<h2>Le&nbsp;toolkit</h2> +<div class="section" id="choix-techniques"> +<h3>Choix&nbsp;techniques</h3> +<p><em>Cliquet</em> implémente le protocole en Python (<em>2.7, 3.4+, pypy</em>), avec <a class="reference external" href="http://trypyramid.com/">Pyramid</a> <a class="footnote-reference" href="#footnote-3" id="footnote-reference-3">[3]</a>.</p> +<p><strong>Pyramid</strong> est un framework Web qui va prendre en charge tout la partie <span class="caps">HTTP</span>, +et qui s&#8217;avère pertinent aussi bien pour des petits projets que des plus&nbsp;ambitieux.</p> +<p><strong>Cornice</strong> est une extension de <em>Pyramid</em>, écrite en partie par Alexis et Tarek, +qui permet d&#8217;éviter d&#8217;écrire tout le code <em>boilerplate</em> quand on construit une +<span class="caps">API</span> <span class="caps">REST</span> avec&nbsp;Pyramid.</p> +<p>Avec <em>Cornice</em>, on évite de réécrire à chaque fois le code qui va +cabler les verbes <span class="caps">HTTP</span> aux méthodes, valider les entêtes, choisir le sérialiseur +en fonction des entêtes de négociation de contenus, renvoyer les codes <span class="caps">HTTP</span> +rigoureux, gérer les entêtes <span class="caps">CORS</span>, fournir la validation <span class="caps">JSON</span> à partir de&nbsp;schémas&#8230;</p> +<p><strong>Cliquet</strong> utilise les deux précédents pour implémenter le protocole et fournir +des abstractions, mais on a toujours <em>Pyramid</em> et <em>Cornice</em> sous la main pour +aller au delà de ce qui est proposé&nbsp;!</p> +<table class="docutils footnote" frame="void" id="footnote-3" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-3">[3]</a></td><td>Au tout début nous avons commencé une implémentation avec <em>Python-Eve</em> +(Flask), mais n&#8217;étions pas satisfaits de l&#8217;approche pour la configuration +de l&#8217;<span class="caps">API</span>. En particulier du côté magique.</td></tr> +</tbody> +</table> +</div> +<div class="section" id="concepts"> +<h3>Concepts</h3> +<p>Bien évidemment, les concepts du toolkit reflètent ceux du protocole mais il y +a des éléments&nbsp;supplémentaires:</p> +<ul class="simple"> +<li><strong>Les backends</strong> : abstractions pour le stockage, le cache et les permissions +(<em>ex. PostgreSQL, Redis, en-mémoire, &#8230;</em>)</li> +<li><strong>La supervision</strong> : logging <span class="caps">JSON</span> et indicateurs temps-réel (<em>StatsD</em>) pour suivre les +performances et la santé du&nbsp;service.</li> +<li><strong>La configuration</strong> : chargement de la configuration depuis les variables +d&#8217;environnement et le fichier <tt class="docutils literal">.ini</tt></li> +<li><strong>La flexibilité</strong> : dés/activation ou substitution de la majorité des composants +depuis la&nbsp;configuration.</li> +<li><strong>Le profiling</strong> : utilitaires de développement pour trouver les <a class="reference external" href="https://fr.wiktionary.org/wiki/goulet_d%E2%80%99%C3%A9tranglement">goulets +d&#8217;étranglement</a>.</li> +</ul> +<img alt="Cliquet concepts" class="align-center" src="https://blog.notmyidea.org/images/cliquet/cliquet-concepts.png" /> +<p>Proportionnellement, l&#8217;implémentation du protocole pour les resources <span class="caps">REST</span> est +la plus volumineuse dans le code source de <em>Cliquet</em>. +Cependant, comme nous l&#8217;avons décrit plus haut, <em>Cliquet</em> fournit tout un +ensemble d&#8217;outillage et de bonnes pratiques, et reste +donc tout à fait pertinent pour n&#8217;importe quel type d&#8217;<span class="caps">API</span>, même sans +manipulation de données&nbsp;!</p> +<p>L&#8217;objectif de la boîte à outils est de faire en sorte qu&#8217;un développeur puisse constuire +une application simplement, en étant sûr qu&#8217;elle réponde aux exigeances de la +mise en production, tout en ayant la possibilité de remplacer certaines parties +au fur et à mesure que ses besoins se&nbsp;précisent.</p> +<p>Par exemple, la persistence fournie par défault est <em>schemaless</em> (e.g <em><span class="caps">JSONB</span></em>), +mais rien n&#8217;empêcherait d&#8217;implémenter le stockage dans un modèle&nbsp;relationnel.</p> +<p>Comme les composants peuvent être remplacés depuis la configuration, il est +tout à fait possible d&#8217;étendre <em>Cliquet</em> avec des notions métiers ou des +codes exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation +de l&#8217;éco-système</a>.</p> +<p>Dans les prochaines semaines, nous allons introduire la notion d&#8217;«évènements» (ou signaux), +qui permettraient aux extensions de s&#8217;interfacer beaucoup plus&nbsp;proprement.</p> +<p>Nous attachons beaucoup d&#8217;importance à la clareté du code, la pertinence des +<em>patterns</em>, des tests et de la documentation. Si vous avez des commentaires, +des critiques ou des interrogations, n&#8217;hésitez pas à <a class="reference external" href="https://github.com/mozilla-services/cliquet/issues">nous en faire part</a>&nbsp;!</p> +</div> +</div> +<div class="section" id="cliquet-a-l-action"> +<h2>Cliquet, à&nbsp;l&#8217;action.</h2> +<p>Nous avons écrit un <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/quickstart.html">guide de démarrage</a>, +qui n&#8217;exige pas de connaître <em>Pyramid</em>.</p> +<p>Pour illustrer la simplicité et les concepts, voici quelques extraits&nbsp;!</p> +<div class="section" id="etape-1"> +<h3>Étape&nbsp;1</h3> +<p>Activer <em>Cliquet</em>:</p> +<div class="highlight"><pre><span></span><span class="hll"><span class="kn">import</span> <span class="nn">cliquet</span> +</span><span class="kn">from</span> <span class="nn">pyramid.config</span> <span class="kn">import</span> <span class="n">Configurator</span> + +<span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">global_config</span><span class="p">,</span> <span class="o">**</span><span class="n">settings</span><span class="p">):</span> + <span class="n">config</span> <span class="o">=</span> <span class="n">Configurator</span><span class="p">(</span><span class="n">settings</span><span class="o">=</span><span class="n">settings</span><span class="p">)</span> + +<span class="hll"> <span class="n">cliquet</span><span class="o">.</span><span class="n">initialize</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="s1">&#39;1.0&#39;</span><span class="p">)</span> +</span> <span class="k">return</span> <span class="n">config</span><span class="o">.</span><span class="n">make_wsgi_app</span><span class="p">()</span> +</pre></div> +<p>À partir de là, la plupart des outils de <em>Cliquet</em> sont activés et&nbsp;accessibles.</p> +<p>Par exemple, les URLs <em>hello</em> (<tt class="docutils literal">/v1/</tt>) ou <em>supervision</em> (<tt class="docutils literal">/v1/__heartbeat__</tt>). +Mais aussi les backends de stockage, de cache, etc. +qu&#8217;il est possible d&#8217;utiliser dans des vues classiques <em>Pyramid</em> ou <em>Cornice</em>.</p> +</div> +<div class="section" id="etape-2"> +<h3>Étape&nbsp;2</h3> +<p>Ajouter des&nbsp;vues:</p> +<div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">global_config</span><span class="p">,</span> <span class="o">**</span><span class="n">settings</span><span class="p">):</span> + <span class="n">config</span> <span class="o">=</span> <span class="n">Configurator</span><span class="p">(</span><span class="n">settings</span><span class="o">=</span><span class="n">settings</span><span class="p">)</span> + + <span class="n">cliquet</span><span class="o">.</span><span class="n">initialize</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="s1">&#39;1.0&#39;</span><span class="p">)</span> +<span class="hll"> <span class="n">config</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="s2">&quot;myproject.views&quot;</span><span class="p">)</span> +</span> <span class="k">return</span> <span class="n">config</span><span class="o">.</span><span class="n">make_wsgi_app</span><span class="p">()</span> +</pre></div> +<p>Pour définir des resources <span class="caps">CRUD</span>, il faut commencer par définir un schéma, +avec <em>Colander</em>, et ensuite déclarer une&nbsp;resource:</p> +<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">cliquet</span> <span class="kn">import</span> <span class="n">resource</span><span class="p">,</span> <span class="n">schema</span> + +<span class="k">class</span> <span class="nc">BookmarkSchema</span><span class="p">(</span><span class="n">schema</span><span class="o">.</span><span class="n">ResourceSchema</span><span class="p">):</span> + <span class="n">url</span> <span class="o">=</span> <span class="n">schema</span><span class="o">.</span><span class="n">URL</span><span class="p">()</span> + +<span class="hll"><span class="nd">@resource</span><span class="o">.</span><span class="n">register</span><span class="p">()</span> +</span><span class="hll"><span class="k">class</span> <span class="nc">Bookmark</span><span class="p">(</span><span class="n">resource</span><span class="o">.</span><span class="n">BaseResource</span><span class="p">):</span> +</span><span class="hll"> <span class="n">mapping</span> <span class="o">=</span> <span class="n">BookmarkSchema</span><span class="p">()</span> +</span></pre></div> +<p>Désormais, la resource <span class="caps">CRUD</span> est disponible sur <tt class="docutils literal">/v1/bookmarks</tt>, avec toutes +les fonctionnalités de synchronisation, filtrage, tri, pagination, timestamp, etc. +De base les enregistrements sont privés, par&nbsp;utilisateur.</p> +<div class="highlight"><pre><span></span><span class="err">$</span><span class="w"> </span><span class="err">h</span><span class="kc">tt</span><span class="err">p</span><span class="w"> </span><span class="err">GET</span><span class="w"> </span><span class="s2">&quot;http://localhost:8000/v1/bookmarks&quot;</span> +<span class="err">HTTP/</span><span class="mf">1.1</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="err">OK</span> +<span class="err">...</span> +<span class="p">{</span> +<span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span> +<span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="nt">&quot;url&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;http://cliquet.readthedocs.org&quot;</span><span class="p">,</span> +<span class="w"> </span><span class="nt">&quot;id&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;cc103eb5-0c80-40ec-b6f5-dad12e7d975e&quot;</span><span class="p">,</span> +<span class="w"> </span><span class="nt">&quot;last_modified&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">1437034418940</span><span class="p">,</span> +<span class="w"> </span><span class="p">}</span> +<span class="w"> </span><span class="p">]</span> +<span class="p">}</span> +</pre></div> +</div> +<div class="section" id="etape-3"> +<h3>Étape&nbsp;3</h3> +<p>Évidemment, il est possible choisir les <span class="caps">URLS</span>, les verbes <span class="caps">HTTP</span> supportés, de modifier +des champs avant l&#8217;enregistrement,&nbsp;etc.</p> +<div class="highlight"><pre><span></span><span class="hll"><span class="nd">@resource</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">collection_path</span><span class="o">=</span><span class="s1">&#39;/user/bookmarks&#39;</span><span class="p">,</span> +</span><span class="hll"> <span class="n">record_path</span><span class="o">=</span><span class="s1">&#39;/user/bookmarks/{{id}}&#39;</span><span class="p">,</span> +</span><span class="hll"> <span class="n">collection_methods</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;GET&#39;</span><span class="p">,))</span> +</span><span class="k">class</span> <span class="nc">Bookmark</span><span class="p">(</span><span class="n">resource</span><span class="o">.</span><span class="n">BaseResource</span><span class="p">):</span> + <span class="n">mapping</span> <span class="o">=</span> <span class="n">BookmarkSchema</span><span class="p">()</span> + +<span class="hll"> <span class="k">def</span> <span class="nf">process_record</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new</span><span class="p">,</span> <span class="n">old</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> +</span><span class="hll"> <span class="k">if</span> <span class="n">old</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">new</span><span class="p">[</span><span class="s1">&#39;device&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="n">old</span><span class="p">[</span><span class="s1">&#39;device&#39;</span><span class="p">]:</span> +</span><span class="hll"> <span class="n">device</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;User-Agent&#39;</span><span class="p">)</span> +</span><span class="hll"> <span class="n">new</span><span class="p">[</span><span class="s1">&#39;device&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">device</span> +</span><span class="hll"> <span class="k">return</span> <span class="n">new</span> +</span></pre></div> +<p><a class="reference external" href="http://cliquet.readthedocs.org/en/latest/reference/resource.html">Plus d&#8217;infos dans la documentation dédiée</a>&nbsp;!</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Il est possible de définir des resources sans validation de schema. +<a class="reference external" href="https://github.com/mozilla-services/kinto/blob/master/kinto/views/records.py">Voir le code source de Kinto</a>.</p> +</div> +</div> +<div class="section" id="etape-4-optionelle"> +<h3>Étape 4&nbsp;(optionelle)</h3> +<p>Utiliser les abstractions de <em>Cliquet</em> dans une vue <em>Cornice</em>.</p> +<p>Par exemple, une vue qui utilise le backend de&nbsp;stockage:</p> +<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">cliquet</span> <span class="kn">import</span> <span class="n">Service</span> + +<span class="n">score</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;score&quot;</span><span class="p">,</span> + <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/score/</span><span class="si">{game}</span><span class="s1">&#39;</span><span class="p">,</span> + <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Store game score&quot;</span><span class="p">)</span> + +<span class="nd">@score</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">schema</span><span class="o">=</span><span class="n">ScoreSchema</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">post_score</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="n">collection_id</span> <span class="o">=</span> <span class="s1">&#39;scores-&#39;</span> <span class="o">+</span> <span class="n">request</span><span class="o">.</span><span class="n">match_dict</span><span class="p">[</span><span class="s1">&#39;game&#39;</span><span class="p">]</span> + <span class="n">user_id</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">authenticated_userid</span> + <span class="n">value</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">validated</span> <span class="c1"># c.f. Cornice.</span> + +<span class="hll"> <span class="n">storage</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">registry</span><span class="o">.</span><span class="n">storage</span> +</span><span class="hll"> <span class="n">record</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">collection_id</span><span class="p">,</span> <span class="n">user_id</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> +</span> <span class="k">return</span> <span class="n">record</span> +</pre></div> +</div> +</div> +<div class="section" id="vos-retours"> +<h2>Vos&nbsp;retours</h2> +<p>N&#8217;hésitez pas à nous faire part de vos retours ! Cela vous a donné envie +d&#8217;essayer ? Vous connaissez un outil similaire ? +Y-a-t-il des points qui ne sont pas clairs ? Manque de cas d&#8217;utilisation concrets ? +Certains aspects mal pensés ? Trop contraignants ? Trop de magie ? Overkill&nbsp;?</p> +<p>Nous prenons&nbsp;tout.</p> +<div class="section" id="points-faibles"> +<h3>Points&nbsp;faibles</h3> +<p>Nous sommes très fiers de ce que nous avons construit, en relativement peu +de temps. Et comme nous l&#8217;exposions dans l&#8217;article précédent (plus accessible), il y a du potentiel&nbsp;!</p> +<p>Cependant, nous sommes conscients d&#8217;un certain nombre de points +qui peuvent être vus comme des&nbsp;faiblesses.</p> +<ul class="simple"> +<li><strong>La documentation d&#8217;<span class="caps">API</span></strong> : actuellement, nous n&#8217;avons pas de solution pour qu&#8217;un +projet qui utilise <em>Cliquet</em> puisse intégrer facilement toute +<a class="reference external" href="http://cliquet.readthedocs.org/en/latest/api/index.html">la documentation de l&#8217;<span class="caps">API</span></a>&nbsp;obtenue.</li> +<li><strong>La documentation</strong> : il est très difficile d&#8217;organiser la documentation, surtout +quand le public visé est aussi bien débutant qu&#8217;expérimenté. Nous sommes probablement +victimes du «<a class="reference external" href="https://en.wikipedia.org/wiki/Curse_of_knowledge">curse of knowledge</a>».</li> +<li><strong>Le protocole</strong> : on sent bien qu&#8217;on va devoir versionner le protocole. Au +moins pour le désolidariser des versions de <em>Cliquet</em>, si on veut aller au +bout de la philosophie et de&nbsp;l&#8217;éco-système.</li> +<li><strong>Le conservatisme</strong> : Nous aimons la stabilité et la robustesse. Mais surtout +nous ne sommes pas tout seuls et devons nous plier aux contraintes de la mise +en production ! Cependant, nous avons très envie de faire de l&#8217;async avec Python 3&nbsp;!</li> +<li><strong>Publication de versions</strong> : le revers de la médaille de la factorisation. Il +arrive qu&#8217;on préfère faire évoluer le toolkit (e.g. ajouter une option) pour +un point précis d&#8217;un projet. En conséquence, on doit souvent releaser les +projets en&nbsp;cascade.</li> +</ul> +</div> +<div class="section" id="quelques-questions-courantes"> +<h3>Quelques questions&nbsp;courantes</h3> +<blockquote> +Pourquoi Python ?</blockquote> +<p>On prend beaucoup de plaisir à écrire du Python, et le calendrier annoncé +initialement était très serré: pas question de tituber avec une code +mal maitrisée&nbsp;!</p> +<p>Et puis, après avoir passé près d&#8217;un an sur un projet Node.js, l&#8217;équipe avait +bien envie de refaire du&nbsp;Python.</p> +<blockquote> +Pourquoi pas Django ?</blockquote> +<p>On y a pensé, surtout parce qu&#8217;il y a plusieurs fans de <em>Django <span class="caps">REST</span> Framework</em> +dans&nbsp;l&#8217;équipe.</p> +<p>On l&#8217;a écarté principalement au profit de la légèreté et la modularité de +<em>Pyramid</em>.</p> +<blockquote> +Pourquoi pas avec un framework asynchrone en Python 3+ ?</blockquote> +<p>Pour l&#8217;instant nos administrateurs système nous imposent des déploiements en +Python 2.7, à notre grand désarroi&nbsp;/o\</p> +<p>Pour <em>Reading List</em>, nous <a class="reference external" href="https://github.com/mozilla-services/readinglist/blob/1.7.0/readinglist/__init__.py#L19-L26">avions activé</a> +<em>gevent</em>.</p> +<p>Puisque l&#8217;approche consiste à implémenter un protocole bien déterminé, nous n&#8217;excluons +pas un jour d&#8217;écrire un <em>Cliquet</em> en <em>aiohttp</em> ou <em>Go</em> si cela s&#8217;avèrerait&nbsp;pertinent.</p> +<blockquote> +Pourquoi pas <span class="caps">JSON</span>-<span class="caps">API</span> ?</blockquote> +<p>Comme nous l&#8217;expliquions au retour des APIdays, +<span class="caps">JSON</span>-<span class="caps">API</span> est une spécification qui rejoint plusieurs de nos&nbsp;intentions.</p> +<p>Quand nous avons commencé le protocole, nous ne connaissions pas <span class="caps">JSON</span>-<span class="caps">API</span>. +Pour l&#8217;instant, comme notre proposition est beaucoup plus minimaliste, le +rapprochement n&#8217;a <a class="reference external" href="https://github.com/mozilla-services/cliquet/issues/254">pas dépassé le stade de la discussion</a>.</p> +<blockquote> +Est-ce que Cliquet est un framework <span class="caps">REST</span> pour Pyramid ?</blockquote> +<p>Non.</p> +<p>Au delà des classes de resources <span class="caps">CRUD</span> de Cliquet, qui implémentent un +protocole bien précis, il faut utiliser Cornice ou Pyramid&nbsp;directement.</p> +<blockquote> +Est-ce que Cliquet est suffisamment générique pour des projets hors Mozilla ?</blockquote> +<p>Premièrement, nous faisons en sorte que tout soit contrôlable depuis la +configuration <tt class="docutils literal">.ini</tt> pour permettre la dés/activation ou substitution des&nbsp;composants.</p> +<p>Si le protocole <span class="caps">HTTP</span>/<span class="caps">JSON</span> des resources <span class="caps">CRUD</span> vous satisfait, +alors Cliquet est probablement le plus court chemin pour construire une +application qui tient la&nbsp;route.</p> +<p>Mais l&#8217;utilisation des resources <span class="caps">CRUD</span> est facultative, donc Cliquet reste pertinent +si les bonnes pratiques en terme de mise en production ou les abstractions fournies +vous paraissent valables&nbsp;!</p> +<p>Cliquet reste un moyen simple d&#8217;aller très vite pour mettre sur pied +une application&nbsp;Pyramid/Cornice.</p> +<blockquote> +Est-ce que les resources <span class="caps">JSON</span> supporte les modèles relationnels complexes ?</blockquote> +<p>La couche de persistence fournie est très simple, et devrait +répondre à la majorité des cas d&#8217;utilisation où les données n&#8217;ont pas de&nbsp;relations.</p> +<p>En revanche, il est tout à fait possible de bénéficier de tous les aspects +du protocole en utilisant une classe <tt class="docutils literal">Collection</tt> maison, qui se chargerait +elle de manipuler les&nbsp;relations.</p> +<p>Le besoin de relations pourrait être un bon prétexte pour implémenter le +protocole avec Django <span class="caps">REST</span> Framework&nbsp;:)</p> +<blockquote> +Est-il possible de faire ci ou ça avec Cliquet ?</blockquote> +<p>Nous aimerions collecter des besoins pour écrire un ensemble de «recettes/tutoriels». Mais +pour ne pas travailler dans le vide, nous aimerions <a class="reference external" href="https://github.com/mozilla-services/cliquet/issues">connaitre vos idées</a> ! +(<em>ex. brancher l&#8217;authentification Github, changer le format du logging <span class="caps">JSON</span>, stocker des +données cartographiques, &#8230;</em>)</p> +<blockquote> +Est-ce que Cliquet peut manipuler des fichiers ?</blockquote> +<p><a class="reference external" href="https://github.com/mozilla-services/cliquet/issues/236">Nous l&#8217;envisageons</a>, +mais pour l&#8217;instant nous attendons que le besoin survienne en interne pour se&nbsp;lancer.</p> +<p>Si c&#8217;est le cas, le protocole utilisé sera <a class="reference external" href="http://remotestorage.io/">Remote Storage</a>, +afin notamment de s&#8217;intégrer dans l&#8217;éco-système&nbsp;grandissant.</p> +<blockquote> +Est-ce que la fonctionnalité X va être implémentée ?</blockquote> +<p><em>Cliquet</em> est déjà bien garni. Plutôt qu&#8217;implémenter la fonctionnalité X, +il y a de grandes chances que nous agissions pour s&#8217;assurer que les abstractions +et les mécanismes d&#8217;extension fournis permettent de l&#8217;implémenter sous forme&nbsp;d&#8217;extension.</p> +</div> +</div> +Service de nuages : Perspectives pour l’été2015-07-07T00:00:00+02:002015-07-07T00:00:00+02:00tag:blog.notmyidea.org,2015-07-07:/service-de-nuages-perspectives-pour-lete-fr.html<p class="first last">Le travail en cours et les fonctionnalités à venir pour les prochains&nbsp;mois.</p> +<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> +<p>Mozilla a pour coutume d&#8217;organiser régulièrement des semaines de travail où tous les employés +sont réunis physiquement. Pour cette dernière édition, nous avons pu retrouver +nos collègues du monde entier à <a class="reference external" href="http://www.openstreetmap.org/node/268148288#map=4/50.12/-122.95">Whistler, en Colombie Britannique au Canada</a>&nbsp;!</p> +<img alt="«All Hands» talk about Lego, by &#64;davidcrob - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-talks.jpg" /> +<p>Ce fût l&#8217;occasion pour notre équipe de se retrouver, et surtout de partager notre +vision et nos idées dans le domaine du stockage, afin de collecter des cas d&#8217;utilisation pour +notre solution <a class="reference external" href="https://kinto.readthedocs.org">Kinto</a>.</p> +<p>Dans cet article, nous passons en revue les pistes que nous avons pour +les prochains&nbsp;mois.</p> +<div class="section" id="ateliers-et-promotion"> +<h2>Ateliers et&nbsp;promotion</h2> +<p>Nicolas a présenté <a class="reference external" href="https://github.com/mozilla-services/kinto.js">Kinto.js</a> dans un atelier dédié, avec comme support de +présentation le <a class="reference external" href="http://kintojs.readthedocs.org/en/latest/tutorial/">tutorial d&#8217;introduction</a>.</p> +<p>L&#8217;application résultante, pourtant toute simple, permet d&#8217;appréhender les +concepts de synchronisation de Kinto. Le tout sans installation prélable, +puisque Rémy a mis en place un <a class="reference external" href="https://kinto.dev.mozaws.net/v1/">serveur de dev effacé tous les jours</a>.</p> +<p>Nous avions mis un point d&#8217;honneur à faire du Vanilla.<span class="caps">JS</span>, déjà pour éviter les +combats de clochers autour des frameworks, mais aussi pour mettre en évidence qu&#8217;avec +<span class="caps">HTML5</span> et <span class="caps">ES6</span>, on n&#8217;était plus aussi démunis qu&#8217;il y a quelques&nbsp;années.</p> +<p>Ce petit atelier nous a permis de nous rendre compte qu&#8217;on avait encore de +grosses lacunes en terme de documentation, surtout en ce qui concerne +l&#8217;éco-système et la vision globale des projets (Kinto, Kinto.js, Cliquet, &#8230;). +Nous allons donc faire de notre mieux pour combler ce&nbsp;manque.</p> +<img alt="Kinto.js workshop - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-workshop.jpg" /> +</div> +<div class="section" id="mozilla-payments"> +<h2>Mozilla&nbsp;Payments</h2> +<p>Comme <a class="reference external" href="http://www.servicedenuages.fr/la-gestion-des-permissions">décrit précédemment</a>, nous avons mis en place un système de permissions pour répondre aux besoins de suivi des paiements et&nbsp;abonnements.</p> +<p>Pour ce projet, Kinto sera utilisé depuis une application Django, via un client&nbsp;Python.</p> +<p>Maintenant que les développements ont été livrés, il faut transformer l&#8217;essai, réussir l&#8217;intégration, l&#8217;hébergement et la montée en puissance. La solution doit être livrée à la fin de&nbsp;l&#8217;année.</p> +<div class="section" id="a-venir"> +<h3>À&nbsp;venir</h3> +<p>Nous aimerions en profiter pour implémenter une fonctionnalité qui nous tient à coeur : la construction de la liste des enregistrements accessibles en lecture sur une collection&nbsp;partagée.</p> +<img alt="Whistler Alta Lake - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-lake.jpg" /> +</div> +</div> +<div class="section" id="firefox-os-et-stockage"> +<h2>Firefox <span class="caps">OS</span> et&nbsp;stockage</h2> +<p>Nous avons eu beaucoup d&#8217;échanges avec l&#8217;équipe de Firefox <span class="caps">OS</span>, avec qui nous avions +déjà eu l&#8217;occasion de collaborer, pour le <a class="reference external" href="https://github.com/mozilla-services/msisdn-gateway">serveur d&#8217;identification BrowserID par <span class="caps">SMS</span></a> et pour <a class="reference external" href="https://github.com/mozilla-services/loop-server">Firefox Hello</a>.</p> +<div class="section" id="in-app-sync"> +<h3>In-App&nbsp;sync</h3> +<p>Kinto, la solution simple promue pour la synchronisation de données dans les applications +Firefox <span class="caps">OS</span> ? La classe ! C&#8217;est ce qu&#8217;on avait en tête depuis longtemps, déjà à +l&#8217;époque avec <a class="reference external" href="http://daybed.readthedocs.org/">Daybed</a>. Voici donc une belle opportunité à saisir&nbsp;!</p> +<p>Il va falloir expliciter les limitations et hypothèses simplificatrices de notre +solution, surtout en termes de gestion de la concurrence. Nous sommes persuadés +que ça colle avec la plupart des besoins, mais il ne faudrait pas décevoir&nbsp;:)</p> +<p>Le fait que <a class="reference external" href="https://github.com/daleharvey">Dale</a>, un des auteurs de <a class="reference external" href="http://pouchdb.com/">PouchDB</a> et <a class="reference external" href="https://github.com/michielbdejong">Michiel de Jong</a>, un des auteurs de <a class="reference external" href="http://remotestorage.io/">Remote Storage</a>, nous aient encouragés sur nos premiers pas nous a bien motivé&nbsp;!</p> +</div> +<div class="section" id="cut-the-rope"> +<h3>Cut the&nbsp;Rope</h3> +<p>Kinto devrait être mis à profit pour synchroniser les paramètres et les scores +du <a class="reference external" href="http://mozilla.cuttherope.net/">jeu</a>. Un premier exercice et une première vitrine sympas&nbsp;!</p> +</div> +<div class="section" id="syncto"> +<h3>« SyncTo&nbsp;»</h3> +<p><a class="reference external" href="https://docs.services.mozilla.com/storage/apis-1.5.html">Firefox Sync</a> est la solution qui permet de synchroniser les données de Firefox (favoris, extensions, historique, complétion des formulaires, mots de passe, &#8230;) entre plusieurs périphériques, de manière&nbsp;chiffrée.</p> +<p>L&#8217;implémentation du client en JavaScript est relativement complexe et date un peu maintenant. +Le code existant n&#8217;est pas vraiment portable dans <em>Firefox <span class="caps">OS</span></em> et les tentatives de réécriture +n&#8217;ont pas&nbsp;abouti.</p> +<p>Nous souhaitons implémenter un pont entre <em>Kinto</em> et <em>Firefox Sync</em>, de manière +à pouvoir utiliser le client <em>Kinto.js</em>, plus simple et plus moderne, pour récupérer +les contenus et les stocker dans IndexedDB. Le delta à implémenter côté serveur est faible car nous nous étions +inspirés du protocole déjà éprouvé de Sync. Côté client, il s&#8217;agira surtout de +câbler l&#8217;authentification BrowserId et la&nbsp;Crypto.</p> +<p>Alexis a sauté sur l&#8217;occasion pour commencer l&#8217;écriture d&#8217;<a class="reference external" href="https://github.com/mozilla-services/syncclient">un client python pour Firefox Sync</a>, qui servira de brique de base pour l&#8217;écriture du&nbsp;service.</p> +</div> +<div class="section" id="cloud-storage"> +<h3>Cloud&nbsp;Storage</h3> +<p>Eden Chuang et Sean Lee ont présenté les avancées sur l&#8217;intégration de services de stockages +distants (<em>DropBox, Baidu Yun</em>) dans <em>Firefox <span class="caps">OS</span></em>. Actuellement, leur preuve de +concept repose sur <a class="reference external" href="https://fr.wikipedia.org/wiki/Filesystem_in_Userspace"><span class="caps">FUSE</span></a>.</p> +<p>Nous avons évidemment en tête d&#8217;introduire la notion de fichiers attachés dans +<em>Kinto</em>, en implémentant la specification +<a class="reference external" href="https://tools.ietf.org/html/draft-dejong-remotestorage-05">*Remote Storage*</a>, +mais pour l&#8217;instant les cas d&#8217;utilisations ne se sont pas encore présentés&nbsp;officiellement.</p> +</div> +<div class="section" id="a-venir-1"> +<h3>À&nbsp;venir</h3> +<p>Nous serons probablement amenés à introduire la gestion de la concurrence dans +le client <span class="caps">JS</span>, en complément de ce qui a été fait sur le serveur, pour permettre +les écritures simultanées et synchronisation en tâche de&nbsp;fond.</p> +<p>Nous sommes par ailleurs perpétuellement preneurs de vos retours — et bien +entendu de vos contributions — tant sur le code <a class="reference external" href="https://github.com/mozilla-services/kinto/">serveur</a> +que <a class="reference external" href="https://github.com/mozilla-services/kinto.js/">client</a>&nbsp;!</p> +<img alt="Firefox OS Cloud Storage Presentation - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-cloud-storage.jpg" /> +</div> +</div> +<div class="section" id="contenus-applicatifs-de-firefox"> +<h2>Contenus applicatifs de&nbsp;Firefox</h2> +<p>Aujourd&#8217;hui Firefox a un cycle de release de six semaines. Un des objectifs +consiste à désolidariser certains contenus applicatifs de ces cycles +relativement longs (ex. <em>règles de securité, dictionnaires, traductions, &#8230;</em>) <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a>.</p> +<p>Il s&#8217;agit de données <span class="caps">JSON</span> et binaire qui doivent être versionnées et synchronisées par +les navigateurs (<em>lecture seule</em>).</p> +<p>Il y a plusieurs outils officiels qui existent pour gérer ça (<em>Balrog</em>, <em>Shavar</em>, &#8230;), +et pour l&#8217;instant, aucun choix n&#8217;a été fait. Mais lors des conversations avec +l&#8217;équipe en charge du projet, ce fût vraiment motivant de voir que même pour +ce genre de besoins internes, <em>Kinto</em> est tout aussi pertinent&nbsp;!</p> +<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>La bonne nouvelle c&#8217;est que toutes les fonctionnalités <em>third-party</em> qui ont +été intégrées récemment vont redevenir des <em>add-ons</em> \o/.</td></tr> +</tbody> +</table> +<img alt="Landscape - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-landscape.jpg" /> +</div> +<div class="section" id="awesome-bar"> +<h2>Awesome&nbsp;bar</h2> +<p>L&#8217;équipe <em>Firefox Labs</em>, le laboratoire qui élève des pandas roux en éprouvette, +serait vraiment intéressé par notre solution, notamment pour abreuver en données +un prototype pour améliorer <em>Awesome bar</em>, qui fusionnerait <span class="caps">URL</span>, historique et&nbsp;recherche.</p> +<p>Nous ne pouvons pas en dire beaucoup plus pour l&#8217;instant, mais les fonctionnalités +de collections d&#8217;enregistrements partagées entre utilisateurs de <em>Kinto</em> +correspondent parfaitement à ce qui est envisagé pour le futur du navigateur&nbsp;:)</p> +<div class="section" id="a-venir-2"> +<h3>À&nbsp;venir</h3> +<p>Nous serons donc probablement amenés, avant de la fin de l&#8217;année, à introduire des +fonctionnalités d&#8217;indexation et de recherche <em>full-text</em> (comprendre <em>ElasticSearch</em>). +Cela rejoint nos plans précédents, puisque c&#8217;est quelque chose que nous avions dans +<em>Daybed</em>, et qui figurait sur notre feuille de route&nbsp;!</p> +<img alt="Firefox Labs Meeting - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-labs.jpg" /> +</div> +</div> +<div class="section" id="browser-html"> +<h2>Browser.html</h2> +<p>L&#8217;équipe <em>Recherche</em> explore les notions de plateforme, et travaille notamment +sur l&#8217;implémentation d&#8217;un navigateur en <span class="caps">JS</span>/<span class="caps">HTML</span> avec <em>React</em>: +<a class="reference external" href="https://github.com/mozilla/browser.html">browser.html</a></p> +<p><em>Kinto</em> correspond parfaitement aux attentes +de l&#8217;équipe pour synchroniser les données associées à un&nbsp;utilisateur.</p> +<p>Il pourrait s&#8217;agir de données de navigation (comme Sync), mais aussi de collections +d&#8217;enregistrements diverses, comme par exemple les préférences du navigateur +ou un équivalent à <em>Alexa.com Top 500</em> pour fournir la complétion d&#8217;<span class="caps">URL</span> sans +interroger le moteur de&nbsp;recherche.</p> +<p>L&#8217;exercice pourrait être poussé jusqu&#8217;à la synchronisation d&#8217;états <em>React</em> +entre périphériques (par exemple pour les&nbsp;onglets).</p> +<div class="section" id="a-venir-3"> +<h3>À&nbsp;venir</h3> +<p>Si <em>browser.html</em> doit stocker des données de navigation, il faudra ajouter +des fonctionnalités de chiffrement sur le client <span class="caps">JS</span>. Ça tombe bien, c&#8217;est un +sujet passionant, et <a class="reference external" href="http://www.w3.org/TR/WebCryptoAPI/">il y a plusieurs standards</a>&nbsp;!</p> +<p>Pour éviter d&#8217;interroger le serveur à intervalle régulier afin de synchroniser les +changements, l&#8217;introduction des <a class="reference external" href="https://w3c.github.io/push-api/">*push notifications*</a> semble assez naturelle. +Il s&#8217;agirait alors de la dernière pierre qui manque à l&#8217;édifice pour obtenir +un «<em>Mobile/Web backend as a service</em>»&nbsp;complet.</p> +<img alt="Roadmap - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-roadmap.jpg" /> +</div> +</div> +<div class="section" id="conclusion"> +<h2>Conclusion</h2> +<p>Nous sommes dans une situation idéale, puisque ce que nous avions imaginé +sur <a class="reference external" href="https://github.com/mozilla-services/kinto/wiki/Roadmap">notre feuille de route</a> correspond à ce qui nous est demandé par les +différentes&nbsp;équipes.</p> +<p>L&#8217;enjeu consiste maintenant à se coordonner avec tout le monde, ne pas décevoir, +tenir la charge, continuer à améliorer et à faire la promotion du produit, se concentrer +sur les prochaines étapes et embarquer quelques contributeurs à nos cotés pour +construire une solution libre, générique, simple et auto-hébergeable pour le stockage +de données sur le Web&nbsp;:)</p> +<img alt="Friday Night Party - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-top-roof.jpg" /> +</div> +Service de nuages : Achievement unlocked2015-06-01T00:00:00+02:002015-06-01T00:00:00+02:00tag:blog.notmyidea.org,2015-06-01:/service-de-nuages-achievement-unlocked-fr.html<p class="first last">Après près de 3 mois intensifs, nous venons de <em>tagguer</em> Cliquet 2.0 +et Kinto 1.0&nbsp;!</p> +<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> +<p>Aujourd&#8217;hui, c&#8217;est jour de fête : nous venons de publier Cliquet <strong>2.0</strong> +<a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a> et Kinto <strong>1.0</strong> <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a>.</p> +<blockquote class="epigraph"> +<p>L&#8217;aboutissement de 3 années de R&amp;D&nbsp;!</p> +<p class="attribution">&mdash;Rémy</p> +</blockquote> +<p><a class="reference external" href="https://kinto.readthedocs.org/en/latest/">Kinto</a> est un service pour +stocker, synchroniser et partager des données arbitraires, attachées à un +compte Firefox (mais le système d&#8217;authentification est <em>pluggable</em>).</p> +<p><a class="reference external" href="https://cliquet.readthedocs.org/en/latest/">Cliquet</a> est une boite à outils pour faciliter l&#8217;implémentation de +micro-services <span class="caps">HTTP</span> tels que les APIs <em><span class="caps">REST</span></em> ayant des besoins de&nbsp;synchronisation.</p> +<p>Vous pouvez lire plus à propos des raisons qui nous ont poussé à proposer cette nouvelle solution +et de notre ambition sur <a class="reference external" href="http://www.servicedenuages.fr/eco-systeme-et-stockage-generique.html">http://www.servicedenuages.fr/eco-systeme-et-stockage-generique.html</a></p> +<p>Nous sommes fiers du travail que nous avons pu réaliser durant ces derniers +mois sur ces deux projets. Bien que la plupart du travail que nous ayons +réalisé pour le serveur de liste de lecture (Reading List) ait pu être utilisé, +beaucoup de parties ont été repensées et nous avons introduit des +fonctionnalités que l&#8217;on attendait depuis longtemps, comme la gestion des&nbsp;permissions.</p> +<p>Bien sur, exactement comme après un ré-aménagement de salon, on ne peut +s&#8217;empêcher de voir toutes les choses qui doivent toujours être améliorées, +notamment sur la documentation et les&nbsp;performances.</p> +<p>On peut déjà entrevoir à quoi l&#8217;écosystème va ressembler, et c&#8217;est prometteur. +Il y a déjà un client JavaScript <a class="footnote-reference" href="#footnote-3" id="footnote-reference-3">[3]</a> dont l&#8217;objectif est de synchroniser les +données locales du navigateur avec une instance de&nbsp;Kinto.</p> +<p>N&#8217;hésitez vraiment pas à nous solliciter pour discuter avec vous si vous avez +des problématiques proches : nous accueillons avec plaisir toutes sortes de +retours, que ce soit à propos du code, de la documentation, de la sécurité de +la solution ou de la manière de communiquer avec le monde extérieur. Si vous +souhaitez nous contacter, vous pouvez laisser un commentaire ici ou nous +contacter sur le canal <a class="reference external" href="irc://irc.mozilla.org/#storage">#storage</a> sur le réseau <span class="caps">IRC</span> de&nbsp;Mozilla.</p> +<p>Et ce n&#8217;est que le début ! Le futur se dessine dans notre feuille de route +<a class="footnote-reference" href="#footnote-4" id="footnote-reference-4">[4]</a>.</p> +<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td><strong>Cliquet</strong> est une boite à outils pour faciliter l&#8217;implémentation de +microservices <span class="caps">HTTP</span> tels que les APIs <em><span class="caps">REST</span></em> ayant des besoins de +synchronisation.</td></tr> +</tbody> +</table> +<table class="docutils footnote" frame="void" id="footnote-2" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td><strong>Kinto</strong> est un service pour stocker, synchroniser et partager des données +arbitraires, attachées à un compte Firefox (mais le système d&#8217;authentification +est <em>pluggable</em>).</td></tr> +</tbody> +</table> +<table class="docutils footnote" frame="void" id="footnote-3" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-3">[3]</a></td><td>Cliquetis, la bibliothèque JavaScript pour consommer l&#8217;<span class="caps">API</span> <span class="caps">HTTP</span> de Kinto — +<a class="reference external" href="https://github.com/mozilla-services/cliquetis">https://github.com/mozilla-services/cliquetis</a></td></tr> +</tbody> +</table> +<table class="docutils footnote" frame="void" id="footnote-4" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-4">[4]</a></td><td>La feuille de route de Kinto: <a class="reference external" href="https://github.com/mozilla-services/kinto/wiki/roadmap">https://github.com/mozilla-services/kinto/wiki/roadmap</a></td></tr> +</tbody> +</table> +Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> +<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> +<p><strong>tl;dr: On a maintenant un super système de permission mais comment faire pour stocker et interroger ces permissions de manière efficace&nbsp;?</strong></p> +<div class="section" id="la-problematique"> +<h2>La&nbsp;problématique</h2> +<p>Maintenant que nous avons défini un modèle de gestion des permissions +sur les objets qui nous satisfait, le problème est de stocker ces +permissions de manière efficace afin de pouvoir autoriser ou interdire +l&#8217;accès à un objet pour la personne qui fait la&nbsp;requête.</p> +<p>Chaque requête sur notre <span class="caps">API</span> va générer une ou plusieurs demandes +d&#8217;accès, il faut donc que la réponse soit très rapide sous peine +d&#8217;impacter la vélocité du&nbsp;service.</p> +</div> +<div class="section" id="obtenir-la-liste-des-principals-d-un-utilisateur"> +<h2>Obtenir la liste des &#8220;principals&#8221; d&#8217;un&nbsp;utilisateur</h2> +<p>Les <em>principals</em> de l&#8217;utilisateur correspondent à son <tt class="docutils literal">user_id</tt> +ainsi qu&#8217;à la liste des identifiants des groupes dans lesquels il a +été&nbsp;ajouté.</p> +<p>Pour éviter de recalculer les <em>principals</em> de l&#8217;utilisateur à chaque +requête, le mieux reste de maintenir une liste des <em>principals</em> par&nbsp;utilisateur.</p> +<p>Ainsi lorsqu&#8217;on ajoute un utilisateur à un groupe, il faut bien penser +à ajouter le groupe à la liste des <em>principals</em> de&nbsp;l&#8217;utilisateur.</p> +<p>Ça se complexifie lorsqu&#8217;on ajoute un groupe à un&nbsp;groupe.</p> +<p>Dans un premier temps interdire l&#8217;ajout d&#8217;un groupe à un groupe est +une limitation qu&#8217;on est prêts à accepter pour simplifier le&nbsp;modèle.</p> +<p>L&#8217;avantage de maintenir la liste des <em>principals</em> d&#8217;un utilisateur +lors de la modification de cette liste c&#8217;est qu&#8217;elle est déjà +construite lors des lectures, qui sont dans notre cas plus fréquentes +que les&nbsp;écritures.</p> +<p>Cela nécessite de donner un identifiant unique aux groupes pour tous +les <em>buckets</em>.</p> +<p>Nous proposons de de les nommer avec leur <span class="caps">URI</span>: +<tt class="docutils literal">/buckets/blog/groups/moderators</tt></p> +</div> +<div class="section" id="obtenir-la-liste-des-principals-d-un-ace"> +<h2>Obtenir la liste des &#8220;principals&#8221; d&#8217;un <span class="caps">ACE</span></h2> +<blockquote> +Rappel, un &#8220;<span class="caps">ACE</span>&#8221; est un <em>Access Control Entry</em>, un des éléments +d&#8217;une <span class="caps">ACL</span> (e.g. <em>modifier un enregistrement</em>).</blockquote> +<p>Avec le <a class="reference external" href="https://blog.notmyidea.org/service-de-nuages-la-gestion-des-permissions-fr.html">système de permissions choisi</a>, les permissions d&#8217;un +objet héritent de celle de l&#8217;objet&nbsp;parent.</p> +<p>Par exemple, avoir le droit d&#8217;écriture sur un <em>bucket</em> permet la +création des permissions et la modification de tous ses&nbsp;records.</p> +<p>Ce qui veut dire que pour obtenir la liste complète des <em>principals</em> +ayant une permission sur un objet, il faut regarder à plusieurs&nbsp;endroits.</p> +<p>Rémy a <a class="reference external" href="https://gist.github.com/Natim/77c8f61c1d42e476cef8#file-permission-py-L9-L52">décrit dans un gist la liste d&#8217;héritage de chaque permission</a>.</p> +<p>Prenons l&#8217;exemple de l&#8217;ajout d&#8217;un record dans une&nbsp;collection.</p> +<p>Le droit <tt class="docutils literal">records:create</tt> est obtenu si l&#8217;on a l&#8217;un des droits&nbsp;suivants:</p> +<ul class="simple"> +<li><tt class="docutils literal">bucket:write</tt></li> +<li><tt class="docutils literal">collection:write</tt></li> +<li><tt class="docutils literal">records:create</tt></li> +</ul> +<p>Notre première idée était de stocker les permissions sur chaque objet +et de maintenir la liste exhaustive des permissions lors d&#8217;une +modification d&#8217;<span class="caps">ACL</span>. Cependant cela nécessitait de construire cette +liste lors de l&#8217;ajout d&#8217;un objet et de mettre à jour tout l&#8217;arbre lors +de sa suppression. (<em>Je vous laisse imaginer le nombre d&#8217;opérations +nécessaires pour ajouter un administrateur sur un *bucket</em> contenant +1000 collections avec 100000 records&nbsp;chacune.*)</p> +<p>La solution que nous avons désormais adoptée consiste à stocker les +<em>principals</em> de chaque <em><span class="caps">ACE</span></em> (<em>qui</em> a le droit de faire telle action +sur l&#8217;objet), et de faire l&#8217;union des <em><span class="caps">ACE</span></em> hérités, afin de les +croiser avec les <em>principals</em> de l&#8217;utilisateur&nbsp;:</p> +<blockquote> +(<span class="caps">ACE</span>(object, permission) ∪ inherited_ACE) ∩ <span class="caps">PRINCIPALS</span>(user)</blockquote> +<p>Par exemple l&#8217;<span class="caps">ACE</span>: <tt class="docutils literal">/buckets/blog/collections/article:records:create</tt> hérite de +l&#8217;<span class="caps">ACE</span> <tt class="docutils literal">/buckets/blog/collections/article:write</tt> et de <tt class="docutils literal">/buckets/blog:write</tt> :</p> +<blockquote> +(<span class="caps">ACE</span>(/buckets/blog/collections/article:records:create) ∪ <span class="caps">ACE</span>(/buckets/blog/collections/article:write) ∪ <span class="caps">ACE</span>(/buckets/blog:write)) ∩ <span class="caps">PRINCIPALS</span>(&#8216;fxa:alexis&#8217;)</blockquote> +</div> +<div class="section" id="recuperer-les-donnees-de-l-utilisateur"> +<h2>Récupérer les données de&nbsp;l&#8217;utilisateur</h2> +<p>La situation se corse lorsqu&#8217;on souhaite limiter la liste des +<em>records</em> d&#8217;une collection à ceux accessibles pour l&#8217;utilisateur, car +on doit faire cette intersection pour tous les <em>records</em>.</p> +<p>Une première solution est de regarder si l&#8217;utilisateur est mentionné +dans les <em><span class="caps">ACL</span>*s du *bucket</em> ou de la <em>collection</em>:</p> +<p>Ensuite, si ce n&#8217;est pas le cas, alors on filtre les <em>records</em> pour +lesquels les <em>principals</em> correspondent à ceux de&nbsp;l&#8217;utilisateur.</p> +<div class="highlight"><pre><span></span><span class="n">principals</span> <span class="o">=</span> <span class="n">get_user_principals</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span> +<span class="n">can_read_all</span> <span class="o">=</span> <span class="n">has_read_perms</span><span class="p">(</span><span class="n">bucket_id</span><span class="p">,</span> <span class="n">collection_id</span><span class="p">,</span> + <span class="n">principals</span><span class="p">)</span> +<span class="k">if</span> <span class="n">can_read_all</span><span class="p">:</span> + <span class="n">records</span> <span class="o">=</span> <span class="n">get_all_records</span><span class="p">(</span><span class="n">bucket_id</span><span class="p">,</span> <span class="n">collection_id</span><span class="p">,</span> + <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="o">...</span><span class="p">])</span> +<span class="k">else</span><span class="p">:</span> + <span class="n">records</span> <span class="o">=</span> <span class="n">filter_read_records</span><span class="p">(</span><span class="n">bucket_id</span><span class="p">,</span> <span class="n">collection_id</span><span class="p">,</span> + <span class="n">principals</span><span class="o">=</span><span class="n">principals</span><span class="p">,</span> + <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="o">...</span><span class="p">])</span> +</pre></div> +<p>Il faudra faire quelque chose de similaire pour la suppression +multiple, lorsqu&#8217;un utilisateur souhaitera supprimer des +enregistrements sur lesquels il a les droits de lecture mais pas&nbsp;d&#8217;écriture.</p> +</div> +<div class="section" id="le-modele-de-donnees"> +<h2>Le modèle de&nbsp;données</h2> +<p>Pour avoir une idée des requêtes dans un backend <span class="caps">SQL</span>, voyons un peu ce +que donnerait le modèle de&nbsp;données.</p> +<div class="section" id="le-format-des-id"> +<h3>Le format des <span class="caps">ID</span></h3> +<p>Utiliser des <span class="caps">URI</span> comme identifiant des objets présente de nombreux +avantages (lisibilité, unicité, cohérence avec les&nbsp;URLs)</p> +<ul class="simple"> +<li>bucket: <tt class="docutils literal">/buckets/blog</tt></li> +<li>groupe: <tt class="docutils literal">/buckets/blog/group/moderators</tt></li> +<li>collection: <tt class="docutils literal">/buckets/blog/collections/articles</tt></li> +<li>record: <tt class="docutils literal"><span class="pre">/buckets/blog/collections/articles/records/02f3f76f-7059-4ae4-888f-2ac9824e9200</span></tt></li> +</ul> +</div> +<div class="section" id="les-tables"> +<h3>Les&nbsp;tables</h3> +<p>Pour le stockage des principals et des&nbsp;permissions:</p> +<div class="highlight"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">user</span><span class="p">(</span><span class="n">id</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[]);</span> +<span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">perms</span><span class="p">(</span><span class="n">ace</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[]);</span> +</pre></div> +<p>La table <em>perms</em> va associer des <em>principals</em> à chaque <em><span class="caps">ACE</span></em>&nbsp;(e.g.&#8220;/buckets/blog:write&#8220;).</p> +<p>Pour le stockage des&nbsp;données:</p> +<div class="highlight"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">object</span><span class="p">(</span><span class="n">id</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="n">JSONB</span><span class="p">,</span> +<span class="w"> </span><span class="n">write_principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[],</span><span class="w"> </span><span class="n">read_principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[]);</span> +</pre></div> +<p>La colonne <em>parent_id</em> permet de savoir à qui appartient l&#8217;objet +(e.g. groupe d&#8217;un <em>bucket</em>, collection d&#8217;un <em>bucket</em>, <em>record</em> d&#8217;une +collection,&nbsp;&#8230;).</p> +</div> +<div class="section" id="exemple-d-utilisateur"> +<h3>Exemple&nbsp;d&#8217;utilisateur</h3> +<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="p">)</span> +<span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;fxa:alexis&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">);</span> + +<span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="p">)</span> +<span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;fxa:natim&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{&quot;/buckets/blog/groups/moderators&quot;}&#39;</span><span class="p">);</span> +</pre></div> +</div> +<div class="section" id="exemple-d-objets"> +<h3>Exemple&nbsp;d&#8217;objets</h3> +<div class="section" id="bucket"> +<h4>Bucket</h4> +<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> +<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> +<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;bucket&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="k">NULL</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;blog&quot;}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{&quot;fxa:alexis&quot;}&#39;</span><span class="p">);</span> +</pre></div> +</div> +<div class="section" id="group"> +<h4>Group</h4> +<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> +<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> +<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog/groups/moderators&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;group&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;moderators&quot;, &quot;members&quot;: [&#39;</span><span class="n">fxa</span><span class="p">:</span><span class="n">natim</span><span class="s1">&#39;]}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">);</span> +</pre></div> +<p>Ce groupe peut être gére par <tt class="docutils literal">fxa:alexis</tt> puisqu&#8217;il a la permission +<tt class="docutils literal">write</tt> dans le <em>bucket</em>&nbsp;parent.</p> +</div> +<div class="section" id="collection"> +<h4>Collection</h4> +<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> +<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> +<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/articles&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;collection&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;article&quot;}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{&quot;system.Everyone&quot;}&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{&quot;/buckets/blog/groups/moderators&quot;}&#39;</span><span class="p">);</span> +</pre></div> +<p>Cette collection d&#8217;articles peut être lue par tout le monde, +et gérée par les membres du groupe <tt class="docutils literal">moderators</tt>, ainsi que +<tt class="docutils literal">fxa:alexis</tt>, via le <em>bucket</em>.</p> +</div> +<div class="section" id="records"> +<h4>Records</h4> +<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> +<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> +<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/articles/records/02f3f76f-7059-4ae4-888f-2ac9824e9200&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;record&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/articles&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;02f3f76f-7059-4ae4-888f-2ac9824e9200&quot;,</span> +<span class="s1"> &quot;title&quot;: &quot;Stocker les permissions&quot;, ...}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">);</span> +</pre></div> +</div> +</div> +<div class="section" id="interroger-les-permissions"> +<h3>Interroger les&nbsp;permissions</h3> +<div class="section" id="obtenir-la-liste-des-principals-d-un-ace-1"> +<h4>Obtenir la liste des &#8220;principals&#8221; d&#8217;un <span class="caps">ACE</span></h4> +<p>Comme vu plus haut, pour vérifier une permission, on fait l&#8217;union des +<em>principals</em> requis par les objets hérités, et on teste leur +intersection avec ceux de&nbsp;l&#8217;utilisateur:</p> +<div class="highlight"><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="n">required_principals</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span> +<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">unnest</span><span class="p">(</span><span class="n">principals</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">p</span> +<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">perms</span> +<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">ace</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog:write&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog:read&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/article:write&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/article:read&#39;</span><span class="p">)</span> +<span class="w"> </span><span class="p">),</span> +<span class="w"> </span><span class="n">user_principals</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span> +<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">unnest</span><span class="p">(</span><span class="n">principals</span><span class="p">)</span> +<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">user</span> +<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;fxa:natim&#39;</span> +<span class="w"> </span><span class="p">)</span> +<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> +<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">user_principals</span><span class="w"> </span><span class="n">a</span> +<span class="w"> </span><span class="k">INNER</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="n">required_principals</span><span class="w"> </span><span class="n">b</span> +<span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">b</span><span class="p">.</span><span class="n">p</span><span class="p">;</span> +</pre></div> +</div> +<div class="section" id="filtrer-les-objets-en-fonction-des-permissions"> +<h4>Filtrer les objets en fonction des&nbsp;permissions</h4> +<p>Pour filtrer les objets, on fait une simple intersection de liste +(<em>merci PostgreSQL</em>):</p> +<div class="highlight"><pre><span></span><span class="k">SELECT</span><span class="w"> </span><span class="k">data</span> +<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="n">o</span><span class="p">,</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="n">u</span> +<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">o</span><span class="p">.</span><span class="k">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;record&#39;</span> +<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">o</span><span class="p">.</span><span class="n">parent_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/article&#39;</span> +<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="p">(</span><span class="n">o</span><span class="p">.</span><span class="n">read_principals</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">u</span><span class="p">.</span><span class="n">principals</span><span class="w"> </span><span class="k">OR</span> +<span class="w"> </span><span class="n">o</span><span class="p">.</span><span class="n">write_principals</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">u</span><span class="p">.</span><span class="n">principals</span><span class="p">)</span> +<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">u</span><span class="p">.</span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;fxa:natim&#39;</span><span class="p">;</span> +</pre></div> +<p>Les listes s&#8217;indexent bien, notamment grâce aux <a class="reference external" href="http://www.postgresql.org/docs/current/static/indexes-types.html">index <span class="caps">GIN</span></a>.</p> +</div> +</div> +<div class="section" id="avec-redis"> +<h3>Avec&nbsp;Redis</h3> +<p><em>Redis</em> présente plusieurs avantages pour ce genre de +problématiques. Notamment, il gère les <em>set</em> nativement (listes de +valeurs uniques), ainsi que les opérations d&#8217;intersection et&nbsp;d&#8217;union.</p> +<p>Avec <em>Redis</em> on peut écrire l&#8217;obtention des <em>principals</em> pour un <em><span class="caps">ACE</span></em> +comme cela&nbsp;:</p> +<div class="highlight"><pre><span></span>SUNIONSTORE temp_perm:/buckets/blog/collections/articles:write permission:/buckets/blog:write permission:/buckets/blog/collections/articles:write +SINTER temp_perm:/buckets/blog/collections/articles:write principals:fxa:alexis +</pre></div> +<ul class="simple"> +<li><tt class="docutils literal"><span class="caps">SUNIONSTORE</span></tt> permet de créer un set contenant les éléments de +l&#8217;union de tous les set suivants. Dans notre cas on le nomme +<tt class="docutils literal"><span class="pre">temp_perm:/buckets/blog/collections/articles:write</span></tt> et il contient +l&#8217;union des sets d&#8217;ACLs suivants: +- <tt class="docutils literal"><span class="pre">permission:/buckets/blog:write</span></tt> +- <tt class="docutils literal"><span class="pre">permission:/buckets/blog/collections/articles:write</span></tt></li> +<li><tt class="docutils literal"><span class="caps">SINTER</span></tt> retourne l&#8217;intersection de tous les sets passés en paramètres dans notre cas : +- <tt class="docutils literal"><span class="pre">temp_perm:/buckets/blog/collections/articles:write</span></tt> +- <tt class="docutils literal">principals:fxa:alexis</tt></li> +</ul> +<p>Plus d&#8217;informations sur : +- <a class="reference external" href="http://redis.io/commands/sinter">http://redis.io/commands/sinter</a> +- <a class="reference external" href="http://redis.io/commands/sunionstore">http://redis.io/commands/sunionstore</a></p> +<p>Si le set résultant de la commande <tt class="docutils literal"><span class="caps">SINTER</span></tt> n&#8217;est pas vide, alors +l&#8217;utilisateur possède la&nbsp;permission.</p> +<p>On peut ensuite supprimer la clé temporaire <tt class="docutils literal">temp_perm</tt>.</p> +<p>En utilisant <tt class="docutils literal"><span class="caps">MULTI</span></tt> on peut <a class="reference external" href="https://gist.github.com/Natim/77c8f61c1d42e476cef8#file-permission-py-L117-L124">même faire tout cela au sein d&#8217;une +transaction</a> +et garantir ainsi l&#8217;intégrité de la&nbsp;requête.</p> +</div> +</div> +<div class="section" id="conclusion"> +<h2>Conclusion</h2> +<p>La solution a l&#8217;air simple mais nous a demandé beaucoup de réflexion +en passant par plusieurs&nbsp;propositions.</p> +<p>L&#8217;idée finale est d&#8217;avoir&nbsp;:</p> +<ul class="simple"> +<li>Un backend spécifique permettant de stocker les <em>principals</em> des +utilisateurs et des <em><span class="caps">ACE</span></em> (e.g. avec les sets Redis)&nbsp;;</li> +<li>La liste des principals read et write sur la table des&nbsp;objets.</li> +</ul> +<p>C&#8217;est dommage d&#8217;avoir le concept de permissions à deux endroits, mais +cela permet de connaître rapidement la permission d&#8217;un utilisateur sur +un objet et également de pouvoir récupérer tous les objets d&#8217;une +collection pour un utilisateur si celui-ci n&#8217;a pas accès à tous les +records de la collection, ou toutes les collections du&nbsp;bucket.</p> +</div> +Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote> +<p>Flip a bit in the communication between sender and recipient and they +will experience decryption or verification errors. How high are the +chances they will start to exchange the data in the clear rather than +trying to hunt down the man in the&nbsp;middle?</p> +<p>&#8212; <a href="http://secushare.org/PGP">http://secushare.org/<span class="caps">PGP</span></a></p> +</blockquote> +<p>Une fois …</p><blockquote> +<p>Flip a bit in the communication between sender and recipient and they +will experience decryption or verification errors. How high are the +chances they will start to exchange the data in the clear rather than +trying to hunt down the man in the&nbsp;middle?</p> +<p>&#8212; <a href="http://secushare.org/PGP">http://secushare.org/<span class="caps">PGP</span></a></p> +</blockquote> +<p>Une fois passé l&#8217;euphorie du &#8220;il faut utiliser <span class="caps">PGP</span> pour l&#8217;ensemble de +nos communications&#8221;, j&#8217;ai réalisé lors de discussions que <span class="caps">PGP</span> avait +plusieurs problèmes, parmi&nbsp;ceux-ci:</p> +<ul> +<li>Les <em>meta données</em> (y compris le champ &#8220;sujet&#8221; de la conversation) + sont quand même échangées en clair (il est possible de savoir qu&#8217;un + message à été échangé entre telle et telle personne, a telle&nbsp;date);</li> +<li><span class="caps">PGP</span> se base sur un protocole de communication qui est lui non + chiffré, et il est donc facile de soit se tromper, soit dégrader le + mode de conversation vers une méthode non&nbsp;chiffrée;</li> +<li>Il est facile de connaître votre réseau social avec <span class="caps">PGP</span>, puisque + tout le principe est de signer les clés des personnes dont vous + validez&nbsp;l&#8217;identité;</li> +<li>En cas de fuite de votre clé privée, tous les messages que vous avez + chiffrés avec elle sont compromis. On dit que <span class="caps">PGP</span> ne fournit pas de + <em>forward secrecy</em>;</li> +<li>La découverte de la clé de pairs se passe souvent <em>en clair</em>, sans + utiliser une connexion &#8220;sécurisée&#8221; (<span class="caps">HTTPS</span>). Tout le monde peut donc + voir ces échanges et savoir de qui vous cherchez la&nbsp;clé;</li> +<li>Les discussions de groupes sont très difficiles: il faut chiffrer + pour chacun des destinataires (ou que ceux-ci partagent une paire de&nbsp;clés).</li> +</ul> +<p>Je suis en train de creuser à propos les alternatives à <span class="caps">PGP</span>, par exemple +<a href="https://pond.imperialviolet.org/">Pond</a>, qui lui ne construit pas par +dessus un standard déjà établi, et donc n&#8217;hérite pas de ses défauts +(mais pas non plus de son réseau déjà&nbsp;établi).</p> +<p>En attendant, quelques bonnes pratiques sur <span class="caps">PGP</span>&nbsp;;)</p> +<h2 id="bonnes-pratiques">Bonnes&nbsp;pratiques</h2> +<p>Il est en fait assez facile d&#8217;utiliser <span class="caps">PGP</span> de travers. Riseup à fait <a href="https://help.riseup.net/en/security/message-security/openpgp/best-practices">un +excellent +guide</a> +qui explique comment configurer son installation&nbsp;correctement.</p> +<ul> +<li>J&#8217;en ai déjà parlé, mais il faut absolument choisir des phrases de + passes suffisamment longues. Pas facile de les retenir, mais + indispensable. Vous pouvez aussi avoir un document chiffré avec une + clé que vous ne mettez jamais en ligne, qui contiens ces phrases de + passe, au cas ou vous les&nbsp;oubliez.</li> +<li>Générez des clés <span class="caps">RSA</span> de 4096 bits, en utilisant&nbsp;sha512;</li> +<li>Il faut utiliser une date d&#8217;expiration de nos clés suffisamment + proche (2 ans). Il est possible de repousser cette date si + nécessaire, par la&nbsp;suite.</li> +</ul> +<p>Parmi les choses les plus frappantes que j&#8217;ai&nbsp;rencontrées:</p> +<ul> +<li>Utiliser le <em>flag</em> –hidden-recipient avec <span class="caps">PGP</span> pour ne pas dévoiler + qui est le destinataire du&nbsp;message;</li> +<li>Ne pas envoyer les messages de brouillons sur votre serveur, ils le + seraient en clair&nbsp;!;</li> +<li>Utilisez <span class="caps">HPKS</span> pour communiquer avec les serveurs de clés, sinon tout + le trafic est en&nbsp;clair.</li> +</ul> +<p>Le <a href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils +de chiffrement d&#8217;échanges de messages et de <span class="caps">VPN</span> simples à utiliser, +encore quelque chose à&nbsp;regarder.</p> +<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Simplifier les preuves d’identités2015-05-11T00:00:00+02:002015-05-11T00:00:00+02:00tag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.html +<ul> +<li>headline<br> + Qu&#8217;est-ce que Keybase.io et comment essayent-ils de simplifier la + création de preuves&nbsp;d&#8217;identité.</li> +</ul> +<p>L&#8217;un des problèmes non réellement résolu actuellement quant au +chiffrement des échanges est lié à l&#8217;authenticité des clés. Si quelqu&#8217;un +décide de publier une clé en mon nom, et en …</p> +<ul> +<li>headline<br> + Qu&#8217;est-ce que Keybase.io et comment essayent-ils de simplifier la + création de preuves&nbsp;d&#8217;identité.</li> +</ul> +<p>L&#8217;un des problèmes non réellement résolu actuellement quant au +chiffrement des échanges est lié à l&#8217;authenticité des clés. Si quelqu&#8217;un +décide de publier une clé en mon nom, et en utilisant mon adresse email, +cela lui est assez&nbsp;facile.</p> +<p>Il est donc nécessaire d&#8217;avoir des moyens de prouver que la clé publique +que j&#8217;utilise est réellement la&nbsp;mienne.</p> +<p>Traditionnellement, il est nécessaire de faire signer ma clé publique +par d&#8217;autres personnes, via une rencontre en personne ou des échanges +hors du réseau. C&#8217;est par exemple ce qui est réalisé lors des <a href="https://fr.wikipedia.org/wiki/Key_signing_party">Key +Signing parties</a>.</p> +<p>Une manière simple d&#8217;effectuer ces vérifications serait, en plus de +donner son adresse email, sa signature de clé, ou a minima de donner un +mot clé pour valider que les échanges proviennent bien de la bonne&nbsp;personne.</p> +<p><span class="caps">PGP</span> propose un mécanisme de signature des clés d&#8217;autrui, une fois celles +ci validées, ce qui permet de placer sa confiance dans les signataires +de la&nbsp;clé.</p> +<p><a href="https://keybase.io">Keybase.io</a> est un service qui vise à rendre la +création de ces preuves plus facile, en partant du principe qu&#8217;il est +possible d&#8217;utiliser différents moyens afin de prouver l&#8217;identité des +personnes. Par exemple, leurs comptes Twitter, GitHub ou leurs noms de +domaines. De la même manière qu&#8217;il est possible de signer (valider) les +clés de nos amis, il est possible de les &#8220;tracker&#8221; selon le jargon de&nbsp;keybase.</p> +<p>Donc, en somme, <em>Keybase.io</em> est un annuaire, qui tente de rendre plus +facile la création de preuves.&nbsp;Bien.</p> +<h2 id="quelques-points-dombre">Quelques points&nbsp;d&#8217;ombre</h2> +<p>Il s&#8217;agit d&#8217;une <em>startup</em> américaine, domiciliée dans le Delaware, qui +se trouve être un des paradis fiscaux qui <a href="https://fr.wikipedia.org/wiki/Delaware">est connu pour être un +paradis fiscal au coeur même des +États-Unis</a>. Je ne veux pas +faire de raccourcis trop rapides, bien évidemment, alors <a href="https://github.com/keybase/keybase-issues/issues/1569">j&#8217;ai ouvert un +ticket sur GitHub pour en savoir +plus</a> (après +tout, le fait d&#8217;être un paradis fiscal permet peut-être d&#8217;échapper à +certaines lois sur la requêtes de données). D&#8217;autant plus étonnant, la +startup n&#8217;a pour l&#8217;instant <a href="https://github.com/keybase/keybase-issues/issues/788">pas de <em>business +model</em></a> (ce qui en +un sens est assez rassurant, même si on peut se poser la question de +pourquoi faire une startup dans ces cas&nbsp;là).</p> +<p>Le service (bien qu&#8217;en Alpha), n&#8217;est pas mis à disposition sous licence +libre, ce qui pour l&#8217;instant empêche quiconque de créer son propre +serveur Keybase. <a href="https://github.com/keybase/">Une partie des composants, cependant, le sont (open +source)</a>.</p> +<p>J&#8217;ai du mal à croire en des initiatives qui veulent sauver le monde, +mais dans leur coin, je ne comprends pas pourquoi il n&#8217;y à pas de +documentation sur comment monter son propre serveur, ou comment les +aider à travailler sur la fédération. Mais bon, c&#8217;est pour l&#8217;instant une +initiative encore fraîche, et je lui laisse le bénéfice du&nbsp;doute.</p> +<p>Sur le long terme, une infrastructure comme <em>Keybase.io</em>, devra +évidemment être +<a href="https://github.com/keybase/keybase-issues/issues/162">distribuée</a>.</p> +<blockquote> +<p>We&#8217;ve been talking about a total decentralization, but we have to +solve a couple things, synchronization in particular. Right now +someone can mirror us and a client can trust a mirror just as easily +as the server at keybase.io, but there needs to be a way of announcing +proofs to any server and having them cooperate with each other. We&#8217;d +be so happy to get this&nbsp;right.</p> +<p>&#8212; <a href="http://chris.beams.io/posts/keybase/">Chris Coyne, co-founder of&nbsp;Keybase</a></p> +</blockquote> +<p>Afin de se &#8220;passer&#8221; de leur service centralisé, les preuves générées +(qui sont la force du système qu&#8217;ils mettent en place) pourraient être +exportées sur des serveurs de clés existants. C&#8217;est quelque chose +<a href="https://github.com/keybase/keybase-issues/issues/890">qu&#8217;ils souhaitent réaliser +.</a>.</p> +<p>Bref, une initiative quand même importante et utile, même si elle +soulève des questions qui méritent qu&#8217;on s&#8217;y attarde un&nbsp;brin.</p> +<p>Par ailleurs, <a href="https://leap.se/nicknym">d&#8217;autres projets qui visent des objectifs +similaires</a> existent, via le projet <span class="caps">LEAP</span>, mais +je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html +<ul> +<li>headline<br> + Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de + mémoriser des phrases de passes complexes. Comment s&#8217;en sortir&nbsp;?</li> +</ul> +<blockquote> +<p>Au contraire des autres mots de passe, les mots de passe +cryptographiques ont specifiquement besoin d&#8217;être longs et extremement +difficiles à deviner. La raison est qu&#8217;un …</p></blockquote> +<ul> +<li>headline<br> + Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de + mémoriser des phrases de passes complexes. Comment s&#8217;en sortir&nbsp;?</li> +</ul> +<blockquote> +<p>Au contraire des autres mots de passe, les mots de passe +cryptographiques ont specifiquement besoin d&#8217;être longs et extremement +difficiles à deviner. La raison est qu&#8217;un ordinateur (ou un cluster de +plusieurs ordinateurs) peut être programmé pour faire des trillions +d&#8217;essais de manière automatique. Si le mot de passe choisi est trop +faible ou construit d&#8217;une manière trop prédictible, cette attaque par +la force pourrait se revéler fructueuse en essayant toutes les&nbsp;possibilités.</p> +<p>&#8212; <a href="https://www.eff.org/wp/defending-privacy-us-border-guide-travelers-carrying-digital-devices">The Electronic Frontier +Foundation</a> +(traduction de mon&nbsp;fait)</p> +</blockquote> +<p>Comprendre les concepts et l&#8217;écosystème qui permettent d&#8217;avoir une vie +numérique chiffrée n&#8217;est pas quelque chose d&#8217;aisé. +<a href="https://emailselfdefense.fsf.org/fr/">Plusieurs</a> +<a href="http://www.controle-tes-donnees.net/outils/GnuPG.html">guides</a> ont été +écrits à ce propos, et pour autant je me rends compte que naïvement il +est possible de mal utiliser les outils&nbsp;existants.</p> +<blockquote> +<p>Utilisez un <em>bon</em> mot de passe pour votre session utilisateur et une +<em>bonne</em> phrase de passe pour proteger votre clé privée. Cette phrase +de passe est la partie la plus fragile de tout le&nbsp;système.</p> +<p>&#8212; La page de manuel de <span class="caps">GPG</span>.</p> +</blockquote> +<p>Une phrase de passe&nbsp;devrait:</p> +<ul> +<li>Être suffisamment longue pour être difficile à&nbsp;deviner;</li> +<li>Ne pas être une citation connue (littérature, livres sacrés&nbsp;etc);</li> +<li>Difficile à deviner même pour vos&nbsp;proches;</li> +<li>Facile à se souvenir et à&nbsp;taper;</li> +<li>être unique et non partagée entre différents sites / applications&nbsp;etc.</li> +</ul> +<p>Une des techniques consiste à utiliser des mots du dictionnaire, +sélectionnés de manière aléatoire, puis&nbsp;modifiés.</p> +<p><img alt="Trough 20 years of effort, we've succesfully trained everyone to use passwords that are hard for humans to remember, but easy for computers to guess" src="https://imgs.xkcd.com/comics/password_strength.png"></p> +<p>Micah Lee <a href="https://github.com/micahflee/passphrases">travaille également sur un +outil</a> qui vise à rendre la +mémorisation des phrases de passe plus aisée, de par leur répétition +avec des pauses de plus en plus&nbsp;longues.</p> +<p>Oui, ce n&#8217;est pas aussi simple que ce qu&#8217;il y parait. Pour ma part, j&#8217;ai +une copie en local de mes clés, dans un fichier chiffré avec une autre +clé que j&#8217;ai généré pour l&#8217;occasion et que je ne partagerait pas. J&#8217;ai +par ailleurs <a href="https://github.com/jamessan/vim-gnupg">configuré</a> mon +éditeur de texte pour pouvoir chiffrer les documents textes par&nbsp;défaut.</p> +<p>J&#8217;ai donc regénéré une nouvelle fois mes clés de travail et +personnelles, en utilisant des phrases de passe plus&nbsp;complexes.</p> +<p>Reste encore la question de la sauvegarde de ces clés privées de manière +chiffrée, que je n&#8217;ai pas encore résolue. Bref, tout cela me semble bien +compliqué pour réussir à l&#8217;expliquer à des novices, qui pour certains ne +sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Service de nuages : La gestion des permissions2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00tag:blog.notmyidea.org,2015-05-01:/service-de-nuages-la-gestion-des-permissions-fr.html<p class="first last">Démystification du vocabulaire des permissions et proposition d&#8217;implémentation pour&nbsp;Kinto</p> +<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> +<p>Dans le cadre de la création d&#8217;un service de stockage de données personnelles +(Kinto), la gestion des permissions est un des gros challenges : qui doit avoir +accès à quoi, et comment le définir&nbsp;?</p> +<p><strong>tl;dr: Quelques retours sur le vocabulaire des systèmes de permission et sur nos idées pour l&#8217;implementation des permissions dans un stockage&nbsp;générique.</strong></p> +<div class="section" id="la-problematique"> +<h2>La&nbsp;problématique</h2> +<p>La problématique est simple : des données sont stockées en ligne, et il +faut un moyen de pouvoir les partager avec d&#8217;autres&nbsp;personnes.</p> +<p>En regardant les cas d&#8217;utilisations, on se rend compte qu&#8217;on a plusieurs types +d&#8217;utilisateurs&nbsp;:</p> +<ul class="simple"> +<li>les utilisateurs &#8220;finaux&#8221; (vous)&nbsp;;</li> +<li>les applications qui interagissent en leurs&nbsp;noms.</li> +</ul> +<p>Tous les intervenants n&#8217;ont donc pas les mêmes droits : certains doivent +pouvoir lire, d&#8217;autres écrire, d&#8217;autres encore créer de nouveaux +enregistrements, et le contrôle doit pouvoir s&#8217;effectuer de manière fine : il +doit être possible de lire un enregistrement mais pas un autre, par&nbsp;exemple.</p> +<p>Nous sommes partis du constat que les solutions disponibles n&#8217;apportaient pas +une réponse satisfaisante à ces&nbsp;besoins.</p> +</div> +<div class="section" id="un-probleme-de-vocabulaire"> +<h2>Un problème de&nbsp;vocabulaire</h2> +<p>Le principal problème rencontré lors des réflexions fût le&nbsp;vocabulaire.</p> +<p>Voici ci-dessous une explication des différents&nbsp;termes.</p> +<div class="section" id="le-concept-de-principal"> +<h3>Le concept de « principal&nbsp;»</h3> +<p>Un <em>principal</em>, en sécurité informatique, est une entité qui peut être +authentifiée par un système informatique. <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a> En Français il s&#8217;agit +du « commettant », l&#8217;acteur qui commet l&#8217;action (oui, le terme est conceptuel&nbsp;!)</p> +<p>Il peut s&#8217;agir aussi bien d&#8217;un individu, d&#8217;un ordinateur, d&#8217;un +service ou d&#8217;un groupe regroupant l&#8217;une de ces entités, ce qui +est plus large que le classique « <em>user id</em>&nbsp;».</p> +<p>Les permissions sont alors associées à ces <em>principals</em>.</p> +<p>Par exemple, un utilisateur est identifié de manière unique lors de la +connexion par le système d&#8217;authentification dont le rôle est de +définir une liste de <em>principals</em> pour l&#8217;utilisateur se&nbsp;connectant.</p> +<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>Pour en savoir plus sur les <em>principals</em> : +<a class="reference external" href="https://en.wikipedia.org/wiki/Principal_%28computer_security%29">https://en.wikipedia.org/wiki/Principal_%28computer_security%29</a></td></tr> +</tbody> +</table> +</div> +<div class="section" id="la-difference-entre-role-et-groupe"> +<h3>La différence entre rôle et&nbsp;groupe</h3> +<p>De but en blanc, il n&#8217;est pas évident de définir précisément la +différence entre ces deux concepts qui permettent d&#8217;associer +des permissions à un groupe de <em>principals</em>. <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a></p> +<p>La différence est principalement sémantique. Mais on peut y voir une +différence dans la « direction » de la relation entre les deux&nbsp;concepts.</p> +<ul class="simple"> +<li>Un rôle est une liste de permissions que l&#8217;on associe à un <em>principal</em>.</li> +<li>Un groupe est une liste de <em>principals</em> que l&#8217;on peut associer à une&nbsp;permission.</li> +</ul> +<table class="docutils footnote" frame="void" id="footnote-2" rules="none"> +<colgroup><col class="label" /><col /></colgroup> +<tbody valign="top"> +<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td>Plus d&#8217;informations : +<a class="reference external" href="http://stackoverflow.com/questions/7770728/group-vs-role-any-real-difference">http://stackoverflow.com/questions/7770728/group-vs-role-any-real-difference</a></td></tr> +</tbody> +</table> +</div> +<div class="section" id="la-difference-entre-permission-acl-ace"> +<h3>La différence entre permission, <span class="caps">ACL</span>, <span class="caps">ACE</span></h3> +<blockquote class="epigraph"> +<p>Une <span class="caps">ACL</span> est une liste d’Access Control Entry (<span class="caps">ACE</span>) ou entrée de contrôle d&#8217;accès +donnant ou supprimant des droits d&#8217;accès à une personne ou un&nbsp;groupe.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://fr.wikipedia.org/wiki/Access_Control_List">https://fr.wikipedia.org/wiki/Access_Control_List</a></p> +</blockquote> +<p>Je dirais même plus, dans notre cas, « à un <em>principal</em> ». Par&nbsp;exemple:</p> +<div class="highlight"><pre><span></span>create_record: alexis,remy,tarek +</pre></div> +<p>Cet <span class="caps">ACE</span> donne la permission <tt class="docutils literal">create</tt> sur l&#8217;objet <tt class="docutils literal">record</tt> aux +utilisateurs Tarek, Rémy et&nbsp;Alexis.</p> +</div> +</div> +<div class="section" id="la-delegation-de-permissions"> +<h2>La délégation de&nbsp;permissions</h2> +<p>Imaginez l&#8217;exemple suivant, où un utilisateur stocke deux types de données en +ligne&nbsp;:</p> +<ul class="simple"> +<li>des contacts&nbsp;;</li> +<li>une liste de tâches à faire qu&#8217;il peut associer à ses&nbsp;contacts.</li> +</ul> +<p>L&#8217;utilisateur a tous les droits sur ses&nbsp;données.</p> +<p>Cependant il utilise deux applications qui doivent elles avoir un accès restreint&nbsp;:</p> +<ul class="simple"> +<li>une application de gestion des contacts à qui il souhaite déléguer +la gestion intégrale de ses contacts : <tt class="docutils literal">contacts:write</tt> ;</li> +<li>une application de gestion des tâches à qui il souhaite déléguer la +gestion des tâches : <tt class="docutils literal">contacts:read tasks:write</tt></li> +</ul> +<p>Il souhaite que son application de contacts ne puisse pas accéder à +ses tâches et que son application de tâches ne puisse pas modifier ses +contacts existants, juste éventuellement en créer de&nbsp;nouveaux.</p> +<p>Il lui faut donc un moyen de déléguer certains de ses droits à un tiers&nbsp;(l&#8217;application).</p> +<p>C&#8217;est précisément le rôle des <a class="reference external" href="http://tools.ietf.org/html/rfc6749#page-23">scopes OAuth2</a>.</p> +<p>Lors de la connexion d&#8217;un utilisateur, une fenêtre lui demande quels +accès il veut donner à l&#8217;application qui va agir en son&nbsp;nom.</p> +<p>Le service aura ensuite accès à ces <em>scopes</em> en regardant le jeton +d&#8217;authentification utilisé. Cette information doit être +considérée comme une entrée utilisateur (c&#8217;est à dire qu&#8217;on ne peut +pas lui faire confiance). Il s&#8217;agit de ce que l&#8217;utilisateur&nbsp;souhaite.</p> +<p>Or, il est également possible que l&#8217;utilisateur n&#8217;ait pas accès aux données +qu&#8217;il demande. Le service doit donc utiliser deux niveaux de permissions : +celles de l&#8217;utilisateur, et celles qui ont été déléguées à&nbsp;l&#8217;application.</p> +</div> +<div class="section" id="espace-de-noms"> +<h2>Espace de&nbsp;noms</h2> +<p>Dans notre implémentation initiale de <em>Kinto</em> (notre service de stockage en +construction), l&#8217;espace de nom était implicite : les données stockées étaient +nécessairement celles de l&#8217;utilisateur&nbsp;connecté.</p> +<p>Les données d&#8217;un utilisateur étaient donc cloisonnées et impossible à&nbsp;partager.</p> +<p>L&#8217;utilisation d&#8217;espaces de noms est une manière simple de gérer le partage des&nbsp;données.</p> +<p>Nous avons choisi de reprendre le modèle de GitHub et de Bitbucket, qui +utilisent les « organisations » comme espaces de&nbsp;noms.</p> +<p>Dans notre cas, il est possible de créer des &#8220;buckets&#8221;, qui correspondent à ces +espaces de noms. Un bucket est un conteneur de collections et de groupes&nbsp;utilisateurs.</p> +<p>Les ACLs sur ces collections peuvent être attribuées à certains groupes du +<em>bucket</em> ainsi qu&#8217;à d&#8217;autres <em>principals</em>&nbsp;directement.</p> +</div> +<div class="section" id="notre-proposition-d-api"> +<h2>Notre proposition d&#8217;<span class="caps">API</span></h2> +<div class="section" id="les-objets-manipules"> +<h3>Les objets&nbsp;manipulés</h3> +<p>Pour mettre en place la gestion des permissions, nous avons identifié les +objets suivants&nbsp;:</p> +<table border="1" class="docutils"> +<colgroup> +<col width="23%" /> +<col width="77%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Objet</th> +<th class="head">Description</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td><strong>bucket</strong></td> +<td>On peut les voir comme des espaces de noms. Ils +permettent d&#8217;avoir différentes collections portant +le même nom mais stockées dans différents <em>buckets</em> de +manière à ce que les données soient distinctes.</td> +</tr> +<tr><td><strong>collection</strong></td> +<td>Une liste d&#8217;enregistrements.</td> +</tr> +<tr><td><strong>record</strong></td> +<td>Un enregistrement d&#8217;une collection.</td> +</tr> +<tr><td><strong>group</strong></td> +<td>Un groupe de commetants (« <em>principals</em> »).</td> +</tr> +</tbody> +</table> +<p>Pour la définition des ACLs, il y a une hiérarchie et les objets « héritent » des +ACLs de leur parents&nbsp;:</p> +<div class="highlight"><pre><span></span> +---------------+ + | Bucket | + +---------------+ + +-----&gt;+ - id +&lt;---+ + | | - permissions | | + | +---------------+ | + | | + | | + | | + | | + | | ++---+-----------+ +------+---------+ +| Collection | | Group | ++---------------+ +----------------+ +| - id | | - id | +| - permissions | | - members | ++------+--------+ | - permissions | + ^ +----------------+ + | + | ++------+---------+ +| Record | ++----------------+ +| - id | +| - data | +| - permissions | ++----------------+ +</pre></div> +</div> +<div class="section" id="les-permissions"> +<h3>Les&nbsp;permissions</h3> +<p>Pour chacun de ces objets nous avons identifié les permissions suivantes&nbsp;:</p> +<table border="1" class="docutils"> +<colgroup> +<col width="23%" /> +<col width="77%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Permission</th> +<th class="head">Description</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td><strong>read</strong></td> +<td>La permission de lire le contenu de +l&#8217;objet et de ses sous-objets.</td> +</tr> +<tr><td><strong>write</strong></td> +<td>La permission de modifier et +d&#8217;administrer un objet et ses sous- +objets. La permission <em>write</em> permet la +lecture, modification et suppression +d&#8217;un objet ainsi que la gestion de ses +permissions.</td> +</tr> +<tr><td><strong>create</strong></td> +<td>La permission de créer le sous-objet +spécifié. Par exemple: +<tt class="docutils literal">collections:create</tt></td> +</tr> +</tbody> +</table> +<p>À chaque permission spécifiée sur un objet est associée une liste de +<em>principals</em>.</p> +<p>Dans le cas de la permission <tt class="docutils literal">create</tt> on est obligé de spécifier +l&#8217;objet enfant en question car un objet peut avoir plusieurs types +d&#8217;enfants. Par exemple : <tt class="docutils literal">collections:create</tt>, <tt class="docutils literal">groups:create</tt>.</p> +<p>Nous n&#8217;avons pour l&#8217;instant pas de permission pour <cite>delete</cite> et <cite>update</cite>, +puisque nous n&#8217;avons pas trouvé de cas d&#8217;utilisation qui les nécessitent. +Quiconque avec le droit d&#8217;écriture peut donc supprimer un&nbsp;enregistrement.</p> +<p>Les permissions d&#8217;un objet sont héritées de son parent. Par exemple, +un enregistrement créé dans une collection accessible à tout le monde +en lecture sera lui aussi accessible à tout le&nbsp;monde.</p> +<p>Par conséquent, les permissions sont cumulées. Autrement dit, il n&#8217;est pas +possible qu&#8217;un objet ait des permissions plus restrictives que son&nbsp;parent.</p> +<p>Voici la liste exhaustive des permissions&nbsp;:</p> +<table border="1" class="docutils"> +<colgroup> +<col width="21%" /> +<col width="32%" /> +<col width="47%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Objet</th> +<th class="head">Permissions associées</th> +<th class="head">Commentaire</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td>Configuration +(.ini)</td> +<td><cite>buckets:create</cite></td> +<td>Les <em>principals</em> ayant le droit +de créer un bucket sont définis +dans la configuration du serveur. +(<em>ex. utilisateurs authentifiés</em>)</td> +</tr> +<tr><td rowspan="4"><tt class="docutils literal">bucket</tt></td> +<td><cite>write</cite></td> +<td>C&#8217;est en quelque sorte le droit +d&#8217;administration du <em>bucket</em>.</td> +</tr> +<tr><td><cite>read</cite></td> +<td>C&#8217;est le droit de lire le contenu +de tous les objets du <em>bucket</em>.</td> +</tr> +<tr><td><cite>collections:create</cite></td> +<td>Permission de créer des +collections dans le <em>bucket</em>.</td> +</tr> +<tr><td><cite>groups:create</cite></td> +<td>Permission de créer des groupes +dans le <em>bucket</em>.</td> +</tr> +<tr><td rowspan="3"><tt class="docutils literal">collection</tt></td> +<td><cite>write</cite></td> +<td>Permission d&#8217;administrer tous les +objets de la collection.</td> +</tr> +<tr><td><cite>read</cite></td> +<td>Permission de consulter tous les +objets de la collection.</td> +</tr> +<tr><td><cite>records:create</cite></td> +<td>Permission de créer des nouveaux +enregistrement dans la collection.</td> +</tr> +<tr><td rowspan="2"><tt class="docutils literal">record</tt></td> +<td><cite>write</cite></td> +<td>Permission de modifier ou de +partager l&#8217;enregistrement.</td> +</tr> +<tr><td><cite>read</cite></td> +<td>Permission de consulter +l&#8217;enregistrement.</td> +</tr> +<tr><td rowspan="2"><tt class="docutils literal">group</tt></td> +<td><cite>write</cite></td> +<td>Permission d&#8217;administrer le +groupe</td> +</tr> +<tr><td><cite>read</cite></td> +<td>Permission de consulter les +membres du groupe.</td> +</tr> +</tbody> +</table> +</div> +<div class="section" id="les-principals"> +<h3>Les « <em>principals</em>&nbsp;»</h3> +<p>Les acteurs se connectant au service de stockage peuvent&nbsp;s&#8217;authentifier.</p> +<p>Ils reçoivent alors une liste de <em>principals</em>&nbsp;:</p> +<ul class="simple"> +<li><tt class="docutils literal">Everyone</tt>: le <em>principal</em> donné à tous les acteurs (authentifiés ou pas)&nbsp;;</li> +<li><tt class="docutils literal">Authenticated</tt>: le <em>principal</em> donné à tous les acteurs authentifiés&nbsp;;</li> +<li>un <em>principal</em> identifiant l&#8217;acteur, par exemple <tt class="docutils literal">fxa:32aa95a474c984d41d395e2d0b614aa2</tt></li> +</ul> +<p>Afin d&#8217;éviter les collisions d&#8217;identifiants, le <em>principal</em> de l&#8217;acteur dépend +de son type d&#8217;authentification (<tt class="docutils literal">system</tt>, <tt class="docutils literal">basic</tt>, <tt class="docutils literal">ipaddr</tt>, <tt class="docutils literal">hawk</tt>, +<tt class="docutils literal">fxa</tt>) et de son identifiant (unique par&nbsp;acteur).</p> +<p>En fonction du <em>bucket</em> sur lequel se passe l&#8217;action, les groupes dont +fait partie l&#8217;utilisateur sont également ajoutés à sa liste de +<tt class="docutils literal">principals</tt>. <tt class="docutils literal">group:moderators</tt> par&nbsp;exemple.</p> +<p>Ainsi, si Bob se connecte avec <em>Firefox Accounts</em> sur le <em>bucket</em> +<tt class="docutils literal">servicedenuages_blog</tt> dans lequel il fait partie du groupe +<tt class="docutils literal">moderators</tt>, il aura la liste de <em>principals</em> suivante : +<tt class="docutils literal">Everyone, Authenticated, fxa:32aa95a474c984d41d395e2d0b614aa2, group:moderators</tt></p> +<p>Il est donc possible d&#8217;assigner une permission à Bob en utilisant l&#8217;un de +ces quatre <em>principals</em>.</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Le <em>principal</em> <tt class="docutils literal">&lt;userid&gt;</tt> dépend du <em>back-end</em> d&#8217;authentification (e.g. +<tt class="docutils literal">github:leplatrem</tt>).</p> +</div> +</div> +<div class="section" id="quelques-exemples"> +<h3>Quelques&nbsp;exemples</h3> +<p><strong>Blog</strong></p> +<table border="1" class="docutils"> +<colgroup> +<col width="35%" /> +<col width="18%" /> +<col width="46%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Objet</th> +<th class="head">Permissions</th> +<th class="head">Principals</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td><tt class="docutils literal">bucket:blog</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;blog</span> owner id&gt;</tt></td> +</tr> +<tr><td rowspan="2"><tt class="docutils literal">collection:articles</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal">group:moderators</tt></td> +</tr> +<tr><td><tt class="docutils literal">read</tt></td> +<td><tt class="docutils literal">Everyone</tt></td> +</tr> +<tr><td><tt class="docutils literal">record:569e28r98889</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;co-author</span> id&gt;</tt></td> +</tr> +</tbody> +</table> +<p><strong>Wiki</strong></p> +<table border="1" class="docutils"> +<colgroup> +<col width="35%" /> +<col width="18%" /> +<col width="46%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Object</th> +<th class="head">Permissions</th> +<th class="head">Principals</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td><tt class="docutils literal">bucket:wiki</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;wiki</span> administrator id&gt;</tt></td> +</tr> +<tr><td rowspan="2"><tt class="docutils literal">collection:articles</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal">Authenticated</tt></td> +</tr> +<tr><td><tt class="docutils literal">read</tt></td> +<td><tt class="docutils literal">Everyone</tt></td> +</tr> +</tbody> +</table> +<p><strong>Sondages</strong></p> +<table border="1" class="docutils"> +<colgroup> +<col width="34%" /> +<col width="31%" /> +<col width="35%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Objet</th> +<th class="head">Permissions</th> +<th class="head">Principals</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td rowspan="2"><tt class="docutils literal">bucket:poll</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;admin</span> id&gt;</tt></td> +</tr> +<tr><td><tt class="docutils literal">collection:create</tt></td> +<td><tt class="docutils literal">Authenticated</tt></td> +</tr> +<tr><td rowspan="2"><tt class="docutils literal"><span class="pre">collection:&lt;poll</span> id&gt;</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;poll</span> author id&gt;</tt></td> +</tr> +<tr><td><tt class="docutils literal">record:create</tt></td> +<td><tt class="docutils literal">Everyone</tt></td> +</tr> +</tbody> +</table> +<p><strong>Cartes&nbsp;colaboratives</strong></p> +<table border="1" class="docutils"> +<colgroup> +<col width="34%" /> +<col width="31%" /> +<col width="35%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Objet</th> +<th class="head">Permissions</th> +<th class="head">Principals</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td rowspan="2"><tt class="docutils literal">bucket:maps</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;admin</span> id&gt;</tt></td> +</tr> +<tr><td><tt class="docutils literal">collection:create</tt></td> +<td><tt class="docutils literal">Authenticated</tt></td> +</tr> +<tr><td rowspan="2"><tt class="docutils literal"><span class="pre">collection:&lt;map</span> id&gt;</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;map</span> author id&gt;</tt></td> +</tr> +<tr><td><tt class="docutils literal">read</tt></td> +<td><tt class="docutils literal">Everyone</tt></td> +</tr> +<tr><td><tt class="docutils literal"><span class="pre">record:&lt;record</span> id&gt;</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;maintainer</span> id&gt;</tt> +(<em>ex. event staff member +maintaining venues</em>)</td> +</tr> +</tbody> +</table> +<p><strong>Plateformes</strong></p> +<p>Bien sûr, il y a plusieurs façons de modéliser les cas d&#8217;utilisation typiques. +Par exemple, on peut imaginer une plateforme de wikis (à la wikia.com), où les +wikis sont privés par défaut et certaines pages peuvent être rendues publiques&nbsp;:</p> +<table border="1" class="docutils"> +<colgroup> +<col width="32%" /> +<col width="30%" /> +<col width="38%" /> +</colgroup> +<thead valign="bottom"> +<tr><th class="head">Objet</th> +<th class="head">Permissions</th> +<th class="head">Principals</th> +</tr> +</thead> +<tbody valign="top"> +<tr><td rowspan="3"><tt class="docutils literal">bucket:freewiki</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;administrator</span> id&gt;</tt></td> +</tr> +<tr><td><tt class="docutils literal">collection:create</tt></td> +<td><tt class="docutils literal">Authenticated</tt></td> +</tr> +<tr><td><tt class="docutils literal">group:create</tt></td> +<td><tt class="docutils literal">Authenticated</tt></td> +</tr> +<tr><td rowspan="2"><tt class="docutils literal"><span class="pre">collection:&lt;wiki</span> id&gt;</tt></td> +<td><tt class="docutils literal">write</tt></td> +<td><tt class="docutils literal"><span class="pre">fxa:&lt;wiki</span> owner id&gt;</tt>, +<tt class="docutils literal"><span class="pre">group:&lt;editors</span> id&gt;</tt></td> +</tr> +<tr><td><tt class="docutils literal">read</tt></td> +<td><tt class="docutils literal"><span class="pre">group:&lt;readers</span> id&gt;</tt></td> +</tr> +<tr><td><tt class="docutils literal"><span class="pre">record:&lt;page</span> id&gt;</tt></td> +<td><tt class="docutils literal">read</tt></td> +<td><tt class="docutils literal">Everyone</tt></td> +</tr> +</tbody> +</table> +</div> +<div class="section" id="l-api-http"> +<h3>L&#8217;<span class="caps">API</span> <span class="caps">HTTP</span></h3> +<p>Lors de la création d&#8217;un objet, l&#8217;utilisateur se voit +attribué la permission <tt class="docutils literal">write</tt> sur l&#8217;objet&nbsp;:</p> +<div class="highlight"><pre><span></span><span class="nf">PUT</span> <span class="nn">/v1/buckets/servicedenuages_blog</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> +<span class="na">Authorization</span><span class="o">:</span> <span class="l">Bearer 0b9c2625dc21ef05f6ad4ddf47c5f203837aa32ca42fced54c2625dc21efac32</span> +<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json</span> + +HTTP/1.1 201 Created +Content-Type: application/json; charset=utf-8 + +{ + &quot;id&quot;: &quot;servicedenuages_blog&quot;, + &quot;permissions&quot;: { + &quot;write&quot;: [&quot;fxa:49d02d55ad10973b7b9d0dc9eba7fdf0&quot;] + } +} +</pre></div> +<p>Il est possible d&#8217;ajouter des permissions à l&#8217;aide de <tt class="docutils literal"><span class="caps">PATCH</span></tt> :</p> +<div class="highlight"><pre><span></span><span class="nf">PATCH</span> <span class="nn">/v1/buckets/servicedenuages_blog/collections/articles</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> +<span class="na">Authorization</span><span class="o">:</span> <span class="l">Bearer 0b9c2625dc21ef05f6ad4ddf47c5f203837aa32ca42fced54c2625dc21efac32</span> +<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json</span> + +{ + &quot;permissions&quot;: { + &quot;read&quot;: [&quot;+system.Everyone&quot;] + } +} + +HTTP/1.1 201 Created +Content-Type: application/json; charset=utf-8 + +{ + &quot;id&quot;: &quot;servicedenuages_blog&quot;, + &quot;permissions&quot;: { + &quot;write&quot;: [&quot;fxa:49d02d55ad10973b7b9d0dc9eba7fdf0&quot;], + &quot;read&quot;: [&quot;system.Everyone&quot;] + } +} +</pre></div> +<p>Pour le <tt class="docutils literal"><span class="caps">PATCH</span></tt> nous utilisons la syntaxe préfixée par un <tt class="docutils literal">+</tt> ou +par un <tt class="docutils literal">-</tt> pour ajouter ou enlever des <em>principals</em> sur un <span class="caps">ACL</span>.</p> +<p>Il est également possible de faire un <tt class="docutils literal"><span class="caps">PUT</span></tt> pour réinitialiser les ACLs, +sachant que le <tt class="docutils literal"><span class="caps">PUT</span></tt> va ajouter l&#8217;utilisateur courant à la +liste automatiquement mais qu&#8217;il pourra se retirer avec un <tt class="docutils literal"><span class="caps">PATCH</span></tt>. +Ajouter l&#8217;utilisateur courant permet d&#8217;éviter les situations où plus +personne n&#8217;a accès aux&nbsp;données.</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">La permission <tt class="docutils literal">create</tt> est valable pour <tt class="docutils literal"><span class="caps">POST</span></tt> mais aussi pour <tt class="docutils literal"><span class="caps">PUT</span></tt> +lorsque l&#8217;enregistrement n&#8217;existe&nbsp;pas.</p> +</div> +</div> +<div class="section" id="le-cas-specifique-des-donnees-utilisateurs"> +<h3>Le cas spécifique des données&nbsp;utilisateurs</h3> +<p>Une des fonctionnalités actuelles de <em>Kinto</em> est de pouvoir gérer des +collections d&#8217;enregistrements par&nbsp;utilisateur.</p> +<p>Sous <em>*nix</em> il est possible, pour une +application, de sauvegarder la configuration de l&#8217;utilisateur courant +dans son dossier personnel sans se soucier de l&#8217;emplacement sur +le disque en utilisant <tt class="docutils literal">~/</tt>.</p> +<p>Dans notre cas si une application souhaite sauvegarder les contacts d&#8217;un +utilisateur, elle peut utiliser le raccourci <tt class="docutils literal">~</tt> pour faire référence au +<em>bucket</em> <strong>personnel</strong> de l&#8217;utilisateur : <tt class="docutils literal"><span class="pre">/buckets/~/collections/contacts</span></tt></p> +<p>Cette <span class="caps">URL</span> retournera le code <tt class="docutils literal"><span class="caps">HTTP</span> 307</tt> vers le <em>bucket</em> de l&#8217;utilisateur courant&nbsp;:</p> +<div class="highlight"><pre><span></span><span class="nf">POST</span> <span class="nn">/v1/buckets/~/collections/contacts/records</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> + +{ + &quot;name&quot;: &quot;Rémy&quot;, + &quot;emails&quot;: [&quot;remy@example.com&quot;], + &quot;phones&quot;: [&quot;+330820800800&quot;] +} + +HTTP/1.1 307 Temporary Redirect +Location: /v1/buckets/fxa:49d02d55ad10973b7b9d0dc9eba7fdf0/collections/contacts/records +</pre></div> +<p>Ainsi il est tout à fait possible à Alice de partager ses contacts +avec Bob. Il lui suffit pour cela de donner la permission <tt class="docutils literal">read</tt> à +Bob sur sa collection et de donner l&#8217;<span class="caps">URL</span> complète +<tt class="docutils literal">/v1/buckets/fxa:49d02d55ad10973b7b9d0dc9eba7fdf0/collections/contacts/records</tt> +à&nbsp;Bob.</p> +</div> +<div class="section" id="la-delegation-des-permissions"> +<h3>La délégation des&nbsp;permissions</h3> +<p>Dans le cas de <em>Kinto</em>, nous avons défini un format pour restreindre les +permissions via les scopes OAuth2: +<tt class="docutils literal"><span class="pre">storage:&lt;bucket_id&gt;:&lt;collection_id&gt;:&lt;permissions_list&gt;</span></tt>.</p> +<p>Ainsi, si on reprend l&#8217;exemple précédent de la liste de tâches, il est possible pour +Bob de créer un token OAuth spécifique avec les <em>scopes</em> suivants : +<tt class="docutils literal">profile storage:todolist:tasks:write <span class="pre">storage:~:contacts:read+records:create</span></tt></p> +<p>Donc, bien que Bob a la permission <tt class="docutils literal">write</tt> sur ses contacts, +l&#8217;application utilisant ce token pourra uniquement lire les contacts +existants et en ajouter de&nbsp;nouveaux.</p> +<p>Une partie de la complexité est donc de réussir à présenter ces <em>scopes</em> de +manière lisible à l&#8217;utilisateur, afin qu&#8217;il choisisse quelles permissions +donner aux applications qui agissent en son&nbsp;nom.</p> +<p>Voilà où nous en sommes de notre réflexion&nbsp;!</p> +<p>Si vous avez des choses à ajouter, des points de désaccord ou autres +réflexions, n&#8217;hésitez pas à nous interrompre pendant qu&#8217;il est encore temps&nbsp;!</p> +</div> +</div> +Eco-système et stockage générique2015-04-30T00:00:00+02:002015-04-30T00:00:00+02:00tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.html +<p><strong>tl;dr Nous devons construire un service de suivi de paiements, et nous +hésitons à continuer à nous entêter avec notre propre solution de&nbsp;stockage/synchronisation.</strong></p> +<p>Comme nous l&#8217;écrivions <a href="https://blog.notmyidea.org/service-de-nuages-fr.html">dans l&#8217;article +précédent</a>, nous +souhaitons construire une solution de stockage générique. On refait +<a href="http://daybed.readthedocs.org">Daybed</a> chez Mozilla&nbsp;!</p> +<p>Notre objectif est …</p> +<p><strong>tl;dr Nous devons construire un service de suivi de paiements, et nous +hésitons à continuer à nous entêter avec notre propre solution de&nbsp;stockage/synchronisation.</strong></p> +<p>Comme nous l&#8217;écrivions <a href="https://blog.notmyidea.org/service-de-nuages-fr.html">dans l&#8217;article +précédent</a>, nous +souhaitons construire une solution de stockage générique. On refait +<a href="http://daybed.readthedocs.org">Daybed</a> chez Mozilla&nbsp;!</p> +<p>Notre objectif est simple: permettre aux développeurs d&#8217;application, +internes à Mozilla ou du monde entier, de faire persister et +synchroniser facilement des données associées à un&nbsp;utilisateur.</p> +<div id="storage-specs"> + +Les aspects de l&#8217;architecture qui nous semblent incontournables: + +</div> + +<ul> +<li>La solution doit reposer sur un protocole, et non sur une + implémentation&nbsp;;</li> +<li>L&#8217;auto-hébergement de l&#8217;ensemble doit être simplissime&nbsp;;</li> +<li>L&#8217;authentification doit être <em>pluggable</em>, voire décentralisée + (OAuth2, FxA, Persona)&nbsp;;</li> +<li>Les enregistrements doivent pouvoir être validés par le serveur&nbsp;;</li> +<li>Les données doivent pouvoir être stockées dans n&#8217;importe quel + backend&nbsp;;</li> +<li>Un système de permissions doit permettre de protéger des + collections, ou de partager des enregistrements de manière fine&nbsp;;</li> +<li>La résolution de conflits doit pouvoir avoir lieu sur le serveur&nbsp;;</li> +<li>Le client doit être pensé «*offline-first*»&nbsp;;</li> +<li>Le client doit pouvoir réconcilier les données simplement&nbsp;;</li> +<li>Le client doit pouvoir être utilisé aussi bien dans le navigateur + que côté serveur&nbsp;;</li> +<li>Tous les composants se doivent d´être simples et substituables&nbsp;facilement.</li> +</ul> +<p>La première question qui nous a été posée fût «*Pourquoi vous +n&#8217;utilisez pas PouchDB ou Remote Storage&nbsp;?*»</p> +<h2 id="remote-storage">Remote&nbsp;Storage</h2> +<p>Remote Storage est un standard ouvert pour du stockage par utilisateur. +<a href="http://tools.ietf.org/html/draft-dejong-remotestorage-04">La +specification</a> +se base sur des standards déjà existants et éprouvés: Webfinger, OAuth +2, <span class="caps">CORS</span> et <span class="caps">REST</span>.</p> +<p>L&#8217;<span class="caps">API</span> est simple, des <a href="http://blog.cozycloud.cc/news/2014/08/12/when-unhosted-meets-cozy-cloud/">projets prestigieux +l&#8217;utilisent</a>. +Il y a plusieurs <a href="https://github.com/jcoglan/restore">implémentations</a> +du serveur, et il existe <a href="https://www.npmjs.com/package/remotestorage-server">un squelette +Node</a> pour +construire un serveur sur&nbsp;mesure.</p> +<p><img alt="Remote Storage widget" src="%7Bfilename%7D/images/remotestorage-widget.png"></p> +<p>Le client +<a href="https://github.com/remotestorage/remotestorage.js/">remoteStorage.js</a> +permet d&#8217;intégrer la solution dans les applications Web. Il se charge du +«store local», du cache, de la synchronization, et fournit un widget qui +permet aux utilisateurs des applications de choisir le serveur qui +recevra les données (via&nbsp;Webfinger).</p> +<p><a href="https://github.com/michielbdejong/ludbud">ludbud</a>, la version épurée de +<em>remoteStorage.js</em>, se limite à l&#8217;abstraction du stockage distant. Cela +permettrait à terme, d&#8217;avoir une seule bibliothèque pour stocker dans un +serveur <em>remoteStorage</em>, <em>ownCloud</em> ou chez les méchants comme <em>Google +Drive</em> ou <em>Dropbox</em>.</p> +<p>Au premier abord, la spécification correspond à ce que nous voulons&nbsp;accomplir:</p> +<ul> +<li>La philosophie du protocole est&nbsp;saine;</li> +<li>L&#8217;éco-système est bien&nbsp;fichu;</li> +<li>La vision politique colle: redonner le contrôle des données aux + utilisateurs (voir <a href="http://unhosted.org/">unhosted</a>);</li> +<li>Les choix techniques compatibles avec ce qu&#8217;on a commencé (<span class="caps">CORS</span>, + <span class="caps">REST</span>, OAuth&nbsp;2);</li> +</ul> +<p>En revanche, vis à vis de la manipulation des données, il y a plusieurs +différences avec ce que nous souhaitons&nbsp;faire:</p> +<ul> +<li>L&#8217;<span class="caps">API</span> suit globalement une métaphore «fichiers» (dossier/documents), + plutôt que «données» (collection/enregistrements)&nbsp;;</li> +<li>Il n&#8217;y a pas de validation des enregistrements selon un schéma (même + si <a href="https://remotestorage.io/doc/code/files/baseclient/types-js.html">certaines + implémentations</a> + du protocole le font)&nbsp;;</li> +<li>Il n&#8217;y a pas la possibilité de trier/filtrer les enregistrements + selon des attributs&nbsp;;</li> +<li>Les permissions <a href="https://groups.google.com/forum/#!topic/unhosted/5_NOGq8BPTo">se limitent à + privé/public</a> + (et <a href="https://github.com/remotestorage/spec/issues/58#issue-27249452">l&#8217;auteur envisage plutôt un modèle à la + Git</a>)[1]&nbsp;;</li> +</ul> +<p>En résumé, il semblerait que ce que nous souhaitons faire avec le +stockage d&#8217;enregistrements validés est complémentaire avec <em>Remote +Storage</em>.</p> +<p>Si des besoins de persistence orientés «fichiers» se présentent, a +priori nous aurions tort de réinventer les solutions apportées par cette +spécification. Il y a donc de grandes chances que nous l´intégrions à +terme, et que <em>Remote Storage</em> devienne une facette de notre&nbsp;solution.</p> +<h2 id="pouchdb">PouchDB</h2> +<p><a href="http://pouchdb.com/">PouchDB</a> est une bibliothèque JavaScript qui +permet de manipuler des enregistrements en local et de les synchroniser +vers une base&nbsp;distante.</p> +<div class="highlight"><pre><span></span><code><span class="n">javascript</span> +<span class="k">var</span><span class="w"> </span><span class="n">db</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new</span><span class="w"> </span><span class="n">PouchDB</span><span class="p">(</span><span class="s1">&#39;dbname&#39;</span><span class="p">);</span> + +<span class="n">db</span><span class="o">.</span><span class="n">put</span><span class="p">({</span> +<span class="w"> </span><span class="n">_id</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;dave@gmail.com&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="n">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;David&#39;</span><span class="p">,</span> +<span class="w"> </span><span class="n">age</span><span class="p">:</span><span class="w"> </span><span class="mi">68</span> +<span class="p">});</span> + +<span class="n">db</span><span class="o">.</span><span class="n">replicate</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="s1">&#39;http://example.com/mydb&#39;</span><span class="p">);</span> +</code></pre></div> + +<p>Le projet a le vent en poupe, bénéficie de nombreux contributeurs, +l&#8217;éco-système est très riche et l&#8217;adoption par des projets <a href="https://github.com/hoodiehq/wip-hoodie-store-on-pouchdb">comme +Hoodie</a> ne fait +que confirmer la pertinence de l&#8217;outil pour les développeurs&nbsp;frontend.</p> +<p><em>PouchDB</em> gère un « store » local, dont la persistence est abstraite et +<a href="http://pouchdb.com/2014/07/25/pouchdb-levels-up.html">repose sur</a> l&#8217;<span class="caps">API</span> +<a href="https://github.com/level/levelup#relationship-to-leveldown">LevelDown</a> +pour persister les données dans <a href="https://github.com/Level/levelup/wiki/Modules#storage-back-ends">n&#8217;importe quel +backend</a>.</p> +<p>Même si <em>PouchDB</em> adresse principalement les besoins des applications +«*offline-first*», il peut être utilisé aussi bien dans le navigateur +que côté serveur, via&nbsp;Node.</p> +<h3 id="synchronisation">Synchronisation</h3> +<p>La synchronisation (ou réplication) des données locales s&#8217;effectue sur +un <a href="http://couchdb.apache.org/">CouchDB</a>&nbsp;distant.</p> +<p>Le projet <a href="https://github.com/pouchdb/pouchdb-server">PouchDB Server</a> +implémente l&#8217;<span class="caps">API</span> de CouchDB en NodeJS. Comme <em>PouchDB</em> est utilisé, on +obtient un service qui se comporte comme un <em>CouchDB</em> mais qui stocke +ses données n&#8217;importe où, dans un <em>Redis</em> ou un <em>PostgreSQL</em> par&nbsp;exemple.</p> +<p>La synchronisation est complète. Autrement dit, tous les enregistrements +qui sont sur le serveur se retrouvent synchronisés dans le client. Il +est possible de filtrer les collections synchronisées, mais cela <a href="http://pouchdb.com/2015/04/05/filtered-replication.html">n&#8217;a +pas pour objectif de sécuriser l&#8217;accès aux +données</a>.</p> +<p>L&#8217;approche recommandée pour cloisonner les données par utilisateur +consiste à créer <a href="https://github.com/nolanlawson/pouchdb-authentication#some-people-can-read-some-docs-some-people-can-write-those-same-docs">une base de données par +utilisateur</a>.</p> +<p>Ce n&#8217;est pas forcément un problème, CouchDB <a href="https://mail-archives.apache.org/mod_mbox/couchdb-user/201401.mbox/%3C52CEB873.7080404@ironicdesign.com%3E">supporte des centaines de +milliers de bases sans +sourciller</a>. +Mais selon les cas d&#8217;utilisation, le cloisement n&#8217;est pas toujours +facile à déterminer (par rôle, par application, par collection,&nbsp;&#8230;).</p> +<h2 id="le-cas-dutilisation-payments">Le cas d&#8217;utilisation « Payments&nbsp;»</h2> +<p><img alt="Put Payments Here -- Before the Internet - CC-NC-SA Katy Silberger +https://www.flickr.com/photos/katysilbs/11163812186" src="%7Bfilename%7D/images/put-payments.jpg"></p> +<p>Dans les prochaines semaines, nous devrons mettre sur pied un prototype +pour tracer l&#8217;historique des paiements et abonnements d&#8217;un&nbsp;utilisateur.</p> +<p>Le besoin est&nbsp;simple:</p> +<ul> +<li>l&#8217;application « Payment » enregistre les paiements et abonnements + d&#8217;un utilisateur pour une application&nbsp;donnée;</li> +<li>l&#8217;application « Donnée » interroge le service pour vérifier qu&#8217;un + utilisateur a payé ou est&nbsp;abonné;</li> +<li>l&#8217;utilisateur interroge le service pour obtenir la liste de tous ses&nbsp;abonnements.</li> +</ul> +<p>Seule l&#8217;application « Payment » a le droit de créer/modifier/supprimer +des enregistrements, les deux autres ne peuvent que consulter en lecture&nbsp;seule.</p> +<p>Une application donnée ne peut pas accéder aux paiements des autres +applications, et un utilisateur ne peut pas accéder aux paiements des +autres&nbsp;utilisateurs.</p> +<h3 id="avec-remotestorage">Avec&nbsp;RemoteStorage</h3> +<p><img alt="Remote Love - CC-BY-NC Julie +https://www.flickr.com/photos/mamajulie2008/2609549461" src="%7Bfilename%7D/images/remote-love.jpg"></p> +<p>Clairement, l&#8217;idée de <em>RemoteStorage</em> est de dissocier l&#8217;application +executée, et les données créées par l&#8217;utilisateur avec&nbsp;celle-ci.</p> +<p>Dans notre cas, c&#8217;est l&#8217;application « Payment » qui manipule des données +concernant un utilisateur. Mais celles-ci ne lui appartiennent pas +directement: certes un utilisateur doit pouvoir les supprimer, surtout +pas en créer ou les&nbsp;modifier!</p> +<p>La notion de permissions limitée à privé/publique ne suffit pas dans ce +cas&nbsp;précis.</p> +<h3 id="avec-pouchdb">Avec&nbsp;PouchDB</h3> +<p>Il va falloir créer une <em>base de données</em> par utilisateur, afin d&#8217;isoler +les enregistrements de façon sécurisée. Seule l&#8217;application « Payment » +aura tous les droits sur les&nbsp;databases.</p> +<p>Mais cela ne suffit&nbsp;pas.</p> +<p>Il ne faut pas qu&#8217;une application puisse voir les paiements des autres +applications, donc il va aussi falloir recloisonner, et créer une <em>base +de données</em> par&nbsp;application.</p> +<p>Quand un utilisateur voudra accéder à l&#8217;ensemble de ses paiements, il +faudra agréger les <em>databases</em> de toutes les applications. Quand +l&#8217;équipe marketing voudra faire des statistiques sur l&#8217;ensemble des +applications, il faudra agrégér des centaines de milliers de +<em>databases</em>.</p> +<p>Ce qui est fort dommage, puisqu&#8217;il est probable que les paiements ou +abonnements d&#8217;un utilisateur pour une application se comptent sur les +doigts d&#8217;une main. Des centaines de milliers de bases contenant moins de +5 enregistrements&nbsp;?</p> +<p>De plus, dans le cas de l&#8217;application « Payment », le serveur est +implémenté en Python. Utiliser un wrapper JavaScript comme le fait +<a href="https://pythonhosted.org/Python-PouchDB/">python-pouchdb</a> cela ne nous +fait pas trop&nbsp;rêver.</p> +<h2 id="un-nouvel-eco-systeme">Un nouvel éco-système&nbsp;?</h2> +<p><img alt="Wagon wheel - CC-BY-NC-SA arbyreed +https://www.flickr.com/photos/19779889@N00/16161808220" src="%7Bfilename%7D/images/wagon-wheel.jpg"></p> +<p>Évidemment, quand on voit la richesse des projets <em>PouchDB</em> et <em>Remote +Storage</em> et la dynamique de ces communautés, il est légitime d&#8217;hésiter +avant de développer une solution&nbsp;alternative.</p> +<p>Quand nous avons créé le serveur <em>Reading List</em>, nous l&#8217;avons construit +avec <a href="http://cliquet.readthedocs.org/">Cliquet</a>, ce fût l&#8217;occasion de +mettre au point <a href="http://cliquet.readthedocs.org/en/latest/api/">un protocole très +simple</a>, fortement +inspiré de <a href="http://en.wikipedia.org/wiki/Firefox_Sync">Firefox Sync</a>, +pour faire de la synchronisation&nbsp;d&#8217;enregistrements.</p> +<p>Et si les clients <em>Reading List</em> ont pu être implémentés en quelques +semaines, que ce soit en JavaScript, Java (Android) et <span class="caps">ASM</span> (Add-on +Firefox), c&#8217;est que le principe «*offline first*» du service est&nbsp;trivial.</p> +<h3 id="les-compromis">Les&nbsp;compromis</h3> +<p>Évidemment, nous n&#8217;avons pas la prétention de concurrencer <em>CouchDB</em>. +Nous faisons plusieurs&nbsp;concessions:</p> +<ul> +<li>De base, les collections d&#8217;enregistrements sont cloisonnées par&nbsp;utilisateur;</li> +<li>Pas d&#8217;historique des&nbsp;révisions;</li> +<li>Pas de diff sur les enregistrements entre&nbsp;révisions;</li> +<li>De base, pas de résolution de conflit&nbsp;automatique;</li> +<li>Pas de synchronisation par flux (<em>streams</em>);</li> +</ul> +<p>Jusqu&#8217;à preuve du contraire, ces compromis excluent la possibilité +d&#8217;implémenter un <a href="https://github.com/pouchdb/pouchdb/blob/master/lib/adapters/http/http.js#L721-L946">adapter +PouchDB</a> +pour la synchronisation avec le protocole <span class="caps">HTTP</span> de <em>Cliquet</em>.</p> +<p>Dommage puisque capitaliser sur l&#8217;expérience client de <em>PouchDB</em> au +niveau synchro client semble être une très bonne&nbsp;idée.</p> +<p>En revanche, nous avons plusieurs fonctionnalités&nbsp;intéressantes:</p> +<ul> +<li>Pas de&nbsp;map-reduce;</li> +<li>Synchronisation partielle et/ou ordonnée et/ou paginée&nbsp;;</li> +<li>Le client choisit, via des headers, d&#8217;écraser la donnée ou de + respecter la version du serveur&nbsp;;</li> +<li>Un seul serveur à déployer pour N applications&nbsp;;</li> +<li>Auto-hébergement simplissime&nbsp;;</li> +<li>Le client peut choisir de ne pas utiliser de « store local » du tout&nbsp;;</li> +<li>Dans le client <span class="caps">JS</span>, la gestion du « store local » sera externalisée + (on pense à <a href="https://github.com/mozilla/localForage">LocalForage</a> ou + <a href="https://github.com/dfahlander/Dexie.js">Dexie.js</a>)&nbsp;;</li> +</ul> +<p>Et, on répond au reste des <a href="#storage-specs">specifications mentionnées au début de +l&#8217;article</a>&nbsp;!</p> +<h3 id="les-arguments-philosophiques">Les arguments&nbsp;philosophiques</h3> +<p>Il est <a href="http://en.wikipedia.org/wiki/Law_of_the_instrument">illusoire de penser qu&#8217;on peut tout faire avec un seul +outil</a>.</p> +<p>Nous avons d&#8217;autres cas d&#8217;utilisations dans les cartons qui semblent +correspondre au scope de <em>PouchDB</em> (<em>pas de notion de permissions ou de +partage, environnement JavaScript, &#8230;</em>). Nous saurons en tirer profit +quand cela s&#8217;avèrera pertinent&nbsp;!</p> +<p>L&#8217;éco-système que nous voulons construire tentera de couvrir les cas +d&#8217;utilisation qui sont mal adressés par <em>PouchDB</em>. Il se&nbsp;voudra:</p> +<ul> +<li>Basé sur notre protocole très simple&nbsp;;</li> +<li>Minimaliste et multi-usages (<em>comme la fameuse <span class="caps">2CV</span></em>)&nbsp;;</li> +<li>Naïf (<em>pas de rocket science</em>)&nbsp;;</li> +<li>Sans magie (<em>explicite et facile à réimplémenter from scratch</em>)&nbsp;;</li> +</ul> +<p><a href="http://cliquet.readthedocs.org/en/latest/rationale.html">La philosophie et les fonctionnalités du toolkit python +Cliquet</a> seront +bien entendu à l&#8217;honneur&nbsp;:)</p> +<p>Quant à <em>Remote Storage</em>, dès que le besoin se présentera, nous serons +très fier de rejoindre l&#8217;initiative, mais pour l&#8217;instant cela nous +paraît risqué de démarrer en tordant la&nbsp;solution.</p> +<h3 id="les-arguments-pratiques">Les arguments&nbsp;pratiques</h3> +<p>Avant d&#8217;accepter de déployer une solution à base de <em>CouchDB</em>, les <em>ops</em> +de Mozilla vont nous demander de leur prouver par A+B que ce n&#8217;est pas +faisable avec les stacks qui sont déjà rodées en interne (i.e. MySQL, +Redis,&nbsp;PostgreSQL).</p> +<p>De plus, on doit s&#8217;engager sur une pérennité d&#8217;au moins 5 ans pour les +données. Avec <em>Cliquet</em>, en utilisant le backend PostgreSQL, les données +sont persistées à plat dans un <a href="https://github.com/mozilla-services/cliquet/blob/40aa33/cliquet/storage/postgresql/schema.sql#L14-L28">schéma PostgreSQL tout +bête</a>. +Ce qui ne sera pas le cas d&#8217;un adapteur LevelDown qui va manipuler des +notions de révisions éclatées dans un schéma&nbsp;clé-valeur.</p> +<p>Si nous basons le service sur <em>Cliquet</em>, comme c&#8217;est le cas avec +<a href="http://kinto.readthedocs.org">Kinto</a>, tout le travail d&#8217;automatisation +de la mise en production (<em>monitoring, builds <span class="caps">RPM</span>, Puppet&#8230;</em>) que nous +avons fait pour <em>Reading List</em> est complètement&nbsp;réutilisable.</p> +<p>De même, si on repart avec une stack complètement différente, nous +allons devoir recommencer tout le travail de rodage, de profiling et +d&#8217;optimisation effectué au premier&nbsp;trimestre.</p> +<h2 id="les-prochaines-etapes">Les prochaines&nbsp;étapes</h2> +<p>Et il est encore temps de changer de stratégie :) Nous aimerions avoir +un maximum de retours ! C&#8217;est toujours une décision difficile à +prendre&#8230; <code>&lt;/appel à troll&gt;</code></p> +<ul> +<li>Tordre un éco-système existant vs. constuire sur mesure&nbsp;;</li> +<li>Maîtriser l&#8217;ensemble vs. s&#8217;intégrer&nbsp;;</li> +<li>Contribuer vs. refaire&nbsp;;</li> +<li>Guider vs.&nbsp;suivre.</li> +</ul> +<p>Nous avons vraiment l&#8217;intention de rejoindre l&#8217;initiative +<a href="https://nobackend.org/">no-backend</a>, et ce premier pas n&#8217;exclue pas que +nous convergions à terme ! Peut-être que nous allons finir par rendre +notre service compatible avec <em>Remote Storage</em>, et peut-être que +<em>PouchDB</em> deviendra plus agnostique quand au protocole de&nbsp;synchronisation&#8230;</p> +<p><img alt="XKCD — Standards +https://xkcd.com/927/" src="%7Bfilename%7D/images/standards.png"></p> +<p>Utiliser ce nouvel écosystème pour le projet « Payments » va nous +permettre de mettre au point un système de permissions (<em>probablement +basé sur les scopes OAuth</em>) qui correspond au besoin exprimé. Et nous +avons bien l&#8217;intention de puiser dans <a href="http://blog.daybed.io/daybed-revival.html">notre expérience avec Daybed sur +le sujet</a>.</p> +<p>Nous extrairons aussi le code des clients implémentés pour <em>Reading +List</em> afin de faire un client JavaScript&nbsp;minimaliste.</p> +<p>En partant dans notre coin, nous prenons plusieurs&nbsp;risques:</p> +<ul> +<li>réinventer une roue dont nous n&#8217;avons pas connaissance&nbsp;;</li> +<li>échouer à faire de l&#8217;éco-système <em>Cliquet</em> un projet communautaire&nbsp;;</li> +<li>échouer à positionner <em>Cliquet</em> dans la niche des cas non couverts + par PouchDB&nbsp;:)</li> +</ul> +<p>Comme <a href="http://pouchdb.com/2015/04/05/filtered-replication.html">le dit Giovanni +Ornaghi</a>:</p> +<blockquote> +<p>Rolling out your set of webservices, push notifications, or background +services might give you more control, but at the same time it will +force you to engineer, write, test, and maintain a whole new&nbsp;ecosystem.</p> +</blockquote> +<p>C&#8217;est justement l&#8217;éco-système dont est responsable l&#8217;équipe <em>Mozilla +Cloud Services</em>!</p> +<ol> +<li>Il existe le <a href="https://sharesome.5apps.com/">projet Sharesome</a> qui + permet de partager publiquement des ressources de son <em>remote + Storage</em>.</li> +</ol>Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> +<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> +<p>Pas mal de changements depuis le début de l&#8217;année pour l&#8217;équipe +«cloud-services»&nbsp;francophone!</p> +<p>Tout d&#8217;abord, nouvelle importante, l&#8217;équipe s&#8217;étoffe avec des profils assez +complémentaires: <a class="reference external" href="https://nicolas.perriault.net/">n1k0</a> et <a class="reference external" href="http://mathieu-leplatre.info">Mathieu</a> sont venus prêter main forte à <a class="reference external" href="http://ziade.org/">Tarek</a>, <a class="reference external" href="http://natim.ionyse.com">Rémy</a> et <a class="reference external" href="http://notmyidea.org">Alexis</a>.</p> +<p>Le début de l&#8217;année a vu le lancement de <a class="reference external" href="https://www.mozilla.org/en-US/firefox/hello/">Firefox Hello</a> ce qui nous a permis de passer +à l&#8217;échelle <a class="reference external" href="https://github.com/mozilla-services/loop-server">le serveur</a>, +écrit en Node.js®, pour&nbsp;l&#8217;occasion.</p> +<div class="section" id="un-serveur-de-listes-de-lecture"> +<h2>Un serveur de listes de&nbsp;lecture</h2> +<p>En parallèle, un projet de <a class="reference external" href="https://readinglist.readthedocs.org">synchronisation de liste de lecture</a> (<em>Reading List</em>) a vu le jour. L&#8217;idée +étant de pouvoir marquer des pages &#8220;à lire pour plus tard&#8221; et de continuer la +lecture sur n&#8217;importe quel périphérique synchronisé (Firefox pour Android ou +Firefox Desktop). Un équivalent libre à <a class="reference external" href="http://getpocket.com">Pocket</a> en quelque sorte, qu&#8217;il est +possible d&#8217;héberger&nbsp;soit-même.</p> +<img alt="Capture d'écran de Firefox nightly avec readinglist." src="https://blog.notmyidea.org/images/readinglist-screenshot.png" /> +<p>Pour le construire, nous aurions pu réutiliser <a class="reference external" href="https://github.com/mozilla-services/server-syncstorage">Firefox Sync</a>, après tout +c&#8217;est un service de synchronisation de données très robuste, construit avec <a class="reference external" href="http://cornice.readthedocs.org/">Cornice</a>. +Mais seulement, <em>Sync</em> n&#8217;a pas été pensé pour garantir la pérennité des données, +et la marche était trop haute pour changer ça en&nbsp;profondeur.</p> +<p>Nous aurions pu aussi nous contenter de faire une énième application qui expose +une <span class="caps">API</span> et persiste des données dans une base de&nbsp;données.</p> +<p>Mais cette nouvelle petite équipe n&#8217;est pas là par hasard&nbsp;:)</p> +</div> +<div class="section" id="la-daybed-team"> +<h2>La «Daybed&nbsp;Team»</h2> +<p>On partage une vision: un service générique de stockage de données ! Peut-être +que ça vous rappelle <a class="reference external" href="https://daybed.io">un certain projet nommé Daybed</a> ? +Pour les applications clientes, JavaScript, mobiles ou autres, l&#8217;utilisation de +ce service doit être un jeu d&#8217;enfant ! L&#8217;application gère ses données +localement (aka offline-first), et synchronise à la&nbsp;demande.</p> +<p>Ici, le cœur du serveur <em>Reading List</em> est justement une <span class="caps">API</span> &#8220;<span class="caps">CRUD</span>&#8221; (Create, +Retrieve, Update, Delete), qui gère de la synchronisation et de +l&#8217;authentification. Nous avons donc pris le parti de faire une <span class="caps">API</span> &#8220;simple&#8221;, +avec le moins de spécificités possible, qui poserait les bases d&#8217;un service +générique. Notamment parce qu&#8217;il y a d&#8217;autres projets dans la même trempe qui vont&nbsp;suivre.</p> +<p>Pas mal d&#8217;expérience ayant été accumulée au sein de l&#8217;équipe, avec d&#8217;une part la +création de <em>Firefox Sync</em>, et d&#8217;autre part avec <em>Daybed</em>, notre side-project, nous +tentons de ne pas reproduire les mêmes erreurs, tout en gardant les concepts +qui ont fait leurs&nbsp;preuves.</p> +<p>Par exemple, nous avons conservé le mécanisme de collections d&#8217;enregistrements +et de <em>timestamp</em> de <em>Sync</em>. Comme ces problématiques sont récurrentes, voire +incontournables, nous avons décidé de reprendre le protocole de synchronisation, +de l&#8217;étendre légèrement et surtout de le dissocier du projet de listes de&nbsp;lecture.</p> +</div> +<div class="section" id="le-mecanisme-qui-force-a-aller-de-l-avant"> +<h2>Le mécanisme qui force à aller de&nbsp;l&#8217;avant</h2> +<p>Comme première pierre à l&#8217;édifice, nous avons donné naissance au projet +<a class="reference external" href="https://cliquet.readthedocs.org">Cliquet</a>, dont l&#8217;idée principale est de +fournir une implémentation de ce protocole en python, tout en factorisant +l&#8217;ensemble de nos bonnes pratiques (pour la prod&nbsp;notamment).</p> +<img alt="Logo du projet Cliquet" class="align-right" src="https://blog.notmyidea.org/images/cliquet/cliquet-logo.png" /> +<p>L&#8217;avantage d&#8217;avoir un protocole plutôt qu&#8217;un monolithe, c&#8217;est que si vous +préférez Asyncio, io.js ou Go, on vous encouragera à publier votre +implémentation alternative&nbsp;!</p> +<p>Avec <em>Cliquet</em>, le code du serveur liste de lecture consiste principalement +à définir un schéma pour les enregistrements, puis à forcer des valeurs de +champs sur certains appels. Cela réduit ce projet à quelques dizaines de lignes +de&nbsp;code.</p> +<p>Quant au futur service de stockage générique, <a class="reference external" href="http://kinto.readthedocs.org">le projet</a> en est encore à ses balbutiements mais c&#8217;est +bel et bien en route ! Il permet déjà d&#8217;être branché comme backend de stockage +dans une application <em>Cliquet</em>, et ça <a class="reference external" href="https://github.com/mozilla-services/kinto/blob/0.2.1/kinto/views/collection.py">implémenté en 20 lignes de code</a>!</p> +<p>Ah, et cette fois, nous ne construirons les fonctionnalités qu&#8217;à partir des +besoins concrets qui surviennent. Ça paraît tout bête, mais sur <em>Daybed</em> on +l&#8217;a pas vu venir&nbsp;:)</p> +<p>Dans les prochains articles, nous avons prévu de décrire les bonnes pratiques +rassemblées dans le protocole (ou <em>Cliquet</em>), certains points techniques précis +et de vous présenter notre vision via des exemples et&nbsp;tutoriaux.</p> +<p>À bientôt, donc&nbsp;!</p> +</div> +What’s Hawk and how to use it?2014-07-31T00:00:00+02:002014-07-31T00:00:00+02:00tag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.html +<p>At Mozilla, we recently had to implement <a href="https://github.com/hueniverse/hawk">the Hawk authentication +scheme</a> for a number of projects, +and we came up creating two libraries to ease integration into pyramid +and node.js&nbsp;apps.</p> +<p>But maybe you don&#8217;t know&nbsp;Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the …</p> +<p>At Mozilla, we recently had to implement <a href="https://github.com/hueniverse/hawk">the Hawk authentication +scheme</a> for a number of projects, +and we came up creating two libraries to ease integration into pyramid +and node.js&nbsp;apps.</p> +<p>But maybe you don&#8217;t know&nbsp;Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original +<a href="https://en.wikipedia.org/wiki/OAuth">OAuth</a> specification authors, that +intends to replace the 2-legged OAuth authentication scheme using a +simpler&nbsp;approach.</p> +<p>It is an authentication scheme for <span class="caps">HTTP</span>, built around <a href="https://en.wikipedia.org/wiki/Hmac"><span class="caps">HMAC</span> +digests</a> of requests and&nbsp;responses.</p> +<p>Every authenticated client request has an Authorization header +containing a <span class="caps">MAC</span> (Message Authentication Code) and some additional +metadata, then each server response to authenticated requests contains a +Server-Authorization header that authenticates the response, so the +client is sure it comes from the right&nbsp;server.</p> +<h2 id="exchange-of-the-hawk-id-and-hawk-key">Exchange of the hawk id and hawk&nbsp;key</h2> +<p>To sign the requests, a client needs to retrieve a token id and a token +key from the&nbsp;server.</p> +<p>Hawk itself does not define how these credentials should be exchanged +between the server and the client. The excellent team behind <a href="http://accounts.firefox.com">Firefox +Accounts</a> put together a scheme to do that, +which acts like the&nbsp;following:</p> +<div class="note"> + +<div class="admonition-title"> + +Note + +</div> + +All this derivation crazyness might seem a bit complicated, but don&#8217;t +worry, we put together some libraries that takes care of that for you +automatically. + +If you are not interested into these details, you can directly jump to +the next section to see how to use the libraries. + +</div> + +<p>When your server application needs to send you the credentials, it will +return it inside a specific Hawk-Session-Token header. This token can be +derived to split this string in two values (hawk id and hawk key) that +you will use to sign your next&nbsp;requests.</p> +<p>In order to get the hawk credentials, you&#8217;ll need&nbsp;to:</p> +<p>First, do an <a href="http://en.wikipedia.org/wiki/HKDF"><span class="caps">HKDF</span> derivation</a> on the +given session token. You&#8217;ll need to use the following&nbsp;parameters:</p> +<div class="highlight"><pre><span></span><code>key_material = HKDF(hawk_session, &quot;&quot;, &#39;identity.mozilla.com/picl/v1/sessionToken&#39;, 32*2) +</code></pre></div> + +<div class="note"> + +<div class="admonition-title"> + +Note + +</div> + +The `identity.mozilla.com/picl/v1/sessionToken` is a reference to this +way of deriving the credentials, not an actual <span class="caps">URL</span>. + +</div> + +<p>Then, the key material you&#8217;ll get out of the <span class="caps">HKDF</span> need to be separated +into two parts, the first 32 hex caracters are the hawk id, and the next +32 ones are the hawk&nbsp;key.</p> +<p>Credentials:</p> +<div class="highlight"><pre><span></span><code>javascript +credentials = { + &#39;id&#39;: keyMaterial[0:32], + &#39;key&#39;: keyMaterial[32:64], + &#39;algorithm&#39;: &#39;sha256&#39; +} +</code></pre></div> + +<h2 id="httpie">Httpie</h2> +<p>To showcase APIs in the documentation, I like to use +<a href="https://github.com/jakubroztocil/httpie">httpie</a>, a curl-replacement +with a nicer <span class="caps">API</span>, built around <a href="http://python-requests.org">the python requests +library</a>.</p> +<p>Luckily, HTTPie allows you to plug different authentication schemes for +it, so <a href="https://github.com/mozilla-services/requests-hawk">I wrote a +wrapper</a> around +<a href="https://github.com/kumar303/mohawk">mohawk</a> to add hawk support to the +requests&nbsp;lib.</p> +<p>Doing hawk requests in your terminal is now as simple&nbsp;as:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>requests-hawk<span class="w"> </span>httpie +$<span class="w"> </span>http<span class="w"> </span>GET<span class="w"> </span>localhost:5000/registration<span class="w"> </span>--auth-type<span class="o">=</span>hawk<span class="w"> </span>--auth<span class="o">=</span><span class="s1">&#39;id:key&#39;</span> +</code></pre></div> + +<p>In addition, it will help you to craft requests using the requests&nbsp;library:</p> +<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span> +<span class="kn">from</span> <span class="nn">requests_hawk</span> <span class="kn">import</span> <span class="n">HawkAuth</span> + +<span class="n">hawk_auth</span> <span class="o">=</span> <span class="n">HawkAuth</span><span class="p">(</span> + <span class="n">credentials</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="nb">id</span><span class="p">,</span> <span class="s1">&#39;key&#39;</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="s1">&#39;algorithm&#39;</span><span class="p">:</span> <span class="s1">&#39;sha256&#39;</span><span class="p">})</span> + +<span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&quot;/url&quot;</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="n">hawk_auth</span><span class="p">)</span> +</code></pre></div> + +<p>Alternatively, if you don&#8217;t have the token id and key, you can pass the +hawk session token I talked about earlier and the lib will take care of +the derivation for&nbsp;you:</p> +<div class="highlight"><pre><span></span><code><span class="n">hawk_auth</span> <span class="o">=</span> <span class="n">HawkAuth</span><span class="p">(</span> + <span class="n">hawk_session</span><span class="o">=</span><span class="n">resp</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">&#39;hawk-session-token&#39;</span><span class="p">],</span> + <span class="n">server_url</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">server_url</span> +<span class="p">)</span> +<span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&quot;/url&quot;</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="n">hawk_auth</span><span class="p">)</span> +</code></pre></div> + +<h2 id="integrate-with-python-pyramid-apps">Integrate with python pyramid&nbsp;apps</h2> +<p>If you&#8217;re writing pyramid applications, you&#8217;ll be happy to learn that +<a href="https://www.rfk.id.au/blog/">Ryan Kelly</a> put together a library that +makes Hawk work as an Authentication provider for them. I&#8217;m chocked how +simple it is to use&nbsp;it.</p> +<p>Here is a demo of how we implemented it for&nbsp;Daybed:</p> +<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pyramid_hawkauth</span> <span class="kn">import</span> <span class="n">HawkAuthenticationPolicy</span> + +<span class="n">policy</span> <span class="o">=</span> <span class="n">HawkAuthenticationPolicy</span><span class="p">(</span><span class="n">decode_hawk_id</span><span class="o">=</span><span class="n">get_hawk_id</span><span class="p">)</span> +<span class="n">config</span><span class="o">.</span><span class="n">set_authentication_policy</span><span class="p">(</span><span class="n">authn_policy</span><span class="p">)</span> +</code></pre></div> + +<p>The get_hawk_id function is a function that takes a request and a +tokenid and returns a tuple of (token_id,&nbsp;token_key).</p> +<p>How you want to store the tokens and retrieve them is up to you. The +default implementation (e.g. if you don&#8217;t pass a decode_hawk_id +function) decodes the key from the token itself, using a master secret +on the server (so you don&#8217;t need to store&nbsp;anything).</p> +<h2 id="integrate-with-nodejs-express-apps">Integrate with node.js Express&nbsp;apps</h2> +<p>We had to implement Hawk authentication for two node.js projects and +finally came up factorizing everything in a library for express, named +<a href="https://github.com/mozilla-services/express-hawkauth">express-hawkauth</a>.</p> +<p>In order to plug it in your application, you&#8217;ll need to use it as a&nbsp;middleware:</p> +<div class="highlight"><pre><span></span><code><span class="n">javascript</span> +<span class="k">var</span><span class="w"> </span><span class="n">express</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">require</span><span class="p">(</span><span class="s2">&quot;express&quot;</span><span class="p">);</span> +<span class="k">var</span><span class="w"> </span><span class="n">hawk</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">require</span><span class="p">(</span><span class="s2">&quot;express-hawkauth&quot;</span><span class="p">);</span> +<span class="n">app</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">express</span><span class="p">();</span> + +<span class="k">var</span><span class="w"> </span><span class="n">hawkMiddleware</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hawk</span><span class="o">.</span><span class="n">getMiddleware</span><span class="p">({</span> +<span class="w"> </span><span class="n">hawkOptions</span><span class="p">:</span><span class="w"> </span><span class="p">{},</span> +<span class="w"> </span><span class="n">getSession</span><span class="p">:</span><span class="w"> </span><span class="n">function</span><span class="p">(</span><span class="n">tokenId</span><span class="p">,</span><span class="w"> </span><span class="n">cb</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">function</span><span class="w"> </span><span class="n">which</span><span class="w"> </span><span class="k">pass</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">cb</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">key</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">algorithm</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">given</span><span class="w"> </span><span class="n">token</span><span class="w"> </span><span class="n">id</span><span class="o">.</span><span class="w"> </span><span class="n">First</span><span class="w"> </span><span class="n">argument</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">callback</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">potential</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">error</span><span class="o">.</span> +<span class="w"> </span><span class="n">cb</span><span class="p">(</span><span class="nb nb-Type">null</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="n">key</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;key&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">algorithm</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;sha256&quot;</span><span class="p">});</span> +<span class="w"> </span><span class="p">},</span> +<span class="w"> </span><span class="n">createSession</span><span class="p">:</span><span class="w"> </span><span class="n">function</span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="n">cb</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">function</span><span class="w"> </span><span class="n">which</span><span class="w"> </span><span class="n">stores</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">session</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">given</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">key</span><span class="o">.</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">Argument</span><span class="w"> </span><span class="n">returned</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">potential</span><span class="w"> </span><span class="n">error</span><span class="o">.</span> +<span class="w"> </span><span class="n">cb</span><span class="p">(</span><span class="nb nb-Type">null</span><span class="p">);</span> +<span class="w"> </span><span class="p">},</span> +<span class="w"> </span><span class="n">setUser</span><span class="p">:</span><span class="w"> </span><span class="n">function</span><span class="p">(</span><span class="n">req</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">tokenId</span><span class="p">,</span><span class="w"> </span><span class="n">cb</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">function</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">uses</span><span class="w"> </span><span class="n">req</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">hawkId</span><span class="w"> </span><span class="n">when</span><span class="w"> </span><span class="n">they</span><span class="s1">&#39;re known so</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">tweak</span><span class="w"> </span><span class="n">it</span><span class="o">.</span><span class="w"> </span><span class="n">For</span><span class="w"> </span><span class="n">instance</span><span class="p">,</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">store</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">tokenId</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">the</span> +<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">user</span><span class="o">.</span> +<span class="w"> </span><span class="n">req</span><span class="o">.</span><span class="n">user</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tokenId</span><span class="p">;</span> +<span class="w"> </span><span class="p">}</span> +<span class="p">});</span> + +<span class="n">app</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;/hawk-enabled-endpoint&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">hawkMiddleware</span><span class="p">);</span> +</code></pre></div> + +<p>If you pass the createSession parameter, all non-authenticated requests +will create a new hawk session and return it with the response, in the +Hawk-Session-Token&nbsp;header.</p> +<p>If you want to only check a valid hawk session exists (without creating +a new one), just create a middleware which doesn&#8217;t have any +createSession parameter&nbsp;defined.</p> +<h2 id="some-reference-implementations">Some reference&nbsp;implementations</h2> +<p>As a reference, here is how we&#8217;re using the libraries I&#8217;m talking about, +in case that helps you to integrate with your&nbsp;projects.</p> +<ul> +<li>The Mozilla Loop server <a href="https://github.com/mozilla-services/loop-server/blob/master/loop/index.js#L70-L133">uses hawk as authentication once you&#8217;re + logged in with a valid BrowserID + assertion</a>; + request, to keep a session between client and&nbsp;server;</li> +<li><a href="https://github.com/spiral-project/daybed/commit/f178b4e43015fa077430798dcd3d0886c7611caf">I recently added hawk support on the Daybed + project</a> + (that&#8217;s a pyramid / cornice)&nbsp;app.</li> +<li>It&#8217;s also interesting to note that Kumar put together <a href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for + the django rest&nbsp;framework</a></li> +</ul>Implementing CORS in Cornice2013-02-04T00:00:00+01:002013-02-04T00:00:00+01:00tag:blog.notmyidea.org,2013-02-04:/implementing-cors-in-cornice.html +<div class="note"> + +<div class="admonition-title"> + +Note + +</div> + +I&#8217;m cross-posting [on the mozilla services +weblog](https://blog.mozilla.org/services/). Since this is the first +time we&#8217;re doing that, I though it could be useful to point you there. +Check it out and expect more technical articles there in the future. + +</div> + +<p>For security reasons, it …</p> +<div class="note"> + +<div class="admonition-title"> + +Note + +</div> + +I&#8217;m cross-posting [on the mozilla services +weblog](https://blog.mozilla.org/services/). Since this is the first +time we&#8217;re doing that, I though it could be useful to point you there. +Check it out and expect more technical articles there in the future. + +</div> + +<p>For security reasons, it&#8217;s not possible to do cross-domain requests. In +other words, if you have a page served from the domain lolnet.org, it +will not be possible for it to get data from&nbsp;notmyidea.org.</p> +<p>Well, it&#8217;s possible, using tricks and techniques like +<a href="http://en.wikipedia.org/wiki/JSONP"><span class="caps">JSONP</span></a>, but that doesn&#8217;t work all +the time (see <a href="#how-this-is-different-from-jsonp">the section below</a>). I +remember myself doing some simple proxies on my domain server to be able +to query other&#8217;s <span class="caps">API</span>.</p> +<p>Thankfully, there is a nicer way to do this, namely, &#8220;Cross Origin +Resource-Sharing&#8221;, or <a href="http://www.w3.org/TR/cors/"><span class="caps">CORS</span></a>.</p> +<h2 id="you-want-an-icecream-go-ask-your-dad-first">You want an icecream? Go ask your dad&nbsp;first.</h2> +<p>If you want to use <span class="caps">CORS</span>, you need the <span class="caps">API</span> you&#8217;re querying to support it; +on the server&nbsp;side.</p> +<p>The <span class="caps">HTTP</span> server need to answer to the <span class="caps">OPTIONS</span> verb, and with the +appropriate response&nbsp;headers.</p> +<p><span class="caps">OPTIONS</span> is sent as what the authors of the spec call a &#8220;preflight +request&#8221;; just before doing a request to the <span class="caps">API</span>, the <em>User-Agent</em> (the +browser most of the time) asks the permission to the resource, with an +<span class="caps">OPTIONS</span>&nbsp;call.</p> +<p>The server answers, and tell what is available and what&nbsp;isn&#8217;t:</p> +<p><img alt="The CORS flow (from the HTML5 CORS tutorial)" src="/images/cors_flow.png"></p> +<ul> +<li> +<p>1a. The User-Agent, rather than doing the call directly, asks the + server, the <span class="caps">API</span>, the permission to do the request. It does so with + the following&nbsp;headers:</p> +<ul> +<li><strong>Access-Control-Request-Headers</strong>, contains the headers the + User-Agent want to&nbsp;access.</li> +<li><strong>Access-Control-Request-Method</strong> contains the method the + User-Agent want to&nbsp;access.</li> +</ul> +</li> +<li> +<p>1b. The <span class="caps">API</span> answers what is&nbsp;authorized:</p> +<ul> +<li><strong>Access-Control-Allow-Origin</strong> the origin that&#8217;s accepted. Can + be * or the domain&nbsp;name.</li> +<li><strong>Access-Control-Allow-Methods</strong> a <em>list</em> of allowed methods. + This can be cached. Note than the request asks permission for + one method and the server should return a list of accepted&nbsp;methods.</li> +<li><strong>Access-Allow-Headers</strong> a list of allowed headers, for all of + the methods, since this can be cached as&nbsp;well.</li> +</ul> +</li> +<li> +<ol> +<li>The User-Agent can do the &#8220;normal&#8221;&nbsp;request.</li> +</ol> +</li> +</ul> +<p>So, if you want to access the /icecream resource, and do a <span class="caps">PUT</span> there, +you&#8217;ll have the following&nbsp;flow:</p> +<div class="highlight"><pre><span></span><code>&gt; OPTIONS /icecream +&gt; Access-Control-Request-Methods = PUT +&gt; Origin: notmyidea.org +&lt; Access-Control-Allow-Origin = notmyidea.org +&lt; Access-Control-Allow-Methods = PUT,GET,DELETE +200 OK +</code></pre></div> + +<p>You can see that we have an Origin Header in the request, as well as a +Access-Control-Request-Methods. We&#8217;re here asking if we have the right, +as notmyidea.org, to do a <span class="caps">PUT</span> request on&nbsp;/icecream.</p> +<p>And the server tells us that we can do that, as well as <span class="caps">GET</span> and <span class="caps">DELETE</span>.</p> +<p>I&#8217;ll not cover all the details of the <span class="caps">CORS</span> specification here, but bear +in mind than with <span class="caps">CORS</span>, you can control what are the authorized methods, +headers, origins, and if the client is allowed to send authentication +information or&nbsp;not.</p> +<h2 id="a-word-about-security">A word about&nbsp;security</h2> +<p><span class="caps">CORS</span> is not an answer for every cross-domain call you want to do, +because you need to control the service you want to call. For instance, +if you want to build a feed reader and access the feeds on different +domains, you can be pretty much sure that the servers will not implement +<span class="caps">CORS</span>, so you&#8217;ll need to write a proxy yourself, to provide&nbsp;this.</p> +<p>Secondly, if misunderstood, <span class="caps">CORS</span> can be insecure, and cause problems. +Because the rules apply when a client wants to do a request to a server, +you need to be extra careful about who you&#8217;re&nbsp;authorizing.</p> +<p>An incorrectly secured <span class="caps">CORS</span> server can be accessed by a malicious client +very easily, bypassing network security. For instance, if you host a +server on an intranet that is only available from behind a <span class="caps">VPN</span> but +accepts every cross-origin call. A bad guy can inject javascript into +the browser of a user who has access to your protected server and make +calls to your service, which is probably not what you&nbsp;want.</p> +<h2 id="how-this-is-different-from-jsonp">How this is different from <span class="caps">JSONP</span>?</h2> +<p>You may know the <a href="http://en.wikipedia.org/wiki/JSONP"><span class="caps">JSONP</span></a> protocol. +<span class="caps">JSONP</span> allows cross origin, but for a particular use case, and does have +some drawbacks (for instance, it&#8217;s not possible to do DELETEs or PUTs +with <span class="caps">JSONP</span>).</p> +<p><span class="caps">JSONP</span> exploits the fact that it is possible to get information from +another domain when you are asking for javascript code, using the +\&lt;script&gt;&nbsp;element.</p> +<blockquote> +<p>Exploiting the open policy for \&lt;script&gt; elements, some pages use +them to retrieve JavaScript code that operates on dynamically +generated <span class="caps">JSON</span>-formatted data from other origins. This usage pattern +is known as <span class="caps">JSONP</span>. Requests for <span class="caps">JSONP</span> retrieve not <span class="caps">JSON</span>, but arbitrary +JavaScript code. They are evaluated by the JavaScript interpreter, not +parsed by a <span class="caps">JSON</span>&nbsp;parser.</p> +</blockquote> +<h2 id="using-cors-in-cornice">Using <span class="caps">CORS</span> in&nbsp;Cornice</h2> +<p>Okay, things are hopefully clearer about <span class="caps">CORS</span>, let&#8217;s see how we +implemented it on the&nbsp;server-side.</p> +<p>Cornice is a toolkit that lets you define resources in python and takes +care of the heavy lifting for you, so I wanted it to take care of the +<span class="caps">CORS</span> support as&nbsp;well.</p> +<p>In Cornice, you define a service like&nbsp;this:</p> +<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">cornice</span> <span class="kn">import</span> <span class="n">Service</span> + +<span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;foobar&quot;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s2">&quot;/foobar&quot;</span><span class="p">)</span> + +<span class="c1"># and then you do something with it</span> +<span class="nd">@foobar</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> +<span class="k">def</span> <span class="nf">get_foobar</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="c1"># do something with the request.</span> +</code></pre></div> + +<p>To add <span class="caps">CORS</span> support to this resource, you can go this way, with the +cors_origins&nbsp;parameter:</p> +<div class="highlight"><pre><span></span><code><span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;foobar&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/foobar&#39;</span><span class="p">,</span> <span class="n">cors_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> +</code></pre></div> + +<p>Ta-da! You have enabled <span class="caps">CORS</span> for your service. <strong>Be aware that you&#8217;re +authorizing anyone to query your server, that may not be what you&nbsp;want.</strong></p> +<p>Of course, you can specify a list of origins you trust, and you don&#8217;t +need to stick with *, which means &#8220;authorize&nbsp;everyone&#8221;.</p> +<h3 id="headers">Headers</h3> +<p>You can define the headers you want to expose for the&nbsp;service:</p> +<div class="highlight"><pre><span></span><code><span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;foobar&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/foobar&#39;</span><span class="p">,</span> <span class="n">cors_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> + +<span class="nd">@foobar</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">cors_headers</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;X-My-Header&#39;</span><span class="p">,</span> <span class="s1">&#39;Content-Type&#39;</span><span class="p">))</span> +<span class="k">def</span> <span class="nf">get_foobars_please</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="k">return</span> <span class="s2">&quot;some foobar for you&quot;</span> +</code></pre></div> + +<p>I&#8217;ve done some testing and it wasn&#8217;t working on Chrome because I wasn&#8217;t +handling the headers the right way (The missing one was Content-Type, +that Chrome was asking for). With my first version of the +implementation, I needed the service implementers to explicitely list +all the headers that should be exposed. While this improves security, it +can be frustrating while&nbsp;developing.</p> +<p>So I introduced an expose_all_headers flag, which is set to True by +default, if the service supports <span class="caps">CORS</span>.</p> +<h3 id="cookies-credentials">Cookies /&nbsp;Credentials</h3> +<p>By default, the requests you do to your <span class="caps">API</span> endpoint don&#8217;t include the +credential information for security reasons. If you really want to do +that, you need to enable it using the cors_credentials parameter. You +can activate this one on a per-service basis or on a per-method&nbsp;basis.</p> +<h3 id="caching">Caching</h3> +<p>When you do a preflight request, the information returned by the server +can be cached by the User-Agent so that it&#8217;s not redone before each +actual&nbsp;call.</p> +<p>The caching period is defined by the server, using the +Access-Control-Max-Age header. You can configure this timing using the +cors_max_age&nbsp;parameter.</p> +<h3 id="simplifying-the-api">Simplifying the <span class="caps">API</span></h3> +<p>We have cors_headers, cors_enabled, cors_origins, cors_credentials, +cors_max_age, cors_expose_all_headers … a fair number of +parameters. If you want to have a specific <span class="caps">CORS</span>-policy for your +services, that can be a bit tedious to pass these to your services all +the&nbsp;time.</p> +<p>I introduced another way to pass the <span class="caps">CORS</span> policy, so you can do +something like&nbsp;that:</p> +<div class="highlight"><pre><span></span><code><span class="n">policy</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">enabled</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> + <span class="n">headers</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;X-My-Header&#39;</span><span class="p">,</span> <span class="s1">&#39;Content-Type&#39;</span><span class="p">),</span> + <span class="n">origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*.notmyidea.org&#39;</span><span class="p">),</span> + <span class="n">credentials</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> + <span class="n">max_age</span><span class="o">=</span><span class="mi">42</span><span class="p">)</span> + +<span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;foobar&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/foobar&#39;</span><span class="p">,</span> <span class="n">cors_policy</span><span class="o">=</span><span class="n">policy</span><span class="p">)</span> +</code></pre></div> + +<h2 id="comparison-with-other-implementations">Comparison with other&nbsp;implementations</h2> +<p>I was curious to have a look at other implementations of <span class="caps">CORS</span>, in django +for instance, and I found <a href="https://gist.github.com/426829.js">a gist about +it</a>.</p> +<p>Basically, this adds a middleware that adds the &#8220;rights&#8221; headers to the +answer, depending on the&nbsp;request.</p> +<p>While this approach works, it&#8217;s not implementing the specification +completely. You need to add support for all the resources at&nbsp;once.</p> +<p>We can think about a nice way to implement this specifying a definition +of what&#8217;s supposed to be exposed via <span class="caps">CORS</span> and what shouldn&#8217;t directly in +your settings. In my opinion, <span class="caps">CORS</span> support should be handled at the +service definition level, except for the list of authorized hosts. +Otherwise, you don&#8217;t know exactly what&#8217;s going on when you look at the +definition of the&nbsp;service.</p> +<h2 id="resources">Resources</h2> +<p>There are a number of good resources that can be useful to you if you +want to either understand how <span class="caps">CORS</span> works, or if you want to implement it&nbsp;yourself.</p> +<ul> +<li><a href="http://enable-cors.org/">http://enable-cors.org/</a> is useful to get started when you don&#8217;t + know anything about <span class="caps">CORS</span>.</li> +<li>There is a <span class="caps">W3C</span> wiki page containing information that may be useful + about clients, common pitfalls etc: + <a href="http://www.w3.org/wiki/CORS_Enabled">http://www.w3.org/wiki/CORS_Enabled</a></li> +<li><em><span class="caps">HTML5</span> rocks</em> has a tutorial explaining how to implement <span class="caps">CORS</span>, with + <a href="http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server">a nice section about the + server-side</a>.</li> +<li>Be sure to have a look at the <a href="http://caniuse.com/#search=cors">clients support-matrix for this + feature</a>.</li> +<li>About security, <a href="https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity">check out this&nbsp;page</a></li> +<li>If you want to have a look at the implementation code, check <a href="https://github.com/mozilla-services/cornice/pull/98/files">on&nbsp;github</a></li> +</ul> +<p>Of course, the <span class="caps">W3C</span> specification is the best resource to rely on. This +specification isn&#8217;t hard to read, so you may want to go through it. +Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>Status board2012-12-29T00:00:00+01:002012-12-29T00:00:00+01:00tag:blog.notmyidea.org,2012-12-29:/status-board.html +<p>À force de démarrer des services web pour un oui et pour un non, de +proposer à des copains d&#8217;héberger leurs sites, de faire pareil pour +quelques assos etc, je me suis retrouvé avec, comme dirait l&#8217;autre, <em>une +bonne platrée</em> de sites et de services à gérer sur …</p> +<p>À force de démarrer des services web pour un oui et pour un non, de +proposer à des copains d&#8217;héberger leurs sites, de faire pareil pour +quelques assos etc, je me suis retrouvé avec, comme dirait l&#8217;autre, <em>une +bonne platrée</em> de sites et de services à gérer sur lolnet.org, mon&nbsp;serveur.</p> +<p>Jusqu&#8217;à très récemment, rien de tout ça n&#8217;était sauvegardé, et non plus +monitoré. Après quelques recherches, je suis tombé sur +<a href="http://www.stashboard.org/">stashboard</a>, un &#8220;status board&#8221; qu&#8217;il est +bien fait. Le seul problème, c&#8217;est écrit pour se lancer sur <span class="caps">GAE</span>, <em>Google +App Engine</em>. Heureusement, c&#8217;est open-source, et ça a été forké pour +donner naissance à +<a href="https://github.com/bfirsh/whiskerboard">whiskerboard</a> (la planche +moustachue, pour les non&nbsp;anglophones).</p> +<p><img alt="Capture d'écran du site." src="/images/status_board.png"></p> +<h2 id="verifier-le-statut-des-services">Vérifier le statut des&nbsp;services</h2> +<p>Donc, c&#8217;est chouette, c&#8217;est facile à installer, tout ça, mais… mais ça ne fait en fait pas ce que je veux: ça ne fait que m&#8217;afficher le statut des services, mais ça ne vérifie pas que tout est bien&nbsp;&#8220;up&#8221;.</p> +<p>Bon, un peu embêtant pour moi, parce que c&#8217;est vraiment ça que je voulais. Pas grave, je sais un peu coder, autant que ça serve. J&#8217;ai ajouté quelques fonctionnalités au soft, qui sont disponibles sur mon fork, sur github:: <a href="https://github.com/almet/whiskerboard">https://github.com/almet/whiskerboard</a>&nbsp;.</p> +<p>Entres autres, il est désormais possible de lancer +<a href="http://celeryproject.org/">celery</a> en tache de fond et de vérifier périodiquement que les services sont toujours bien vivants, en utilisant une tache&nbsp;spécifique.</p> +<p>C&#8217;était un bonheur de développer ça (on a fait ça à deux, avec guillaume, avec un mumble + tmux en pair prog, en une petite soirée, ça&nbsp;dépote).</p> +<p>Les modifications sont assez simples, vous pouvez aller jeter un œil aux changements ici: +<a href="https://github.com/almet/whiskerboard/compare/b539337416...master">https://github.com/almet/whiskerboard/compare/b539337416&#8230;master</a></p> +<p>En&nbsp;gros:</p> +<ul> +<li>ajout d&#8217;une connection_string aux services (de la forme&nbsp;protocol://host:port)</li> +<li>ajout d&#8217;une commande check_status qui s&#8217;occupe d&#8217;itérer sur les + services et de lancer des taches celery qui vont bien, en fonction + du&nbsp;protocole</li> +<li>ajout des taches en&nbsp;question</li> +</ul> +<h2 id="deploiement">Déploiement</h2> +<p>Le plus long a été de le déployer en fin de compte, parce que je ne +voulais pas déployer mon service de supervision sur mon serveur,&nbsp;forcément.</p> +<p>Après un essai (plutôt rapide en fait) sur <a href="http://heroku.com">heroku</a>, +je me suis rendu compte qu&#8217;il me fallait payer pas loin de 35$ par mois +pour avoir un process celeryd qui tourne, donc j&#8217;ai un peu cherché +ailleurs, pour finalement déployer la chose chez +<a href="https://www.alwaysdata.com/">alwaysdata</a></p> +<p>Après quelques péripéties, j&#8217;ai réussi à faire tourner le tout, ça à été +un peu la bataille au départ pour installer virtualenv (j&#8217;ai du faire +des changements dans mon <span class="caps">PATH</span> pour que ça puisse marcher), voici mon&nbsp;`.bash_profile`:</p> +<div class="highlight"><pre><span></span><code><span class="k">export</span><span class="w"> </span><span class="n">PYTHONPATH</span><span class="o">=~/</span><span class="n">modules</span><span class="o">/</span> +<span class="k">export</span><span class="w"> </span><span class="n">PATH</span><span class="o">=$</span><span class="n">HOME</span><span class="o">/</span><span class="n">modules</span><span class="o">/</span><span class="n">bin</span><span class="p">:</span><span class="o">$</span><span class="n">HOME</span><span class="o">/</span><span class="n">modules</span><span class="o">/</span><span class="p">:</span><span class="o">$</span><span class="n">PATH</span> +</code></pre></div> + +<p>Et après y&#8217;a plus qu&#8217;à installer avec&nbsp;`easy_install`:</p> +<div class="highlight"><pre><span></span><code>easy_install --install-dir ~/modules -U pip +easy_install --install-dir ~/modules -U virtualenv +</code></pre></div> + +<p>Et à créer le&nbsp;virtualenv:</p> +<div class="highlight"><pre><span></span><code>virtualenv venv +venv/bin/pip install -r requirements.txt +</code></pre></div> + +<p>Dernière étape, la création d&#8217;un fichier application.wsgi qui s&#8217;occupe +de rendre l&#8217;application disponible, avec le bon&nbsp;venv:</p> +<h2 id="ssl-et-requests"><span class="caps">SSL</span> et&nbsp;Requests</h2> +<p>Quelques tours de manivelle plus loin, j&#8217;ai un celeryd qui tourne et qui +consomme les taches qui lui sont envoyées (pour des questions de +simplicité, j&#8217;ai utilisé le backend django de celery, donc pas besoin +d&#8217;<span class="caps">AMQP</span>, par&nbsp;exemple).</p> +<p>Problème, les ressources que je vérifie en <span class="caps">SSL</span> (<span class="caps">HTTPS</span>) me jettent. Je +sais pas exactement pourquoi à l&#8217;heure qu&#8217;il est, mais il semble que +lorsque je fais une requête avec +<a href="http://docs.python-requests.org/en/latest/">Requests</a> je me récupère +des <em>Connection Refused</em>. Peut être une sombre histoire de proxy ? En +attendant, les appels avec <span class="caps">CURL</span> fonctionnent, donc j&#8217;ai fait <a href="https://github.com/ametaireau/whiskerboard/blob/master/board/tasks.py#L17">un +fallback vers <span class="caps">CURL</span> lorsque les autres méthodes +échouent</a>. +Pas super propre, mais ça&nbsp;fonctionne.</p> +<p><strong><span class="caps">EDIT</span></strong> Finalement, il se trouve que mon serveur était mal configuré. +J&#8217;utilisais haproxy + stunnel, et la négiciation <span class="caps">SSL</span> se passait mal. Une +fois <span class="caps">SSL</span> et <span class="caps">TLS</span> activés, et SSLv2 désactivé, tout fonctionne&nbsp;mieux.</p> +<h2 id="et-voila">Et&nbsp;voilà</h2> +<p>Finalement, j&#8217;ai mon joli status-board qui tourne à merveille sur +<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Astuces SSH2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/astuces-ssh.html +<h2 id="tunelling">Tunelling</h2> +<p>Parce que je m&#8217;en rapelle jamais (tête de&nbsp;linote):</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>-f<span class="w"> </span>hote<span class="w"> </span>-L<span class="w"> </span>local:lolnet.org:destination<span class="w"> </span>-N +</code></pre></div> + +<h2 id="sshconfig">.ssh/config</h2> +<p>(merci <a href="http://majerti.fr">gaston</a>&nbsp;!)</p> +<p>La directive suivante dans .ssh/config permet de sauter d&#8217;hôte en hôte +séparés par des &#8220;+&#8221;&nbsp;:</p> +<div class="highlight"><pre><span></span><code>Host *+* + ProxyCommand ssh $(echo %h | sed +&#39;s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l …</code></pre></div> +<h2 id="tunelling">Tunelling</h2> +<p>Parce que je m&#8217;en rapelle jamais (tête de&nbsp;linote):</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>-f<span class="w"> </span>hote<span class="w"> </span>-L<span class="w"> </span>local:lolnet.org:destination<span class="w"> </span>-N +</code></pre></div> + +<h2 id="sshconfig">.ssh/config</h2> +<p>(merci <a href="http://majerti.fr">gaston</a>&nbsp;!)</p> +<p>La directive suivante dans .ssh/config permet de sauter d&#8217;hôte en hôte +séparés par des &#8220;+&#8221;&nbsp;:</p> +<div class="highlight"><pre><span></span><code>Host *+* + ProxyCommand ssh $(echo %h | sed +&#39;s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /&#39;) +PATH=.:\$PATH nc -w1 $(echo %h | sed &#39;s/^.*+//;/:/!s/$/ %p/;s/:/ /&#39;) +</code></pre></div> + +<p>On peut donc spécifier des &#8220;sauts&#8221; ssh du&nbsp;style:</p> +<div class="highlight"><pre><span></span><code><span class="n">ssh</span><span class="w"> </span><span class="n">root</span><span class="mf">@91.25.25.25</span><span class="o">+</span><span class="mf">192.168.1.1</span> +</code></pre></div> + +<p>Ensuite on peut essayer de&nbsp;rajouter:</p> +<div class="highlight"><pre><span></span><code>Host &lt;label_pour_mon_serveur_privé&gt; + user &lt;monuser(root)&gt; + IdentityFile &lt;chemin vers ma clé ssh pour le serveur publique&gt; + hostname ip_serveur_publique+ip_serveur_privé +</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html +<p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut +de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de +regarder du coté de gnome 3, à&nbsp;nouveau.</p> +<p>Et finalement, j&#8217;ai trouvé quelques extensions qui sont vraiment utiles, +que je …</p> +<p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut +de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de +regarder du coté de gnome 3, à&nbsp;nouveau.</p> +<p>Et finalement, j&#8217;ai trouvé quelques extensions qui sont vraiment utiles, +que je liste&nbsp;ici.</p> +<ul> +<li><a href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial + Menu</a> + vire les boutons et textes en rapport avec le web social. J&#8217;en avais + pas besoin puisque je suis connecté à mon instant messenger dans un + terminal, en utilisant&nbsp;weechat.</li> +<li><a href="https://extensions.gnome.org/extension/97/coverflow-alt-tab/">Coverflow + Alt-Tab</a> + change le switcher d&#8217;applications par defaut. Je le trouve bien plus + pratique que celui par defaut puisqu&#8217;il me permet de voir &#8220;en grand&#8221; + quelle est la fenêtre que je vais&nbsp;afficher.</li> +<li><a href="https://extensions.gnome.org/extension/55/media-player-indicator/">Media player + indicator</a> + me permet de voir en temps réel ce qui se passe dans mon lecteur + audio. Ça semble ne pas être grand chose, mais ça me manquait. Ça + s&#8217;intègre niquel avec Spotify, et ça c&#8217;est&nbsp;chouette.</li> +<li><a href="https://extensions.gnome.org/extension/149/search-firefox-bookmarks-provider/">Rechercher dans les bookmarks + firefox</a> + permet de… à votre avis&nbsp;?</li> +</ul> +<p>Un peu moins utile mais sait on&nbsp;jamais:</p> +<ul> +<li>“<a href="https://extensions.gnome.org/extension/130/advanced-settings-in-usermenu/">Advanced Settings in + UserMenu</a>” + permet d&#8217;avoir un raccourci vers les paramètres avancés dans le menu + utilisateur (en haut à&nbsp;droite)</li> +<li>Une <a href="https://extensions.gnome.org/extension/409/gtg-integration/">intégration à Getting things + Gnome</a> + (un truc de <span class="caps">GTD</span>). Je suis en train d&#8217;expérimenter avec cet outil, + donc je ne sais pas encore si ça va rester, mais pourquoi&nbsp;pas.</li> +</ul> +<p>Vous pouvez aller faire un tour sur <a href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> pour +en trouver d&#8217;autres à votre&nbsp;gout.</p>Cheese & code - Wrap-up2012-10-22T00:00:00+02:002012-10-22T00:00:00+02:00tag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.html +<p>This week-end I hosted a <em>cheese <span class="amp">&amp;</span> code</em> session in the country-side of +Angers,&nbsp;France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to +stay inside and to code.&nbsp;Bad.</p> +<p>We were not enough to get rid of all the cheese and the awesome …</p> +<p>This week-end I hosted a <em>cheese <span class="amp">&amp;</span> code</em> session in the country-side of +Angers,&nbsp;France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to +stay inside and to code.&nbsp;Bad.</p> +<p>We were not enough to get rid of all the cheese and the awesome meals, +but well, we finally managed it pretty&nbsp;well.</p> +<p>Here is a summary of what we worked&nbsp;on:</p> +<h2 id="daybed">Daybed</h2> +<p>Daybed started some time ago, and intend to be a replacement to google +forms, in term of features, but backed as a <span class="caps">REST</span> web service, in python, +and open&nbsp;source.</p> +<p>In case you wonder, daybed is effectively the name of a couch. We chose +this name because of the similarities (in the sound) with <strong>db</strong>, and +because we&#8217;re using <strong>CouchDB</strong> as a&nbsp;backend.</p> +<p><img alt="Daybed is a big couch!" src="/images/daybed.jpg"></p> +<p>We mainly hacked on daybed and are pretty close to the release of the +first version, meaning that we have something&nbsp;working.</p> +<p><a href="http://github.com/spiral-project/daybed">The code</a> is available on +github, and we also wrote <a href="http://daybed.rtfd.org">a small +documentation</a> for&nbsp;it.</p> +<p>Mainly, we did a lot of cleanup, rewrote a bunch of tests so that it +would be easier to continue to work on the project, and implemented some +minor features. I&#8217;m pretty confidend that we now have really good basis +for this&nbsp;project.</p> +<p>Also, we will have a nice todolist application, with the backend <strong>and</strong> +the frontend, in javascript / html / css, you&#8217;ll know more when it&#8217;ll be +ready&nbsp;:-)</p> +<p>Once we have something good enough, we&#8217;ll release the first version and +I&#8217;ll host it somewhere so that people can play with&nbsp;it.</p> +<h2 id="cornice">Cornice</h2> +<p>Daybed is built on top of <a href="http://cornice.rtfd.org">Cornice</a>, a +framework to ease the creation of&nbsp;web-services.</p> +<p>At Pycon France, we had the opportunity to attend a good presentation +about <a href="https://github.com/SPORE/specifications"><span class="caps">SPORE</span></a>. <span class="caps">SPORE</span> is a way +to describe your <span class="caps">REST</span> web services, as <span class="caps">WSDL</span> is for <span class="caps">WS</span>-* services. This +allows to ease the creation of generic <span class="caps">SPORE</span> clients, which are able to +consume any <span class="caps">REST</span> <span class="caps">API</span> with a <span class="caps">SPORE</span>&nbsp;endpoint.</p> +<p>Here is how you can let cornice describe your web service for&nbsp;you</p> +<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">cornice.ext.spore</span> <span class="kn">import</span> <span class="n">generate_spore_description</span> +<span class="kn">from</span> <span class="nn">cornice.service</span> <span class="kn">import</span> <span class="n">Service</span><span class="p">,</span> <span class="n">get_services</span> + +<span class="n">spore</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="s1">&#39;spore&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/spore&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s1">&#39;jsonp&#39;</span><span class="p">)</span> +<span class="nd">@spore</span><span class="o">.</span><span class="n">get</span> +<span class="k">def</span> <span class="nf">get_spore</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="n">services</span> <span class="o">=</span> <span class="n">get_services</span><span class="p">()</span> + <span class="k">return</span> <span class="n">generate_spore_description</span><span class="p">(</span><span class="n">services</span><span class="p">,</span> <span class="s1">&#39;Service name&#39;</span><span class="p">,</span> + <span class="n">request</span><span class="o">.</span><span class="n">application_url</span><span class="p">,</span> <span class="s1">&#39;1.0&#39;</span><span class="p">)</span> +</code></pre></div> + +<p>And you&#8217;ll get a definition of your service, in <span class="caps">SPORE</span>, available at&nbsp;/spore.</p> +<p>Of course, you can use it to do other things, like generating the file +locally and exporting it wherever it makes sense to you,&nbsp;etc.</p> +<p>I released today <a href="http://crate.io/packages/cornice/">Cornice 0.11</a>, +which adds into other things the support for <span class="caps">SPORE</span>, plus some other +fixes we found on our&nbsp;way.</p> +<h2 id="respire">Respire</h2> +<p>Once you have the description of the service, you can do generic clients +consuming&nbsp;them!</p> +<p>We first wanted to contribute to <a href="https://github.com/bl0b/spyre">spyre</a> +but it was written in a way that wasn&#8217;t supporting to <span class="caps">POST</span> data, and +they were using their own stack to handle <span class="caps">HTTP</span>. A lot of code that +already exists in other&nbsp;libraries.</p> +<p>While waiting the train with <a href="http://natim.ionyse.com/">Rémy</a>, we hacked +something together, named &#8220;Respire&#8221;, a thin layer on top of the awesome +<a href="http://python-requests.org">Requests</a>&nbsp;library.</p> +<p>We have a first version, feel free to have a look at it and provide +enhancements if you feel like it. We&#8217;re still hacking on it so it may +break (for the better), but that had been working pretty well for us so&nbsp;far.</p> +<p>You can <a href="http://github.com/spiral-project/respire">find the project on +github</a>, but here is how to +use it, really quickly (these examples are how to interact with&nbsp;daybed)</p> +<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">respire</span> <span class="kn">import</span> <span class="n">client_from_url</span> + +<span class="o">&gt;&gt;&gt;</span> <span class="c1"># create the client from the SPORE definition</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span> <span class="o">=</span> <span class="n">client_from_url</span><span class="p">(</span><span class="s1">&#39;http://localhost:8000/spore&#39;</span><span class="p">)</span> + +<span class="o">&gt;&gt;&gt;</span> <span class="c1"># in daybed, create a new definition</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">todo_def</span> <span class="o">=</span> <span class="p">{</span> +<span class="o">...</span> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;todo&quot;</span><span class="p">,</span> +<span class="o">...</span> <span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;A list of my stuff to do&quot;</span><span class="p">,</span> +<span class="o">...</span> <span class="s2">&quot;fields&quot;</span><span class="p">:</span> <span class="p">[</span> +<span class="o">...</span> <span class="p">{</span> +<span class="o">...</span> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;item&quot;</span><span class="p">,</span> +<span class="o">...</span> <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">,</span> +<span class="o">...</span> <span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;The item&quot;</span> +<span class="o">...</span> <span class="p">},</span> +<span class="o">...</span> <span class="p">{</span> +<span class="o">...</span> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;status&quot;</span><span class="p">,</span> +<span class="o">...</span> <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;enum&quot;</span><span class="p">,</span> +<span class="o">...</span> <span class="s2">&quot;choices&quot;</span><span class="p">:</span> <span class="p">[</span> +<span class="o">...</span> <span class="s2">&quot;done&quot;</span><span class="p">,</span> +<span class="o">...</span> <span class="s2">&quot;todo&quot;</span> +<span class="o">...</span> <span class="p">],</span> +<span class="o">...</span> <span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;is it done or not&quot;</span> +<span class="o">...</span> <span class="p">}</span> +<span class="o">...</span> <span class="p">]}</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span><span class="o">.</span><span class="n">put_definition</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">todo_def</span><span class="p">)</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span><span class="o">.</span><span class="n">post_data</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">item</span><span class="o">=</span><span class="s1">&#39;make it work&#39;</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">))</span> +<span class="p">{</span><span class="sa">u</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="sa">u</span><span class="s1">&#39;9f2c90c0529a442cfdc03c191b022cf7&#39;</span><span class="p">}</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span><span class="o">.</span><span class="n">get_data</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">)</span> +</code></pre></div> + +<p>Finally, we were out of cheese so everyone headed back to their +respective houses and&nbsp;cities.</p> +<p>Until next&nbsp;time?</p>Circus sprint at PyconFR2012-09-17T00:00:00+02:002012-09-17T00:00:00+02:00tag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.html +<p>Last Thursday to Sunday, <a href="http://pycon.fr">Pycon France</a> took place, in +Paris. It was the opportunity to meet a lot of people and to talk about +python awesomness in&nbsp;general.</p> +<p>We had three tracks this year, plus sprints the two first days. We +sprinted on <a href="http://circus.io">Circus</a>, the process and socket manager +we …</p> +<p>Last Thursday to Sunday, <a href="http://pycon.fr">Pycon France</a> took place, in +Paris. It was the opportunity to meet a lot of people and to talk about +python awesomness in&nbsp;general.</p> +<p>We had three tracks this year, plus sprints the two first days. We +sprinted on <a href="http://circus.io">Circus</a>, the process and socket manager +we&#8217;re using at Mozilla for some of our&nbsp;setups.</p> +<p>The project gathered some interest, and we ended up with 5 persons +working on it. Of course, we spent some time explaining what is Circus, +how it had been built, a lot of time talking about use-cases and +possible improvements, but we also managed to add new&nbsp;features.</p> +<p>Having people wanting to sprint on our projects is exciting because +that&#8217;s when making things in the open unleashes its full potential. You +can&#8217;t imagine how happy I was to have some friends come and work on this +with us&nbsp;:)</p> +<p>Here is a wrap-up of the&nbsp;sprint:</p> +<h2 id="autocompletion-on-the-command-line">Autocompletion on the&nbsp;command-line</h2> +<p><a href="http://natim.ionyse.com">Remy Hubscher</a> worked on the command-line +autocompletion. Now we have a fancy command-line interface which is able +to aucomplete if you&#8217;re using bash. It seems that not that much work is +needed to make it happen on zsh as well&nbsp;:)</p> +<p><a href="https://github.com/mozilla-services/circus/blob/master/extras/circusctl_bash_completion">Have a look at the&nbsp;feature</a></p> +<p>On the same topic, we now have a cool shell for Circus. If you start the +circusctl command without any option, you&#8217;ll end-up with a cool shell. +Thanks <a href="https://github.com/jojax">Jonathan Dorival</a> for the work on +this! You can have a look at <a href="https://github.com/mozilla-services/circus/pull/268">the pull +request</a>.</p> +<h2 id="future-changes-to-the-web-ui">Future changes to the web&nbsp;ui</h2> +<p><a href="https://twitter.com/rachbelaid">Rachid Belaid</a> had a deep look at the +source code and is much more familiarized to it now than before. We +discussed the possibility to change the implementation of the web ui, +and I&#8217;m glad of this. Currently, it&#8217;s done with bottle.py and we want to +switch to&nbsp;pyramid.</p> +<p>He fixed some issues that were in the tracker, so we now can have the +age of watchers in the webui, for&nbsp;instance.</p> +<h2 id="bug-and-doc-fixing">Bug and doc&nbsp;fixing</h2> +<p>While reading the source code, we found some inconsistencies and fixed +them, with <a href="http://mathieu.agopian.info/">Mathieu Agopian</a>. We also +tried to improve the documentation at different&nbsp;levels.</p> +<p>Documentation still needs a lot of love, and I&#8217;m planning to spend some +time on this shortly. I&#8217;ve gathered a bunch of feedback on&nbsp;this</p> +<h2 id="circus-clustering-capabilities">Circus clustering&nbsp;capabilities</h2> +<p>One feature I wanted to work on during this sprint was the clustering +abilities of Circus. Nick Pellegrino made an internship on this topic at +Mozilla so we spent some time to review his pull&nbsp;requests.</p> +<p>A lot of code was written for this so we discussed a bunch of things +regarding all of this. It took us more time than expected (and I still +need to spend more time on this to provide appropriate feedback), but it +allowed us to have a starting-point about what this clustering thing +could&nbsp;be.</p> +<p>Remy wrote <a href="http://tech.novapost.fr/circus-clustering-management-en.html">a good summary about our +brainstorming</a> +so I&#8217;ll not do it again here, but feel free to contact us if you have +ideas on this, they&#8217;re very&nbsp;welcome!</p> +<h2 id="project-management">Project&nbsp;management</h2> +<p>We&#8217;ve had some inquiries telling us that&#8217;s not as easy as it should to +get started with the Circus project. Some of the reasons are that we +don&#8217;t have any release schedule, and that the documentation is hairy +enough to lost people, at some point&nbsp;:)</p> +<p>That&#8217;s something we&#8217;ll try to fix soon&nbsp;:)</p> +<p>PyconFR was a very enjoyable event. I&#8217;m looking forward to meet the +community again and discuss how Circus can evolve in ways that are +interesting to&nbsp;everyone.</p> +<p>Tarek and me are going to <a href="http://python.ie/pycon/2012/">Pycon ireland</a>, +feel free to reach us if you&#8217;re going there, we&#8217;ll be happy to meet and +enjoy&nbsp;beers!</p>Refactoring Cornice2012-05-01T00:00:00+02:002012-05-01T00:00:00+02:00tag:blog.notmyidea.org,2012-05-01:/refactoring-cornice.html +<p>After working for a while with <a href="http://cornice.readthedocs.com">Cornice</a> +to define our APIs at <a href="http://docs.services.mozilla.com">Services</a>, it +turned out that the current implementation wasn&#8217;t flexible enough to +allow us to do what we wanted to&nbsp;do.</p> +<p>Cornice started as a toolkit on top of the +<a href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> +routing system, allowing to register services …</p> +<p>After working for a while with <a href="http://cornice.readthedocs.com">Cornice</a> +to define our APIs at <a href="http://docs.services.mozilla.com">Services</a>, it +turned out that the current implementation wasn&#8217;t flexible enough to +allow us to do what we wanted to&nbsp;do.</p> +<p>Cornice started as a toolkit on top of the +<a href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> +routing system, allowing to register services in a simpler way. Then we +added some niceties such as the ability to automatically generate the +services documentation or returning the correct <span class="caps">HTTP</span> headers <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">as defined +by the <span class="caps">HTTP</span> +specification</a> +without the need from the developer to deal with them nor to know&nbsp;them.</p> +<p>If you&#8217;re not familiar with Cornice, here is how you define a simple +service with&nbsp;it:</p> +<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">cornice.service</span> <span class="kn">import</span> <span class="n">Service</span> +<span class="n">bar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s2">&quot;/bar&quot;</span><span class="p">)</span> + +<span class="nd">@bar</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validators</span><span class="o">=</span><span class="n">validators</span><span class="p">,</span> <span class="n">accept</span><span class="o">=</span><span class="s1">&#39;application/json&#39;</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">get_drink</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="c1"># do something with the request (with moderation).</span> +</code></pre></div> + +<p>This external <span class="caps">API</span> is quite cool, as it allows to do a bunch of things +quite easily. For instance, we&#8217;ve written our +<a href="https://github.com/mozilla-services/tokenserver">token-server</a> code on +top of this in a&nbsp;blast.</p> +<h2 id="the-burden">The&nbsp;burden</h2> +<p>The problem with this was that we were mixing internally the service +description logic with the route registration one. The way we were doing +this was via an extensive use of decorators&nbsp;internally.</p> +<p>The <span class="caps">API</span> of the cornice.service.Service class was as following +(simplified so you can get the gist of&nbsp;it).</p> +<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">Service</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> + + <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">service_kwargs</span><span class="p">):</span> + <span class="c1"># some information, such as the colander schemas (for validation),</span> + <span class="c1"># the defined methods that had been registered for this service and</span> + <span class="c1"># some other things were registered as instance variables.</span> + <span class="bp">self</span><span class="o">.</span><span class="n">schemas</span> <span class="o">=</span> <span class="n">service_kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">schema</span><span class="s1">&#39;, None)</span> + <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span> <span class="o">=</span> <span class="p">[]</span> + <span class="bp">self</span><span class="o">.</span><span class="n">definitions</span> <span class="o">=</span> <span class="p">[]</span> + + <span class="k">def</span> <span class="nf">api</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">view_kwargs</span><span class="p">):</span> +<span class="w"> </span><span class="sd">&quot;&quot;&quot;This method is a decorator that is being used by some alias</span> +<span class="sd"> methods.</span> +<span class="sd"> &quot;&quot;&quot;</span> + <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="n">view</span><span class="p">):</span> + <span class="c1"># all the logic goes here. And when I mean all the logic, I</span> + <span class="c1"># mean it.</span> + <span class="c1"># 1. we are registering a callback to the pyramid routing</span> + <span class="c1"># system so it gets called whenever the module using the</span> + <span class="c1"># decorator is used.</span> + <span class="c1"># 2. we are transforming the passed arguments so they conform</span> + <span class="c1"># to what is expected by the pyramid routing system.</span> + <span class="c1"># 3. We are storing some of the passed arguments into the</span> + <span class="c1"># object so we can retrieve them later on.</span> + <span class="c1"># 4. Also, we are transforming the passed view before</span> + <span class="c1"># registering it in the pyramid routing system so that it</span> + <span class="c1"># can do what Cornice wants it to do (checking some rules,</span> + <span class="c1"># applying validators and filters etc.</span> + <span class="k">return</span> <span class="n">wrapper</span> + + <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> +<span class="w"> </span><span class="sd">&quot;&quot;&quot;A shortcut of the api decorator&quot;&quot;&quot;</span> + <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">api</span><span class="p">(</span><span class="n">request_method</span><span class="o">=</span><span class="s2">&quot;GET&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> +</code></pre></div> + +<p>I encourage you to go read <a href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/service.py#L44">the entire +file</a>. +on github so you can get a better opinion on how all of this was&nbsp;done.</p> +<p>A bunch of things are&nbsp;wrong:</p> +<ul> +<li>first, we are not separating the description logic from the + registration one. This causes problems when we need to access the + parameters passed to the service, because the parameters you get are + not exactly the ones you passed but the ones that the pyramid + routing system is expecting. For instance, if you want to get the + view get_drink, you will instead get a decorator which contains + this&nbsp;view.</li> +<li>second, we are using decorators as APIs we expose. Even if + decorators are good as shortcuts, they shouldn&#8217;t be the default way + to deal with an <span class="caps">API</span>. A good example of this is <a href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/resource.py#L56">how the resource + module consumes this + <span class="caps">API</span></a>. + This is quite hard to&nbsp;follow.</li> +<li>Third, in the api method, a bunch of things are done regarding + inheritance of parameters that are passed to the service or to its + decorator methods. This leaves you with a really hard to follow path + when it comes to add new parameters to your <span class="caps">API</span>.</li> +</ul> +<h2 id="how-do-we-improve-this">How do we improve&nbsp;this?</h2> +<p>Python is great because it allows you to refactor things in an easy way. +What I did isn&#8217;t breaking our APIs, but make things way simpler to +hack-on. One example is that it allowed me to add features that we +wanted to bring to Cornice really quickly (a matter of minutes), without +touching the <span class="caps">API</span> that&nbsp;much.</p> +<p>Here is the gist of the new&nbsp;architecture:</p> +<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">Service</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> + <span class="c1"># we define class-level variables that will be the default values for</span> + <span class="c1"># this service. This makes things more extensible than it was before.</span> + <span class="n">renderer</span> <span class="o">=</span> <span class="s1">&#39;simplejson&#39;</span> + <span class="n">default_validators</span> <span class="o">=</span> <span class="n">DEFAULT_VALIDATORS</span> + <span class="n">default_filters</span> <span class="o">=</span> <span class="n">DEFAULT_FILTERS</span> + + <span class="c1"># we also have some class-level parameters that are useful to know</span> + <span class="c1"># which parameters are supposed to be lists (and so converted as such)</span> + <span class="c1"># or which are mandatory.</span> + <span class="n">mandatory_arguments</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;renderer&#39;</span><span class="p">,)</span> + <span class="n">list_arguments</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;validators&#39;</span><span class="p">,</span> <span class="s1">&#39;filters&#39;</span><span class="p">)</span> + + <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span> + <span class="c1"># setup name, path and description as instance variables</span> + <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span> + <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span> + <span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">description</span> + + <span class="c1"># convert the arguments passed to something we want to store</span> + <span class="c1"># and then store them as attributes of the instance (because they</span> + <span class="c1"># were passed to the constructor</span> + <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_arguments</span><span class="p">(</span><span class="n">kw</span><span class="p">)</span> + <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> + <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> + + <span class="c1"># we keep having the defined_methods tuple and the list of</span> + <span class="c1"># definitions that are done for this service</span> + <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span> <span class="o">=</span> <span class="p">[]</span> + <span class="bp">self</span><span class="o">.</span><span class="n">definitions</span> <span class="o">=</span> <span class="p">[]</span> + + <span class="k">def</span> <span class="nf">get_arguments</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conf</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> +<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a dict of arguments. It does all the conversions for</span> +<span class="sd"> you, and uses the information that were defined at the instance</span> +<span class="sd"> level as fallbacks.</span> +<span class="sd"> &quot;&quot;&quot;</span> + + <span class="k">def</span> <span class="nf">add_view</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> +<span class="w"> </span><span class="sd">&quot;&quot;&quot;Add a view to this service.&quot;&quot;&quot;</span> + <span class="c1"># this is really simple and looks a lot like this</span> + <span class="n">method</span> <span class="o">=</span> <span class="n">method</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> + <span class="bp">self</span><span class="o">.</span><span class="n">definitions</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">method</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="n">args</span><span class="p">))</span> + <span class="k">if</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span><span class="p">:</span> + <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">method</span><span class="p">)</span> + + <span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> +<span class="w"> </span><span class="sd">&quot;&quot;&quot;This is only another interface to the add_view method, exposing a</span> +<span class="sd"> decorator interface&quot;&quot;&quot;</span> + <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="n">view</span><span class="p">):</span> + <span class="bp">self</span><span class="o">.</span><span class="n">add_view</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> + <span class="k">return</span> <span class="n">view</span> + <span class="k">return</span> <span class="n">wrapper</span> +</code></pre></div> + +<p>So, the service is now only storing the information that&#8217;s passed to it +and nothing more. No more route registration logic goes here. Instead, I +added this as another feature, even in a different module. The function +is named register_service_views and has the following&nbsp;signature:</p> +<div class="highlight"><pre><span></span><code><span class="n">register_service_views</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">service</span><span class="p">)</span> +</code></pre></div> + +<p>To sum up, here are the changes I&nbsp;made:</p> +<ol> +<li>Service description is now separated from the route&nbsp;registration.</li> +<li>cornice.service.Service now provides a hook_view method, which is + not a decorator. decorators are still present but they are optional + (you don&#8217;t need to use them if you don&#8217;t want&nbsp;to).</li> +<li>Everything has been decoupled as much as possible, meaning that you + really can use the Service class as a container of information about + the services you are describing. This is especially useful when + generating&nbsp;documentation.</li> +</ol> +<p>As a result, it is now possible to use Cornice with other frameworks. It +means that you can stick with the service description but plug any other +framework on top of it. cornice.services.Service is now only a +description tool. To register routes, one would need to read the +information contained into this service and inject the right parameters +into their preferred routing&nbsp;system.</p> +<p>However, no integration with other frameworks is done at the moment even +if the design allows&nbsp;it.</p> +<p>The same way, the sphinx description layer is now only a consumer of +this service description tool: it looks at what&#8217;s described and build-up +the documentation from&nbsp;it.</p> +<p>The resulting branch is not merged yet. Still, you can <a href="https://github.com/mozilla-services/cornice/tree/refactor-the-world">have a look at +it</a>.</p> +<p>Any suggestions are of course welcome&nbsp;:-)</p>Djangocong 20122012-04-16T00:00:00+02:002012-04-16T00:00:00+02:00tag:blog.notmyidea.org,2012-04-16:/djangocong-2012.html +<p>Ce week-end, c&#8217;était <a href="http://rencontres.django-fr.org">djangocong</a>, une +conférence autour de <a href="http://djangoproject.org">django</a>, de +<a href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à +Carnon-plage, à quelques kilomètres de Montpellier la&nbsp;belle.</p> +<p>J&#8217;ai vraiment apprécié les trois jours passés avec cette bande de geeks. +Je m&#8217;attendais à des <em>nerds</em>, j …</p> +<p>Ce week-end, c&#8217;était <a href="http://rencontres.django-fr.org">djangocong</a>, une +conférence autour de <a href="http://djangoproject.org">django</a>, de +<a href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à +Carnon-plage, à quelques kilomètres de Montpellier la&nbsp;belle.</p> +<p>J&#8217;ai vraiment apprécié les trois jours passés avec cette bande de geeks. +Je m&#8217;attendais à des <em>nerds</em>, j&#8217;y ai trouvé une qualité d&#8217;écoute, des +personnes qui partagent des valeurs qui leur sont chères, mais qui ne +limitent pas leurs discussions à du technique. Eeeh ouais, encore un +préjugé qui tombe, tiens&nbsp;:)</p> +<p>En tant que <em>hackers</em>, on a le moyen de créer des outils qui sont utiles +à tous, et qui peuvent être utiles pour favoriser la collaboration et la +mise en commun des données. J&#8217;ai eu l&#8217;occasion de discuter de projets +tournant autour de l&#8217;entraide, que ça soit pour mettre en lien des +associations d&#8217;économie sociale et solidaire (<span class="caps">ESS</span>) ou simplement pour +que les populations <em>non tech</em> <a href="http://blog.notmyidea.org/quels-usages-pour-linformatique-fr.html">puissent utiliser toute la puissance de +l&#8217;outil qu&#8217;est le +web</a>.</p> +<p>Au niveau du format des conférences, je ne savais pas trop à quoi +m&#8217;attendre, au vu des échos de l&#8217;an dernier, mais c&#8217;était adapté: des +mini-confs de 12mn le samedi matin + début d&#8217;aprem, en mode no-wifi pour +récupérer une qualité d&#8217;écoute. Et contrairement à mes attentes, ce +n&#8217;est pas trop court. Pas mal de retours d&#8217;expérience pour le coup, et +une matinée pas vraiment techniques, mais ça pose le décor et permet de +savoir qui fait&nbsp;quoi.</p> +<p>Parmi l&#8217;ensemble des conférences du matin, je retiens principalement +celle de Mathieu Leplatre, &#8220;des cartes d&#8217;un autre monde&#8221;, qui m&#8217;a +réellement bluffée quand à la facilité de créer des cartes avec +<a href="http://mapbox.com/tilemill/">TileMill</a>, et qui me pousse à reconsidérer +le fait que &#8220;la carto, c&#8217;est compliqué&#8221;. <a href="https://www.youtube.com/watch?v=7NPQo54NbJ8">La vidéo est (déja !) +disponible en ligne</a>, je +vous invite à la regarder (c&#8217;est une 15aine de minutes) pour vous faire +un avis&nbsp;;)</p> +<p>Une fois les conf passées, ça reste très intéressant, voire plus: il +reste un jour et demi pour discuter avec les autres présents. On a pu se +retrouver avec Mathieu pour discuter de &#8220;notre&#8221; projet <a href="http://blog.notmyidea.org/carto-forms-fr.html">&#8220;carto +forms&#8221;</a>, qui à finalement +pu se redéfinir un peu plus et donner naissance à un +<a href="https://github.com/spiral-project/daybed/blob/master/README.rst"><span class="caps">README</span></a>. +On en à profité pour lui choisir un nouveau nom: &#8220;daybed&#8221;, en référence +à&nbsp;couchdb.</p> +<p>Ça devrait se transformer en code d&#8217;ici peu. La curiosité aidant, on a +pu discuter du projet avec d&#8217;autres personnes et affiner les attentes de +chacun pour finalement arriver à quelque chose d&#8217;assez&nbsp;sympathique.</p> +<p>J&#8217;ai aussi pu me rendre compte que pas mal de monde utilise +<a href="http://pelican.notmyidea.org">pelican</a>, le bout de code que j&#8217;ai codé +pour générer ce blog, et avoir des retours utiles ! Probablement des +réflexions à venir sur comment éviter qu&#8217;un projet open-source ne +devienne chronophage, et sur comment réussir à garder une qualité dans +le code source tout en ne froissant pas les&nbsp;contributeurs.</p> +<p>Bien évidemment, c&#8217;était aussi l&#8217;occaz de rencontrer des gens qu&#8217;on ne +voir que sur les inter-nets, et de discuter un brin de tout ce qui fait +que notre monde est chouette et moins&nbsp;chouette.</p> +<p>Entres autres faits notoires, JMad a perdu au baby-foot face à Exirel, +même en m&#8217;ayant à ses cotés pour le déconcentrer (et je suis un joueur +d&#8217;un autre monde - en d&#8217;autres termes, je suis nul), David`bgk ne s&#8217;est +pas levé pour aller courir le dimanche matin (il avait dit 5 heures!), +Les suisses ont essayé de me convertir à coup d&#8217;abricotine, j&#8217;ai perdu +au skulls-n-roses en quelques tours et on a allumé un feu chez Stéphane +le dimanche soir (oui oui, à montpellier, mi avril, je vous le dis +qu&#8217;ils mentent avec leur soit disant&nbsp;soleil).</p> +<p>Et c&#8217;est sans parler de <a href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la +brasucade</a>&nbsp;…</p> +<p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une +présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html +<p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> +<p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même +chose, à quelques détails près: une page web avec un formulaire qui +permettrait de soumettre des informations géographiques, lié à une carte +et des manières de filtrer&nbsp;l&#8217;information …</p> +<p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> +<p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même +chose, à quelques détails près: une page web avec un formulaire qui +permettrait de soumettre des informations géographiques, lié à une carte +et des manières de filtrer&nbsp;l&#8217;information.</p> +<p>L&#8217;idée fait son bout de chemin, et je commence à penser qu&#8217;on peut même +avoir quelque chose de vraiment flexible et utile. J&#8217;ai nommé le projet +<em>carto-forms</em> pour l&#8217;instant (mais c&#8217;est uniquement un nom de&nbsp;code).</p> +<p>Pour résumer: et si on avait un moyen de construire des formulaires, un +peu comme Google forms, mais avec des informations géographiques en&nbsp;plus?</p> +<p>Si vous ne connaissez pas Google forms, il s&#8217;agit d&#8217;une interface simple +d&#8217;utilisation pour générer des formulaires et récupérer des informations +depuis ces&nbsp;derniers.</p> +<p>Google forms est un super outil mais à mon avis manque deux choses +importantes: premièrement, il s&#8217;agit d&#8217;un outil propriétaire (oui, on +peut aussi dire privateur) et il n&#8217;est donc pas possible de le hacker un +peu pour le faire devenir ce qu&#8217;on souhaite, ni l&#8217;installer sur notre +propre serveur. Deuxièmement, il ne sait pas vraiment fonctionner avec +des informations géographiques, et il n&#8217;y à pas d&#8217;autre moyen de filtrer +les informations que l&#8217;utilisation de leur système de feuilles de&nbsp;calcul.</p> +<p>Après avoir réfléchi un petit peu à ça, j&#8217;ai contacté +<a href="http://blog.mathieu-leplatre.info/">Mathieu</a> et les anciens collègues +de chez <a href="http://makina-corpus.com">Makina Corpus</a>, puisque les projets +libres à base de carto sont à même de les&nbsp;intéresser.</p> +<p>Imaginez le cas&nbsp;suivant:</p> +<ol> +<li>Dans une &#8220;mapping party&#8221;, on choisit un sujet particulier à + cartographier et on design un formulaire (liste des champs (tags) a + remplir + description + le type d&#8217;information)&nbsp;;</li> +<li>Sur place, les utilisateurs remplissent les champs du formulaire + avec ce qu&#8217;ils voient. Les champs géolocalisés peuvent être remplis + automatiquement avec la géolocalisation du téléphone&nbsp;;</li> +<li>À la fin de la journée, il est possible de voir une carte des + contributions, avec le formulaire choisi&nbsp;;</li> +<li>Un script peut importer les résultats et les publier vers&nbsp;OpenStreetMap.</li> +</ol> +<h2 id="quelques-cas-dutilisation">Quelques cas&nbsp;d&#8217;utilisation</h2> +<p>J&#8217;arrive à imaginer différents cas d&#8217;utilisation pour cet outil. Le +premier est celui que j&#8217;ai approximativement décrit plus haut: la +génération de cartes de manière collaborative, avec des filtres à +facettes. Voici un flux d&#8217;utilisation&nbsp;général:</p> +<ul> +<li> +<p>Un &#8220;administrateur&#8221; se rend sur le site web et crée un nouveau + formulaire pour l&#8217;ensemble des évènements alternatifs. Il crée les + champs&nbsp;suivants:</p> +<ul> +<li>Nom: le champ qui contient le nom de&nbsp;l&#8217;évènement.</li> +<li>Catégorie: la catégorie de l&#8217;évènement (marche, concert, + manifestation…). Il peut s&#8217;agir d&#8217;un champ à multiples&nbsp;occurrences.</li> +<li>Le lieu de l&#8217;évènement. Celui-ci peut être donné soit par une + adresse soit en sélectionnant un point sur une&nbsp;carte.</li> +<li>Date: la date de l&#8217;évènement (un &#8220;date picker&#8221; peut permettre + cela&nbsp;facilement)</li> +</ul> +<p>Chaque champ dans le formulaire a des informations sémantiques +associées (oui/non, multiple sélection, date, heure, champ géocodé, +sélection carto,&nbsp;etc.)</p> +</li> +<li> +<p>Une fois terminé, le formulaire est généré et une <span class="caps">URL</span> permet d&#8217;y + accéder. (par exemple <a href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>).</p> +</li> +<li> +<p>Une <span class="caps">API</span> <span class="caps">REST</span> permet à d&#8217;autres applications d&#8217;accéder aux + informations et d&#8217;en ajouter / modifier de&nbsp;nouvelles.</p> +</li> +<li> +<p>Il est maintenant possible de donner l&#8217;<span class="caps">URL</span> à qui voudra en faire bon + usage. N&#8217;importe qui peut ajouter des informations. On peut + également imaginer une manière de modérer les modifications si + besoin&nbsp;est.</p> +</li> +<li> +<p>Bien sur, la dernière phase est la plus intéressante: il est + possible de filtrer les informations par lieu, catégorie ou date, le + tout soit via une <span class="caps">API</span> <span class="caps">REST</span>, soit via une jolie carte et quelques + contrôles bien placés, dans le&nbsp;navigateur.</p> +</li> +</ul> +<p>Vous avez dû remarquer que le processus de création d&#8217;un formulaire est +volontairement très simple. L&#8217;idée est que n&#8217;importe qui puisse créer +des cartes facilement, en quelques clics. Si une <span class="caps">API</span> bien pensée suit, +on peut imaginer faire de la validation coté serveur et même faire des +applications pour téléphone assez&nbsp;simplement.</p> +<p>Pour aller un peu plus loin, si on arrive à penser un format de +description pour le formulaire, il sera possible de construire les +formulaires de manière automatisée sur différentes plateformes et +également sur des clients&nbsp;génériques.</p> +<p>On imagine pas mal d&#8217;exemples pour ce projet: des points de recyclage, +les endroits accessibles (pour fauteuils roulants etc.), identification +des arbres, bons coins à champignons, recensement des espèces en voie de +disparition (l&#8217;aigle de Bonelli est actuellement suivi en utilisant une +feuille de calcul partagée !), suivi des espèces dangereuses (le frelon +asiatique par exemple), cartographier les points d&#8217;affichage +publicitaires, participation citoyenne (graffitis, nids de poule, voir +<a href="http://fixmystreet.ca">http://fixmystreet.ca</a>), geocaching, trajectoires (randonnées, +coureurs,&nbsp;cyclistes)…</p> +<p>Voici quelques exemples où ce projet pourrait être utile (la liste n&#8217;est +pas&nbsp;exhaustive):</p> +<h3 id="un-backend-sig-simple-a-utiliser">Un backend <span class="caps">SIG</span> simple à&nbsp;utiliser</h3> +<p>Disons que vous êtes développeur mobile. Vous ne voulez pas vous +encombrer avec PostGIS ou écrire du code spécifique pour récupérer et +insérer des données <span class="caps">SIG</span>! Vous avez besoin de <em>Carto-Forms</em>! Une <span class="caps">API</span> +simple vous aide à penser vos modèles et vos formulaires, et cette même +<span class="caps">API</span> vous permet d&#8217;insérer et de récupérer des données. Vous pouvez vous +concentrer sur votre application et non pas sur la manière dont les +données géographiques sont stockées et&nbsp;gérées.</p> +<p>En d&#8217;autres termes, vous faites une distinction entre le stockage des +informations et leur&nbsp;affichage.</p> +<p>Si vous êtes un développeur django, plomino, drupal etc. vous pouvez +développer un module pour &#8220;plugger&#8221; vos modèles et votre interface +utilisateur avec celle de <em>Carto-Forms</em>. De cette manière, il est +possible d&#8217;exposer les formulaires aux utilisateurs de vos backoffices. +De la même manière, il est possible d&#8217;écrire des widgets qui consomment +des données et les affichent (en utilisant par exemple une bibliothèque +javascript de&nbsp;webmapping).</p> +<h3 id="un-outil-de-visualisation">Un outil de&nbsp;visualisation</h3> +<p>Puisque les données peuvent être proposées de manière automatisée en +utilisant l&#8217;<span class="caps">API</span>, vous pouvez utiliser la page de résultat de Carto-forms +comme un outil de&nbsp;visualisation.</p> +<p>Il est possible d&#8217;explorer mon jeu de données en utilisant des filtres +sur chacun des champs. La recherche à facettes peut être une idée pour +faciliter ce filtrage. Une carte affiche le résultat. Vous avez +l&#8217;impressoin d&#8217;être en face d&#8217;un système d&#8217;aide à la décision&nbsp;!</p> +<p>Évidemment, il est possible de télécharger les données brutes (geojson, +xml). Idéalement, le mieux serait d&#8217;obtenir ces données filtrées +directement depuis une <span class="caps">API</span> Web, et un lien permet de partager la page +avec l&#8217;état des filtres et le niveau de zoom / la localisation de la&nbsp;carte.</p> +<h3 id="un-service-generique-pour-gerer-les-formulaires">Un service générique pour gérer les&nbsp;formulaires</h3> +<p>Si vous souhaitez générer un fichier de configuration (ou ce que vous +voulez, messages emails, …) vous aurez besoin d&#8217;un formulaire et d&#8217;un +template pour injecter les données proposées par les utilisateurs et +récupérer un&nbsp;résultat.</p> +<p>Un service de gestion des formulaires pourrait être utile pour créer des +formulaires de manière automatique et récupérer les données &#8220;nettoyées&#8221; +et&nbsp;&#8220;validées&#8221;.</p> +<p>On peut imaginer par exemple l&#8217;utilisation d&#8217;un système de templates +externe reposant sur <em>carto-forms</em>. Celui-ci &#8220;parserait&#8221; le contenu des +templates et pourrait le lier aux informations ajoutées par les +utilisateurs via un&nbsp;formulaire.</p> +<p>Pour ce cas particulier, il n&#8217;y a pas besoin d&#8217;informations +géographiques (<span class="caps">SIG</span>). Il s&#8217;agit quasiment du service proposé +actuellement par Google&nbsp;forms.</p> +<h2 id="ca-nexiste-pas-deja-tout-ca">Ça n&#8217;existe pas déjà tout ça&nbsp;?</h2> +<p>Bien sur, il y a Google forms, qui vous permet de faire ce genre de +choses, mais comme je l&#8217;ai précisé plus haut, il ne s&#8217;agit pas +exactement de la même&nbsp;chose.</p> +<p>Nous avons découvert <a href="https://webform.com">https://webform.com</a> qui permet de créer des +formulaires avec un système de drag&#8217;n&#8217;drop. J&#8217;adorerais reproduire +quelque chose de similaire pour l&#8217;interface utilisateur. Par contre ce +projet ne gère pas les appels via <span class="caps">API</span> et les informations de +géolocalisation&nbsp;…</p> +<p>L&#8217;idée de <a href="http://thoth.io">http://thoth.io</a> est également assez sympathique: une api +très simple pour stocker et récupérer des données. En plus de ça, +<em>carto-forms</em> proposerait de la validation de données et proposerait un +support des points <span class="caps">SIG</span> (point, ligne,&nbsp;polygone).</p> +<p><a href="http://mapbox.com">http://mapbox.com</a> fait également un superbe travail autour de la +cartographie, mais ne prends pas en compte le coté auto-génération de&nbsp;formulaires…</p> +<h2 id="on-est-parti">On est parti&nbsp;?!</h2> +<p>Comme vous avez pu vous en rendre compte, il ne s&#8217;agit pas d&#8217;un problème +outrageusement complexe. On a pas mal discuté avec Mathieu, à propos de +ce qu&#8217;on souhaite faire et du comment. Il se trouve qu&#8217;on peut sûrement +s&#8217;en sortir avec une solution élégante sans trop de problèmes. Mathieu +est habitué à travailler autour des projets de <span class="caps">SIG</span> (ce qui est parfait +parce que ce n&#8217;est pas mon cas) et connaît son sujet. Une bonne +opportunité&nbsp;d&#8217;apprendre!</p> +<p>On sera tous les deux à <a href="http://rencontres.django-fr.org">Djangocong</a> le +14 et 15 Avril, et on prévoit une session de <em>tempête de cerveau</em> et un +sprint sur ce projet. Si vous êtes dans le coin et que vous souhaitez +discuter ou nous filer un coup de patte, n&#8217;hésitez&nbsp;pas!</p> +<p>On ne sait pas encore si on utilisera django ou quelque chose d&#8217;autre. +On a pensé un peu à CouchDB, son système de couchapps et geocouch, mais +rien n&#8217;est encore gravé dans le marbre ! N&#8217;hésitez pas à proposer vos +solutions ou&nbsp;suggestions.</p> +<p>Voici le document etherpad sur lequel on a travaillé jusqu&#8217;à maintenant: +<a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. N&#8217;hésitez pas à l&#8217;éditer et à ajouter +vos commentaires, c&#8217;est son&nbsp;objectif!</p> +<p>Merci à <a href="http://sneakernet.fr/">Arnaud</a> pour la relecture et la +correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html +<p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> +<p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> +<p>A bunch of friends asked me twice for quite the same thing: a webpage +with a form, tied to a map generation with some information filtering. +They didn&#8217;t explicitly ask that but that&#8217;s the …</p> +<p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> +<p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> +<p>A bunch of friends asked me twice for quite the same thing: a webpage +with a form, tied to a map generation with some information filtering. +They didn&#8217;t explicitly ask that but that&#8217;s the gist of&nbsp;it.</p> +<p>This idea has been stuck in my head since then and I even think that we +can come out with something a little bit more flexible and useful. I&#8217;ve +named it <em>carto-forms</em> for now, but that&#8217;s only the&nbsp;&#8220;codename&#8221;.</p> +<p>To put it shortly: what if we had a way to build forms, ala Google +forms, but with geographic information in&nbsp;them?</p> +<p>If you don&#8217;t know Google forms, it means having an user-friendly way to +build forms and to use them to gather information from different&nbsp;users.</p> +<p>In my opinion, Google forms is missing two important things: first, it&#8217;s +not open-source, so it&#8217;s not possible to hack it or even to run it on +your own server. Second, it doesn&#8217;t really know how to deal with +geographic data, and there is no way to filter the information more than +in a&nbsp;spreadsheet.</p> +<p>I knew that <a href="http://blog.mathieu-leplatre.info/">Mathieu</a> and some folks +at <a href="http://makina-corpus.com">Makina Corpus</a> would be interested in +this, so I started a discussion with him on <span class="caps">IRC</span> and we refined the +details of the project and its&nbsp;objectives.</p> +<p>Imagine the&nbsp;following:</p> +<ol> +<li>For a mapping party, we choose a specific topic to map and design + the form (list of fields (i.e. tags) to be filled + description + + type of the information)&nbsp;;</li> +<li>In situ, users fill the form fields with what they see. Geo fields + can be pre-populated using device geolocation&nbsp;;</li> +<li>At the end of the day, we can see a map with all user contributions + seized through this particular form&nbsp;;</li> +<li>If relevant, a script could eventually import the resulting dataset + and publish/merge with&nbsp;OpenStreetMap.</li> +</ol> +<h2 id="some-use-cases">Some use&nbsp;cases</h2> +<p>I can see some use cases for this. The first one is a collaborative map, +with facet filtering. Let&#8217;s draw a potential user&nbsp;flow:</p> +<ul> +<li> +<p>An &#8220;administrator&#8221; goes to the website and creates a form to list + all the alternative-related events. He creates the following&nbsp;fields:</p> +<ul> +<li>Name: a plain text field containing the name of the&nbsp;event.</li> +<li>Category: the category of the event. Can be a finite&nbsp;list.</li> +<li>Location: The location of the event. It could be provided by + selecting a point on a map or by typing an&nbsp;address.</li> +<li>Date: the date of the event (a datepicker could do the&nbsp;trick)</li> +</ul> +<p>Each field in the form has semantic information associated with it +(yes/no, multiple selection, date-time, geocoding carto, carto +selection&nbsp;etc)</p> +</li> +<li> +<p>Once finished, the form is generated and the user gets an url (say + <a href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>) for&nbsp;it.</p> +</li> +<li> +<p><span class="caps">REST</span> APIs allow third parties to get the form description and to + push/edit/get information from&nbsp;there.</p> +</li> +<li> +<p>He can communicate the address in any way he wants to his community + so they can go to the page and add information to&nbsp;it.</p> +</li> +<li> +<p>Then, it is possible to filter the results per location / date or + category. This can be done via <span class="caps">API</span> calls (useful for third parties) + or via a nice interface in the&nbsp;browser.</p> +</li> +</ul> +<p>So, as you may have noticed, this would allow us to create interactive +maps really easily. It&#8217;s almost just a matter of some clicks to the +users. If we also come up with a nice Web <span class="caps">API</span> for this, we could do +server-side validation and build even phone applications&nbsp;easily.</p> +<p>To push the cursor a bit further, if we can come with a cool description +format for the forms, we could even build the forms dynamically on +different platforms, with generic&nbsp;clients.</p> +<p>As mentioned before, the idea of a simple tool to support collaborative +mapping fullfils a recurring necessity&nbsp;!</p> +<p>We envision a lot of example uses for this : recycling spots, accessible +spots (wheelchairs, etc.), trees identification, mushrooms picking +areas, tracking of endangered species (e.g. Bonelli&#8217;s Eagle is currently +tracked by sharing a spreadsheet), spotting of dangerous species (e.g. +asian predatory wasps), map advertisement boards (most cities do not +track them!), citizen reporting (e.g. graffiti, potholes, garbage, +lightning like <a href="http://fixmystreet.ca">http://fixmystreet.ca</a>), geocaching, trajectories (e.g +hiking, runners,&nbsp;cyclists)&#8230;</p> +<p>Here are some other examples of where <em>carto-forms</em> could be&nbsp;useful:</p> +<h3 id="simple-gis-storage-backend">Simple <span class="caps">GIS</span> storage&nbsp;backend</h3> +<p>Let&#8217;s say you are a mobile developer, you don&#8217;t want to bother with +PostGIS nor write a custom and insecure code to insert and retrieve your +<span class="caps">GIS</span> data! You need carto-forms! A simple <span class="caps">API</span> helps you design your +models/forms and the same <span class="caps">API</span> allows you to <span class="caps">CRUD</span> and query your data. +Thus, you only need to focus on your application, not on how <span class="caps">GIS</span> data +will be&nbsp;handled.</p> +<p>We make a distinction between storage and&nbsp;widgets.</p> +<p>Besides, if you are a django / drupal / plomino&#8230; maintainer : you can +develop a module to &#8220;plug&#8221; your models (content types) and <span class="caps">UI</span> to +carto-forms! Carto forms are then exposed to your backoffice users (ex: +drupal admin <span class="caps">UI</span>, django adminsite), and likewise you can write your own +<span class="caps">HTML</span> widgets that consume datasets in frontend views (facets in +<span class="caps">JSON</span>/<span class="caps">XML</span>, and map data in&nbsp;GeoJSON).</p> +<h3 id="visualization-tool">Visualization&nbsp;tool</h3> +<p>Since data submission can be done programmatically using the <span class="caps">API</span>, you +could use Carto-forms results page as a visualization&nbsp;tool.</p> +<p>You can explore your dataset content using filters related to each form +field. Facets filtering is a great advantage, and a map shows the +resulting features set. You feel like you&#8217;re in front of a decision +support&nbsp;system!</p> +<p>Of course, filtered raw data can be downloaded (GeoJSON, <span class="caps">XML</span>) and a +permalink allows to share the page with the state of the filters and the +zoom/location of the&nbsp;map.</p> +<h3 id="generic-forms-service">Generic forms&nbsp;service</h3> +<p>If you want to generate a configuration file (or whatever, email +messages, &#8230;), you will need a form and a template to inlay user +submitted values and get the&nbsp;result.</p> +<p>A form service would be really useful to create forms programmatically +and retrieve cleaned and validated input&nbsp;values.</p> +<p>You could run a dedicated template service based on <em>carto-forms</em>! +Parsing a template content, this external service could create a form +dynamically and bind them together. The output of the form service +(fields =&gt; values) would be bound to the input of a template engine +(variables =&gt; final&nbsp;result).</p> +<p>Note that for this use-case, there is no specific need of <span class="caps">GIS</span> data nor +storage of records for further&nbsp;retrieval.</p> +<h2 id="whats-out-in-the-wild-already">What&#8217;s out in the wild&nbsp;already?</h2> +<p>Of course, there is Google forms, which allows you to do these kind of +things, but it&#8217;s closed and not exactly what we are describing&nbsp;here.</p> +<p>We&#8217;ve discovered the interesting <a href="https://webform.com/">https://webform.com/</a> which allows one +to create forms with a nice drag-n-drop flow. I would love to reproduce +something similar for the user experience. However, the project doesn&#8217;t +handle APIs and geolocation&nbsp;information.</p> +<p>The idea of <a href="http://thoth.io">http://thoth.io</a> is very attractive : an extremely simple +web <span class="caps">API</span> to store and retrieve data. In addition, <em>carto-forms</em> would do +datatype validation and have basic <span class="caps">GIS</span> fields (point, line,&nbsp;polygon).</p> +<p><a href="http://mapbox.com">http://mapbox.com</a> also did an awesome work on cartography, but didn&#8217;t +take into account the form aspect we&#8217;re leveraging&nbsp;here.</p> +<h2 id="so-lets-get-it-real">So… Let&#8217;s get it&nbsp;real!</h2> +<p>As you may have understood, this isn&#8217;t a really complicated problem. We +have been sometimes chatting about that with Mathieu about what we would +need and how we could achieve&nbsp;this.</p> +<p>We can probably come with an elegant solution without too much pain. +Mathieu is used to work with <span class="caps">GIS</span> systems (which is really cool because +I&#8217;m not at all) and knows his subject, so that&#8217;s an opportunity to learn&nbsp;;-)</p> +<p>We will be at <a href="http://rencontres.django-fr.org">Djangocong</a> on April 14 +and 15 and will probably have a brainstorming session and a sprint on +this, so if you are around and want to help us, or just to discuss, feel +free to&nbsp;join!</p> +<p>We don&#8217;t know yet if we will be using django for this or something else. +We have been thinking about couchdb, couchapps and geocouch but nothing +is written in stone yet. Comments and proposals are&nbsp;welcome!</p> +<p>Here is the etherpad document we worked on so far: +<a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don&#8217;t hesitate to add your thoughts +and edit it, that&#8217;s what it&#8217;s made&nbsp;for!</p> +<p>Thanks to <a href="http://sneakernet.fr/">Arnaud</a> and +<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Introducing Cornice2011-12-07T00:00:00+01:002011-12-07T00:00:00+01:00tag:blog.notmyidea.org,2011-12-07:/introducing-cornice.html +<p>Wow, already my third working day at Mozilla. Since Monday, I&#8217;ve been +working with <a href="http://ziade.org">Tarek Ziadé</a>, on a pyramid <span class="caps">REST</span>-ish +toolkit named <a href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you&#8217;re usually missing so you +can focus on what&#8217;s important. Cornice provides you …</p> +<p>Wow, already my third working day at Mozilla. Since Monday, I&#8217;ve been +working with <a href="http://ziade.org">Tarek Ziadé</a>, on a pyramid <span class="caps">REST</span>-ish +toolkit named <a href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you&#8217;re usually missing so you +can focus on what&#8217;s important. Cornice provides you facilities for +validation of any&nbsp;kind.</p> +<p>The goal is to simplify your work, but we don&#8217;t want to reinvent the +wheel, so it is easily pluggable with validations frameworks, such as +<a href="http://docs.pylonsproject.org/projects/colander/en/latest/">Colander</a>.</p> +<h2 id="handling-errors-and-validation">Handling errors and&nbsp;validation</h2> +<p>Here is how it&nbsp;works:</p> +<div class="highlight"><pre><span></span><code><span class="n">service</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;service&quot;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s2">&quot;/service&quot;</span><span class="p">)</span> + + +<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="k">if</span> <span class="ow">not</span> <span class="s1">&#39;awesome&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span> + <span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">&#39;query&#39;</span><span class="p">,</span> <span class="s1">&#39;awesome&#39;</span><span class="p">,</span> + <span class="s1">&#39;the awesome parameter is required&#39;</span><span class="p">)</span> + + +<span class="nd">@service</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;test&quot;</span><span class="p">:</span> <span class="s2">&quot;yay!&quot;</span><span class="p">}</span> +</code></pre></div> + +<p>All the errors collected during the validation process, or after, are +collected before returning the request. If any, a error 400 is fired up, +with the list of problems encountered returned as a nice json list +response (we plan to support multiple formats in the&nbsp;future)</p> +<p>As you might have seen, request.errors.add takes three parameters: +<strong>location</strong>, <strong>name</strong> and <strong>description</strong>.</p> +<p><strong>location</strong> is where the error is located in the request. It can either +be &#8220;body&#8221;, &#8220;query&#8221;, &#8220;headers&#8221; or &#8220;path&#8221;. <strong>name</strong> is the name of the +variable causing problem, if any, and <strong>description</strong> contains a more +detailed&nbsp;message.</p> +<p>Let&#8217;s run this simple service and send some queries to&nbsp;it:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>-v<span class="w"> </span>http://127.0.0.1:5000/service +&gt;<span class="w"> </span>GET<span class="w"> </span>/service<span class="w"> </span>HTTP/1.1 +&gt;<span class="w"> </span>Host:<span class="w"> </span><span class="m">127</span>.0.0.1:5000 +&gt;<span class="w"> </span>Accept:<span class="w"> </span>*/* +&gt; +*<span class="w"> </span>HTTP<span class="w"> </span><span class="m">1</span>.0,<span class="w"> </span>assume<span class="w"> </span>close<span class="w"> </span>after<span class="w"> </span>body +&lt;<span class="w"> </span>HTTP/1.0<span class="w"> </span><span class="m">400</span><span class="w"> </span>Bad<span class="w"> </span>Request +&lt;<span class="w"> </span>Content-Type:<span class="w"> </span>application/json<span class="p">;</span><span class="w"> </span><span class="nv">charset</span><span class="o">=</span>UTF-8 +<span class="o">[{</span><span class="s2">&quot;location&quot;</span>:<span class="w"> </span><span class="s2">&quot;query&quot;</span>,<span class="w"> </span><span class="s2">&quot;name&quot;</span>:<span class="w"> </span><span class="s2">&quot;awesome&quot;</span>,<span class="w"> </span><span class="s2">&quot;description&quot;</span>:<span class="w"> </span><span class="s2">&quot;You lack awesomeness!&quot;</span><span class="o">}</span> +</code></pre></div> + +<p>I&#8217;ve removed the extra clutter from the curl&#8217;s output, but you got the +general&nbsp;idea.</p> +<p>The content returned is in <span class="caps">JSON</span>, and I know exactly what I have to do: +add an &#8220;awesome&#8221; parameter in my query. Let&#8217;s do it&nbsp;again:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>http://127.0.0.1:5000/service?awesome<span class="o">=</span>yeah +<span class="o">{</span><span class="s2">&quot;test&quot;</span>:<span class="w"> </span><span class="s2">&quot;yay!&quot;</span><span class="o">}</span> +</code></pre></div> + +<p>Validators can also convert parts of the request and store the converted +value in request.validated. It is a standard dict automatically attached +to the&nbsp;requests.</p> +<p>For instance, in our validator, we can chose to validate the parameter +passed and use it in the body of the&nbsp;webservice:</p> +<div class="highlight"><pre><span></span><code><span class="n">service</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;service&quot;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s2">&quot;/service&quot;</span><span class="p">)</span> + + +<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="k">if</span> <span class="ow">not</span> <span class="s1">&#39;awesome&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span> + <span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">&#39;query&#39;</span><span class="p">,</span> <span class="s1">&#39;awesome&#39;</span><span class="p">,</span> + <span class="s1">&#39;the awesome parameter is required&#39;</span><span class="p">)</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s1">&#39;awesome&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;awesome &#39;</span> <span class="o">+</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">[</span><span class="s1">&#39;awesome&#39;</span><span class="p">]</span> + + +<span class="nd">@service</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span> +<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;test&quot;</span><span class="p">:</span> <span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s1">&#39;awesome&#39;</span><span class="p">]}</span> +</code></pre></div> + +<p>The output would look like&nbsp;this:</p> +<div class="highlight"><pre><span></span><code>curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;awesome yeah&quot;} +</code></pre></div> + +<h2 id="dealing-with-accept-headers">Dealing with &#8220;Accept&#8221;&nbsp;headers</h2> +<p>The <span class="caps">HTTP</span> spec defines a <strong>Accept</strong> header the client can send so the +response is encoded the right way. A resource, available at an <span class="caps">URL</span>, can +be available in different formats. This is especially true for web&nbsp;services.</p> +<p>Cornice can help you dealing with this. The services you define can tell +which Content-Type values they can deal with and this will be checked +against the <strong>Accept</strong> headers sent by the&nbsp;client.</p> +<p>Let&#8217;s refine a bit our previous example, by specifying which +content-types are supported, using the accept&nbsp;parameter:</p> +<div class="highlight"><pre><span></span><code><span class="nd">@service</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">,</span> <span class="n">accept</span><span class="o">=</span><span class="p">(</span><span class="s2">&quot;application/json&quot;</span><span class="p">,</span> <span class="s2">&quot;text/json&quot;</span><span class="p">))</span> +<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> + <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;test&quot;</span><span class="p">:</span> <span class="s2">&quot;yay!&quot;</span><span class="p">}</span> +</code></pre></div> + +<p>Now, if you specifically ask for <span class="caps">XML</span>, Cornice will throw a 406 with the +list of accepted Content-Type&nbsp;values:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>-vH<span class="w"> </span><span class="s2">&quot;Accept: application/xml&quot;</span><span class="w"> </span>http://127.0.0.1:5000/service +&gt;<span class="w"> </span>GET<span class="w"> </span>/service<span class="w"> </span>HTTP/1.1 +&gt;<span class="w"> </span>Host:<span class="w"> </span><span class="m">127</span>.0.0.1:5000 +&gt;<span class="w"> </span>Accept:<span class="w"> </span>application/xml +&gt; +&lt;<span class="w"> </span>HTTP/1.0<span class="w"> </span><span class="m">406</span><span class="w"> </span>Not<span class="w"> </span>Acceptable +&lt;<span class="w"> </span>Content-Type:<span class="w"> </span>application/json<span class="p">;</span><span class="w"> </span><span class="nv">charset</span><span class="o">=</span>UTF-8 +&lt;<span class="w"> </span>Content-Length:<span class="w"> </span><span class="m">33</span> +&lt; +<span class="o">[</span><span class="s2">&quot;application/json&quot;</span>,<span class="w"> </span><span class="s2">&quot;text/json&quot;</span><span class="o">]</span> +</code></pre></div> + +<h2 id="building-your-documentation-automatically">Building your documentation&nbsp;automatically</h2> +<p>writing documentation for web services can be painful, especially when +your services evolve. Cornice provides a sphinx directive to +automatically document your <span class="caps">API</span> in your&nbsp;docs.</p> +<div class="highlight"><pre><span></span><code><span class="nx">rst</span> +<span class="p">..</span><span class="w"> </span><span class="nx">services</span><span class="o">::</span> +<span class="w"> </span><span class="p">:</span><span class="kn">package</span><span class="p">:</span><span class="w"> </span><span class="nx">coolapp</span> +<span class="w"> </span><span class="p">:</span><span class="nx">service</span><span class="p">:</span><span class="w"> </span><span class="nx">quote</span> +</code></pre></div> + +<p>Here is an example of what a generated page looks like: +<a href="http://packages.python.org/cornice/exampledoc.html">http://packages.python.org/cornice/exampledoc.html</a></p> +<h2 id="yay-how-can-i-get-it">Yay! How can I get&nbsp;it?</h2> +<p>We just cut a 0.4 release, so it&#8217;s available at +<a href="http://pypi.python.org/pypi/cornice">http://pypi.python.org/pypi/cornice</a> You can install it easily using +pip, for&nbsp;instance:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>cornice +</code></pre></div> + +<p>You can also have a look at the documentation at +<a href="http://packages.python.org/cornice/">http://packages.python.org/cornice/</a></p> +<h2 id="whats-next">What&#8217;s&nbsp;next?</h2> +<p>We try to make our best to find how Cornice can help you build better +web services. Cool features we want for the future include the automatic +publication of a static definition of the services, so it can be used by +clients to discover services in a nice&nbsp;way.</p> +<p>Of course, we are open to all your ideas and patches! If you feel +haskish and want to see the sources, <a href="https://github.com/mozilla-services/cornice">go grab them on +github</a> , commit and send +us a pull&nbsp;request!</p>How are you handling your shared expenses?2011-10-15T00:00:00+02:002011-10-15T00:00:00+02:00tag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.html +<p><strong><span class="caps">TL</span>;<span class="caps">DR</span>:</strong> We&#8217;re kick-starting a new application to manage your shared +expenses. Have a look at <a href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a></p> +<p>As a student, I lived in a lot of different locations, and the majority +of them had something in common: I lived with others. It usually was a +great …</p> +<p><strong><span class="caps">TL</span>;<span class="caps">DR</span>:</strong> We&#8217;re kick-starting a new application to manage your shared +expenses. Have a look at <a href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a></p> +<p>As a student, I lived in a lot of different locations, and the majority +of them had something in common: I lived with others. It usually was a +great experience (and I think I will continue to live with others). Most +of the time, we had to spend some time each month to compute who had to +pay what to the&nbsp;others.</p> +<p>I wanted to create a pet project using flask, so I wrote a little (\~150 +lines) flask application to handle this. It worked out pretty well for +my housemates and me, and as we had to move into different locations, +one of them asked me if he could continue to use it for the year to&nbsp;come.</p> +<p>I said yes and gave it some more thoughts: We probably aren&#8217;t the only +ones interested by such kind of software. I decided to extend a bit more +the software to have a concept of projects and persons (the list of +persons was hard-coded in the first time,&nbsp;boooh!).</p> +<p>I then discussed with a friend of mine, who was excited about it and +wanted to learn python. Great! That&#8217;s a really nice way to get started. +Some more friends were also interested in it and contributed some +features and provided feedback (thanks +<a href="http://www.sneakernet.fr/">Arnaud</a> and&nbsp;Quentin!)</p> +<p>Since that, the project now support multiple languages and provides a +<span class="caps">REST</span> <span class="caps">API</span> (android and iphone apps in the tubes!), into other things. +There is no need to register for an account or whatnot, just enter a +project name, a secret code and a contact email, invite friends and +that&#8217;s it (this was inspired by&nbsp;doodle)!</p> +<p><img alt="Capture d'écran du site." src="/images/ihatemoney.png"></p> +<p>You can try the project at <a href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a> for now, +and the code lives at <a href="https://github.com/spiral-project/ihatemoney/">https://github.com/spiral-project/ihatemoney/</a>.</p> +<h2 id="features">Features</h2> +<p>In the wild, currently, there already are some implementations of this +shared budget manager thing. The fact is that most of them are either +hard to use, with a too much fancy design or simply trying to do too +much things at&nbsp;once.</p> +<p>No, I don&#8217;t want my budget manager to make my shopping list, or to run a +blog for me, thanks. I want it to let me focus on something else. Keep +out of my&nbsp;way.</p> +<h3 id="no-user-registration">No user&nbsp;registration</h3> +<p>You don&#8217;t need to register an account on the website to start using it. +You just have to create a project, set a secret code for it, and give +both the url and the code to the people you want to share it with (or +the website can poke them for&nbsp;you).</p> +<h3 id="keeping-things-simple">Keeping things&nbsp;simple</h3> +<p><span class="dquo">&#8220;</span>Keep It Simple, Stupid&#8221; really matches our philosophy here: you want to +add a bill? Okay. Just do it. You just have to enter who paid, for who, +how much, and a description, like you would have done when you&#8217;re back +from the farmer&#8217;s market on raw&nbsp;paper.</p> +<h3 id="no-categories">No&nbsp;categories</h3> +<p>Some people like to organise their stuff into different &#8220;categories&#8221;: +leisure, work, eating, etc. That&#8217;s not something I want (at least to +begin&nbsp;with).</p> +<p>I want things to be simple. Got that? Great. Just add your&nbsp;bills!</p> +<h3 id="balance">Balance</h3> +<p>One of the most useful thing is to know what&#8217;s your &#8220;balance&#8221; compared +to others. In other words, if you&#8217;re negative, you owe money, if you&#8217;re +positive, you have to receive money. This allows you to dispatch who has +to pay for the next thing, in order to re-equilibrate the&nbsp;balance.</p> +<p>Additionally, the system is able to compute for you who has to give how +much to who, in order to reduce the number of transactions needed to +restore the&nbsp;balance.</p> +<h3 id="api"><span class="caps">API</span></h3> +<p>All of what&#8217;s possible to do with the standard web interface is also +available through a <span class="caps">REST</span> <span class="caps">API</span>. I developed a simple <span class="caps">REST</span> toolkit for +flask for this (and I should release&nbsp;it!).</p> +<h2 id="interested">Interested?</h2> +<p>This project is open source. All of us like to share what we are doing +and would be happy to work with new people and implement new ideas. If +you have a nice idea about this, if you want to tweak it or to fill +bugs. Don&#8217;t hesitate a second! The project lives at +<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>Using dbpedia to get languages influences2011-08-16T00:00:00+02:002011-08-16T00:00:00+02:00tag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.html +<p>While browsing the Python&#8217;s wikipedia page, I found information about +the languages influenced by python, and the languages that influenced +python&nbsp;itself.</p> +<p>Well, that&#8217;s kind of interesting to know which languages influenced +others, it could even be more interesting to have an overview of the +connexion between them …</p> +<p>While browsing the Python&#8217;s wikipedia page, I found information about +the languages influenced by python, and the languages that influenced +python&nbsp;itself.</p> +<p>Well, that&#8217;s kind of interesting to know which languages influenced +others, it could even be more interesting to have an overview of the +connexion between them, keeping python as the main&nbsp;focus.</p> +<p>This information is available on the wikipedia page, but not in a really +exploitable format. Hopefully, this information is provided into the +information box present on the majority of wikipedia pages. And… guess +what? there is project with the goal to scrap and index all this +information in a more queriable way, using the semantic web&nbsp;technologies.</p> +<p>Well, you may have guessed it, the project in question in dbpedia, and +exposes information in the form of <span class="caps">RDF</span> triples, which are way more easy +to work with than simple <span class="caps">HTML</span>.</p> +<p>For instance, let&#8217;s take the page about python: +<a href="http://dbpedia.org/page/Python_%28programming_language%29">http://dbpedia.org/page/Python_%28programming_language%29</a></p> +<p>The interesting properties here are &#8220;Influenced&#8221; and &#8220;InfluencedBy&#8221;, +which allows us to get a list of languages. Unfortunately, they are not +really using all the power of the Semantic Web here, and the list is +actually a string with coma separated values in&nbsp;it.</p> +<p>Anyway, we can use a simple rule: All wikipedia pages of programming +languages are either named after the name of the language itself, or +suffixed with &#8220;( programming language)&#8221;, which is the case for&nbsp;python.</p> +<p>So I&#8217;ve built <a href="https://github.com/ametaireau/experiments/blob/master/influences/get_influences.py">a tiny script to extract the information from +dbpedia</a> +and transform them into a shiny graph using&nbsp;graphviz.</p> +<p>After a&nbsp;nice:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>python<span class="w"> </span>get_influences.py<span class="w"> </span>python<span class="w"> </span>dot<span class="w"> </span><span class="p">|</span><span class="w"> </span>dot<span class="w"> </span>-Tpng<span class="w"> </span>&gt;<span class="w"> </span>influences.png +</code></pre></div> + +<p>The result is the following graph (<a href="http://files.lolnet.org/alexis/influences.png">see it directly +here</a>)</p> +<p><img alt="Graph des influances des langages les uns sur les +autres." src="http://files.lolnet.org/alexis/influences.png"></p> +<p>While reading this diagram, keep in mind that it is a) not listing all +the languages and b) keeping a python&nbsp;perspective.</p> +<p>This means that you can trust the scheme by following the arrows from +python to something and from something to python, it is not trying to +get the matching between all the languages at the same time to keep +stuff&nbsp;readable.</p> +<p>It would certainly be possible to have all the connections between all +languages (and the resulting script would be easier) to do so, but the +resulting graph would probably be way less&nbsp;readable.</p> +<p>You can find the script <a href="https://github.com/ametaireau/experiments">on my github +account</a>. Feel free to adapt +it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html +<p>Back in October, I released +<a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of +code I wrote to power this weblog. I had simple needs: I wanted to be +able to use my text editor of choice (vim), a vcs (mercurial) and +restructured text. I started to write a really simple blog engine in …</p> +<p>Back in October, I released +<a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of +code I wrote to power this weblog. I had simple needs: I wanted to be +able to use my text editor of choice (vim), a vcs (mercurial) and +restructured text. I started to write a really simple blog engine in +something like a hundred python lines and released it on&nbsp;github.</p> +<p>And people started contributing. I wasn&#8217;t at all expecting to see people +interested in such a little piece of code, but it turned out that they +were. I refactored the code to make it evolve a bit more by two times +and eventually, in 9 months, got 49 forks, 139 issues and 73 pull&nbsp;requests.</p> +<p><strong>Which is clearly&nbsp;awesome.</strong></p> +<p>I pulled features such as translations, tag clouds, integration with +different services such as twitter or piwik, import from dotclear and +rss, fixed a number of mistakes and improved a lot the codebase. This +was a proof that there is a bunch of people that are willing to make +better softwares just for the sake of&nbsp;fun.</p> +<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html +<p>Java provides some interesting libraries that have no exact equivalent +in python. In my case, the awesome boilerpipe library allows me to +remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other +&#8220;boilerplate&#8221;&nbsp;contents.</p> +<p>Boilerpipe is written in Java. Two solutions then: using java from +python or reimplement boilerpipe …</p> +<p>Java provides some interesting libraries that have no exact equivalent +in python. In my case, the awesome boilerpipe library allows me to +remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other +&#8220;boilerplate&#8221;&nbsp;contents.</p> +<p>Boilerpipe is written in Java. Two solutions then: using java from +python or reimplement boilerpipe in python. I will let you guess which +one I chosen,&nbsp;meh.</p> +<p>JPype allows to bridge python project with java libraries. It takes +another point of view than Jython: rather than reimplementing python in +Java, both languages are interfacing at the <span class="caps">VM</span> level. This means you +need to start a <span class="caps">VM</span> from your python script, but it does the job and stay +fully compatible with Cpython and its C&nbsp;extensions.</p> +<h2 id="first-steps-with-jpype">First steps with&nbsp;JPype</h2> +<p>Once JPype installed (you&#8217;ll have to hack a bit some files to integrate +seamlessly with your system) you can access java classes by doing +something like&nbsp;that:</p> +<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">jpype</span> +<span class="n">jpype</span><span class="o">.</span><span class="n">startJVM</span><span class="p">(</span><span class="n">jpype</span><span class="o">.</span><span class="n">getDefaultJVMPath</span><span class="p">())</span> + +<span class="c1"># you can then access to the basic java functions</span> +<span class="n">jpype</span><span class="o">.</span><span class="n">java</span><span class="o">.</span><span class="n">lang</span><span class="o">.</span><span class="n">System</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">println</span><span class="p">(</span><span class="s2">&quot;hello world&quot;</span><span class="p">)</span> + +<span class="c1"># and you have to shutdown the VM at the end</span> +<span class="n">jpype</span><span class="o">.</span><span class="n">shutdownJVM</span><span class="p">()</span> +</code></pre></div> + +<p>Okay, now we have a hello world, but what we want seems somehow more +complex. We want to interact with java classes, so we will have to load&nbsp;them.</p> +<h2 id="interfacing-with-boilerpipe">Interfacing with&nbsp;Boilerpipe</h2> +<p>To install boilerpipe, you just have to run an ant&nbsp;script:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>boilerpipe +$<span class="w"> </span>ant +</code></pre></div> + +<p>Here is a simple example of how to use boilerpipe in Java, from their&nbsp;sources</p> +<div class="highlight"><pre><span></span><code><span class="kn">package</span><span class="w"> </span><span class="nn">de.l3s.boilerpipe.demo</span><span class="p">;</span> +<span class="kn">import</span><span class="w"> </span><span class="nn">java.net.URL</span><span class="p">;</span> +<span class="kn">import</span><span class="w"> </span><span class="nn">de.l3s.boilerpipe.extractors.ArticleExtractor</span><span class="p">;</span> + +<span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">Oneliner</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="kd">final</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Exception</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">URL</span><span class="w"> </span><span class="n">url</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">URL</span><span class="p">(</span><span class="s">&quot;http://notmyidea.org&quot;</span><span class="p">);</span> +<span class="w"> </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="n">ArticleExtractor</span><span class="p">.</span><span class="na">INSTANCE</span><span class="p">.</span><span class="na">getText</span><span class="p">(</span><span class="n">url</span><span class="p">));</span> +<span class="w"> </span><span class="p">}</span> +<span class="p">}</span> +</code></pre></div> + +<p>To run&nbsp;it:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>javac<span class="w"> </span>-cp<span class="w"> </span>dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar<span class="w"> </span>src/demo/de/l3s/boilerpipe/demo/Oneliner.java +$<span class="w"> </span>java<span class="w"> </span>-cp<span class="w"> </span>src/demo:dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar<span class="w"> </span>de.l3s.boilerpipe.demo.Oneliner +</code></pre></div> + +<p>Yes, this is kind of ugly, sorry for your eyes. Let&#8217;s try something +similar, but from&nbsp;python</p> +<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">jpype</span> + +<span class="c1"># start the JVM with the good classpaths</span> +<span class="n">classpath</span> <span class="o">=</span> <span class="s2">&quot;dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar&quot;</span> +<span class="n">jpype</span><span class="o">.</span><span class="n">startJVM</span><span class="p">(</span><span class="n">jpype</span><span class="o">.</span><span class="n">getDefaultJVMPath</span><span class="p">(),</span> <span class="s2">&quot;-Djava.class.path=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">classpath</span><span class="p">)</span> + +<span class="c1"># get the Java classes we want to use</span> +<span class="n">DefaultExtractor</span> <span class="o">=</span> <span class="n">jpype</span><span class="o">.</span><span class="n">JPackage</span><span class="p">(</span><span class="s2">&quot;de&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">l3s</span><span class="o">.</span><span class="n">boilerpipe</span><span class="o">.</span><span class="n">extractors</span><span class="o">.</span><span class="n">DefaultExtractor</span> + +<span class="c1"># call them !</span> +<span class="nb">print</span> <span class="n">DefaultExtractor</span><span class="o">.</span><span class="n">INSTANCE</span><span class="o">.</span><span class="n">getText</span><span class="p">(</span><span class="n">jpype</span><span class="o">.</span><span class="n">java</span><span class="o">.</span><span class="n">net</span><span class="o">.</span><span class="n">URL</span><span class="p">(</span><span class="s2">&quot;http://blog.notmyidea.org&quot;</span><span class="p">))</span> +</code></pre></div> + +<p>And you get what you&nbsp;want.</p> +<p>I must say I didn&#8217;t thought it could work so easily. This will allow me +to extract text content from URLs and remove the <em>boilerplate</em> text +easily for infuse (my master thesis project), without having to write +java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html +<p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du +reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais +besoin d&#8217;un petit coup de&nbsp;main.</p> +<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui +connaissent …</p> +<p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du +reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais +besoin d&#8217;un petit coup de&nbsp;main.</p> +<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui +connaissent last.fm, je fais quelque chose de similaire mais pour les +sites internet: en me basant sur ce que vous visitez quotidiennement et +comment vous le visitez (quelles horaires, quelle emplacement +géographique, etc.) je souhaites proposer des liens qui vous +intéresseront potentiellement, en me basant sur l&#8217;avis des personnes +qui ont des profils similaires au&nbsp;votre.</p> +<p>Le projet est loin d&#8217;être terminé, mais la première étape est de +récupérer des données de navigation, idéalement beaucoup de données de +navigation. Donc si vous pouvez me filer un coup de main je vous en +serais éternellement reconnaissant (pour ceux qui font semblant de pas +comprendre, entendez &#8220;tournée&nbsp;générale&#8221;).</p> +<p>J&#8217;ai créé un petit site web (en anglais) qui résume un peu le concept, +qui vous propose de vous inscrire et de télécharger un plugin firefox +qui m&#8217;enverra des information sur les sites que vous visitez (si vous +avez l&#8217;habitude d&#8217;utiliser chrome vous pouvez considérer de switcher à +firefox4 pour les deux prochains mois pour me filer un coup de main). Il +est possible de désactiver le plugin d&#8217;un simple clic si vous souhaitez +garder votre vie privée privée&nbsp;;-)</p> +<p>Le site est par là: <a href="http://infuse.notmyidea.org">http://infuse.notmyidea.org</a>. Une fois le plugin +téléchargé et le compte créé il faut renseigner vos identifiants dans +le plugin en question, et c&#8217;est&nbsp;tout!</p> +<p>A votre bon cœur ! Je récupérerais probablement des données durant les +2 prochains mois pour ensuite les analyser&nbsp;correctement.</p> +<p>Merci pour votre aide&nbsp;!</p>Analyse users’ browsing context to build up a web recommender2011-04-01T00:00:00+02:002011-04-01T00:00:00+02:00tag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.html +<p>No, this is not an april&#8217;s fool&nbsp;;)</p> +<p>Wow, it&#8217;s been a long time. My year in Oxford is going really well. I +realized few days ago that the end of the year is approaching really +quickly. Exams are coming in one month or such and then I&#8217;ll …</p> +<p>No, this is not an april&#8217;s fool&nbsp;;)</p> +<p>Wow, it&#8217;s been a long time. My year in Oxford is going really well. I +realized few days ago that the end of the year is approaching really +quickly. Exams are coming in one month or such and then I&#8217;ll be working +full time on my dissertation&nbsp;topic.</p> +<p>When I learned we&#8217;ll have about 6 month to work on something, I first +thought about doing a packaging related stuff, but finally decided to +start something new. After all, that&#8217;s the good time to&nbsp;learn.</p> +<p>Since a long time, I&#8217;m being impressed by the <a href="http://last.fm">last.fm</a> +recommender system. They&#8217;re <em>scrobbling</em> the music I listen to since +something like 5 years now and the recommendations they&#8217;re doing are +really nice and accurate (I discovered <strong>a lot</strong> of great artists +listening to the &#8220;neighbour radio&#8221;.) (by the way, <a href="http://lastfm.com/user/akounet/">here +is</a> my lastfm&nbsp;account)</p> +<p>So I decided to work on recommender systems, to better understand what +is it&nbsp;about.</p> +<p>Recommender systems are usually used to increase the sales of products +(like Amazon.com does) which is not really what I&#8217;m looking for (The one +who know me a bit know I&#8217;m kind of sick about all this consumerism going&nbsp;on).</p> +<p>Actually, the most simple thing I thought of was the web: I&#8217;m browsing +it quite every day and each time new content appears. I&#8217;ve stopped to +follow <a href="https://bitbucket.org/bruno/aspirator/">my feed reader</a> because +of the information overload, and reduced drastically the number of +people I follow <a href="http://twitter.com/ametaireau/">on twitter</a>.</p> +<p>Too much information kills the&nbsp;information.</p> +<p>You shall got what will be my dissertation topic: a recommender system +for the web. Well, such recommender systems already exists, so I will +try to add contextual information to them: you&#8217;re probably not +interested by the same topics at different times of the day, or +depending on the computer you&#8217;re using. We can also probably make good +use of the way you browse to create groups into the content you&#8217;re +browsing (or even use the great firefox4 tab group&nbsp;feature).</p> +<p>There is a large part of concerns to have about user&#8217;s privacy as&nbsp;well.</p> +<p>Here is my proposal (copy/pasted from the one I had to do for my&nbsp;master)</p> +<h2 id="introduction-and-rationale">Introduction and&nbsp;rationale</h2> +<p>Nowadays, people surf the web more and more often. New web pages are +created each day so the amount of information to retrieve is more +important as the time passes. These users uses the web in different +contexts, from finding cooking recipes to technical&nbsp;articles.</p> +<p>A lot of people share the same interest to various topics, and the +quantity of information is such than it&#8217;s really hard to triage them +efficiently without spending hours doing it. Firstly because of the huge +quantity of information but also because the triage is something +relative to each person. Although, this triage can be facilitated by +fetching the browsing information of all particular individuals and put +the in&nbsp;perspective.</p> +<p>Machine learning is a branch of Artificial Intelligence (<span class="caps">AI</span>) which deals +with how a program can learn from data. Recommendation systems are a +particular application area of machine learning which is able to +recommend things (links in our case) to the users, given a particular +database containing the previous choices users have&nbsp;made.</p> +<p>This browsing information is currently available in browsers. Even if it +is not in a very usable format, it is possible to transform it to +something useful. This information gold mine just wait to be used. +Although, it is not as simple as it can seems at the first approach: It +is important to take care of the context the user is in while browsing +links. For instance, It&#8217;s more likely that during the day, a computer +scientist will browse computing related links, and that during the +evening, he browse cooking recipes or something&nbsp;else.</p> +<p>Page contents are also interesting to analyse, because that&#8217;s what +people browse and what actually contain the most interesting part of the +information. The raw data extracted from the browsing can then be +translated into something more useful (namely tags, type of resource, +visit frequency, navigation context&nbsp;etc.)</p> +<p>The goal of this dissertation is to create a recommender system for web +links, including this context&nbsp;information.</p> +<p>At the end of the dissertation, different pieces of software will be +provided, from raw data collection from the browser to a recommendation&nbsp;system.</p> +<h2 id="background-review">Background&nbsp;Review</h2> +<p>This dissertation is mainly about data extraction, analysis and +recommendation systems. Two different research area can be isolated: +Data preprocessing and Information&nbsp;filtering.</p> +<p>The first step in order to make recommendations is to gather some data. +The more data we have available, the better it is (T. Segaran, 2007). +This data can be retrieved in various ways, one of them is to get it +directly from user&#8217;s&nbsp;browsers.</p> +<h3 id="data-preparation-and-extraction">Data preparation and&nbsp;extraction</h3> +<p>The data gathered from browsers is basically URLs and additional +information about the context of the navigation. There is clearly a need +to extract more information about the meaning of the data the user is +browsing, starting by the content of the web&nbsp;pages.</p> +<p>Because the information provided on the current Web is not meant to be +read by machines (T. Berners Lee, 2001) there is a need of tools to +extract meaning from web pages. The information needs to be preprocessed +before stored in a machine readable format, allowing to make +recommendations (Choochart et Al,&nbsp;2004).</p> +<p>Data preparation is composed of two steps: cleaning and structuring ( +Castellano et Al, 2007). Because raw data can contain a lot of un-needed +text (such as menus, headers etc.) and need to be cleaned prior to be +stored. Multiple techniques can be used here and belongs to boilerplate +removal and full text extraction (Kohlschütter et Al,&nbsp;2010).</p> +<p>Then, structuring the information: category, type of content (news, +blog, wiki) can be extracted from raw data. This kind of information is +not clearly defined by <span class="caps">HTML</span> pages so there is a need of tools to +recognise&nbsp;them.</p> +<p>Some context-related information can also be inferred from each +resource. It can go from the visit frequency to the navigation group the +user was in while browsing. It is also possible to determine if the user +&#8220;liked&#8221; a resource, and determine a mark for it, which can be used by +information filtering a later step (T. Segaran,&nbsp;2007).</p> +<p>At this stage, structuring the data is required. Storing this kind of +information in <span class="caps">RDBMS</span> can be a bit tedious and require complex queries to +get back the data in an usable format. Graph databases can play a major +role in the simplification of information storage and&nbsp;querying.</p> +<h3 id="information-filtering">Information&nbsp;filtering</h3> +<p>To filter the information, three techniques can be used (Balabanovic et +Al,&nbsp;1997):</p> +<ul> +<li>The content-based approach states that if an user have liked + something in the past, he is more likely to like similar things in + the future. So it&#8217;s about establishing a profile for the user and + compare new items against&nbsp;it.</li> +<li>The collaborative approach will rather recommend items that other + similar users have liked. This approach consider only the + relationship between users, and not the profile of the user we are + making recommendations&nbsp;to.</li> +<li>the hybrid approach, which appeared recently combine both of the + previous approaches, giving recommendations when items score high + regarding user&#8217;s profile, or if a similar user already liked&nbsp;it.</li> +</ul> +<p>Grouping is also something to consider at this stage (G. Myatt, 2007). +Because we are dealing with huge amount of data, it can be useful to +detect group of data that can fit together. Data clustering is able to +find such groups (T. Segaran,&nbsp;2007).</p> +<p>References:</p> +<ul> +<li>Balabanović, M., <span class="amp">&amp;</span> Shoham, Y. (1997). Fab: content-based, + collaborative recommendation. Communications of the <span class="caps">ACM</span>, 40(3), + 66–72. <span class="caps">ACM</span>. Retrieved March 1, 2011, from + <a href="http://portal.acm.org/citation.cfm?id=245108.245124&amp;">http://portal.acm.org/citation.cfm?id=245108.245124&amp;</a>;.</li> +<li>Berners-Lee, T., Hendler, J., <span class="amp">&amp;</span> Lassila, O. (2001). The semantic + web: Scientific american. Scientific American, 284(5), 34–43. + Retrieved November 21, 2010, from + <a href="http://www.citeulike.org/group/222/article/1176986">http://www.citeulike.org/group/222/article/1176986</a>.</li> +<li>Castellano, G., Fanelli, A., <span class="amp">&amp;</span> Torsello, M. (2007). <span class="caps">LODAP</span>: a LOg + DAta Preprocessor for mining Web browsing patterns. Proceedings of + the 6th Conference on 6th <span class="caps">WSEAS</span> Int. Conf. on Artificial + Intelligence, Knowledge Engineering and Data Bases-Volume 6 (p. + 12–17). World Scientific and Engineering Academy and Society + (<span class="caps">WSEAS</span>). Retrieved March 8, 2011, from + <a href="http://portal.acm.org/citation.cfm?id=1348485.1348488">http://portal.acm.org/citation.cfm?id=1348485.1348488</a>.</li> +<li>Kohlschutter, C., Fankhauser, P., <span class="amp">&amp;</span> Nejdl, W. (2010). Boilerplate + detection using shallow text features. Proceedings of the third <span class="caps">ACM</span> + international conference on Web search and data mining (p. 441–450). + <span class="caps">ACM</span>. Retrieved March 8, 2011, from + <a href="http://portal.acm.org/citation.cfm?id=1718542">http://portal.acm.org/citation.cfm?id=1718542</a>.</li> +<li>Myatt, <span class="caps">G. J.</span>(2007). Making Sense of Data: A Practical Guide to + Exploratory Data Analysis and Data&nbsp;Mining.</li> +<li>Segaran, T. (2007). Collective&nbsp;Intelligence.</li> +</ul> +<h2 id="privacy">Privacy</h2> +<p>The first thing that&#8217;s come to people minds when it comes to process +their browsing data is privacy. People don&#8217;t want to be stalked. That&#8217;s +perfectly right, and I don&#8217;t&nbsp;either.</p> +<p>But such a system don&#8217;t have to deal with people identities. It&#8217;s +completely possible to process completely anonymous data, and that&#8217;s +probably what I&#8217;m gonna&nbsp;do.</p> +<p>By the way, if you have interesting thoughts about that, if you do know +projects that do seems related, fire the comments&nbsp;!</p> +<h2 id="whats-the-plan">What&#8217;s the plan&nbsp;?</h2> +<p>There is a lot of different things to explore, especially because I&#8217;m a +complete novice in that&nbsp;field.</p> +<ul> +<li>I want to develop a firefox plugin, to extract the browsing + informations ( still, I need to know exactly which kind of + informations to retrieve). The idea is to provide some <em>raw</em> + browsing data, and then to transform it and to store it in the + better possible&nbsp;way.</li> +<li>Analyse how to store the informations in a graph database. What can + be the different methods to store this data and to visualize the + relationship between different pieces of data? How can I define the + different contexts, and add those informations in the&nbsp;db?</li> +<li>Process the data using well known recommendation algorithms. Compare + the results and criticize their&nbsp;value.</li> +</ul> +<p>There is plenty of stuff I want to try during this&nbsp;experimentation:</p> +<ul> +<li>I want to try using Geshi to visualize the connexion between the + links, and the&nbsp;contexts</li> +<li>Try using graph databases such as&nbsp;Neo4j</li> +<li>Having a deeper look at tools such as scikit.learn (a machine + learning toolkit in&nbsp;python)</li> +<li>Analyse web pages in order to categorize them. Processing their + contents as well, to do some keyword based classification will be&nbsp;done.</li> +</ul> +<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html +<p>I have a server running freebsd since some time now, and was wondering +about the possibility to directly have a development environment ready +to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> +<p>Since I use vim to code, and spend most of my …</p> +<p>I have a server running freebsd since some time now, and was wondering +about the possibility to directly have a development environment ready +to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> +<p>Since I use vim to code, and spend most of my time in a console while +developing, it&#8217;s possible to work via ssh, from&nbsp;everywhere.</p> +<p>The only problem is the synchronisation of the source code, config files +etc. from my machine to the&nbsp;server.</p> +<p>Unison provides an interesting way to synchronise two folders, even over +a network. So let&#8217;s do it&nbsp;!</p> +<h2 id="creating-the-jail">Creating the&nbsp;jail</h2> +<p>In case you don&#8217;t use FreeBSD, you can skip this&nbsp;section.</p> +<div class="highlight"><pre><span></span><code># I have a flavour jail named default +$ ezjail-admin -f default workspace.notmyidea.org 172.19.1.6 +$ ezjail-admin start workspace.notmyidea.org +</code></pre></div> + +<p>In my case, because the &#8220;default&#8221; flavour contains already a lot of +interesting things, my jail come already setup with ssh, bash and vim +for instance, but maybe you&#8217;ll need it in your&nbsp;case.</p> +<p>I want to be redirected to the ssh of the jail when I connect to the +host with the 20006 port. Add lines in <code>/etc/pf.conf</code>:</p> +<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="nv">workspace_jail</span><span class="o">=</span><span class="s2">&quot;172.19.1.6&quot;</span> +<span class="w"> </span>rdr<span class="w"> </span>on<span class="w"> </span><span class="nv">$ext_if</span><span class="w"> </span>proto<span class="w"> </span>tcp<span class="w"> </span>from<span class="w"> </span>any<span class="w"> </span>to<span class="w"> </span><span class="nv">$ext_ip</span><span class="w"> </span>port<span class="w"> </span><span class="m">20006</span><span class="w"> </span>-&gt;<span class="w"> </span><span class="nv">$workspace_jail</span><span class="w"> </span>port<span class="w"> </span><span class="m">22</span> +</code></pre></div> + +<p>Reload packet filter&nbsp;rules</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>/etc/rc.d/pf<span class="w"> </span>reload +</code></pre></div> + +<h2 id="working-with-unison">Working with&nbsp;unison</h2> +<p>Now that we&#8217;ve set up the jail. Set up unison on the server and on your +client. Unison is available on the freebsd ports so just install&nbsp;it</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>notmyidea.org<span class="w"> </span>-p<span class="w"> </span><span class="m">20006</span> +$<span class="w"> </span>make<span class="w"> </span>-C<span class="w"> </span>/usr/ports/net/unison-nox11<span class="w"> </span>config-recursive +$<span class="w"> </span>make<span class="w"> </span>-C<span class="w"> </span>/usr/ports/net/unison-nox11<span class="w"> </span>package-recursive +</code></pre></div> + +<p>Install as well unison on your local machine. Double check to install +the same version on the client and on the server. Ubuntu contains the +2.27.57 as well as the&nbsp;2.32.52.</p> +<p>Check that unison is installed and reachable via ssh from your&nbsp;machine</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>notmyidea.org<span class="w"> </span>-p<span class="w"> </span><span class="m">20006</span><span class="w"> </span>unison<span class="w"> </span>-version +unison<span class="w"> </span>version<span class="w"> </span><span class="m">2</span>.27.157 +$<span class="w"> </span>unison<span class="w"> </span>-version +unison<span class="w"> </span>version<span class="w"> </span><span class="m">2</span>.27.57 +</code></pre></div> + +<h2 id="let-sync-our-folders">Let sync our&nbsp;folders</h2> +<p>The first thing I want to sync is my vim configuration. Well, it&#8217;s +already <a href="http://github.com/ametaireau/dotfiles/">in a git repository</a> +but let&#8217;s try to use unison for it right&nbsp;now.</p> +<p>I have two machines then: workspace, the jail, and ecureuil my&nbsp;laptop.</p> +<div class="highlight"><pre><span></span><code>unison<span class="w"> </span>.vim<span class="w"> </span>ssh://notmyidea.org:20006/.vim +unison<span class="w"> </span>.vimrc<span class="w"> </span>ssh://notmyidea.org:20006/.vimrc +</code></pre></div> + +<p>It is also possible to put all the informations in a config file, and +then to only run unison. (fire up vim&nbsp;\~/.unison/default.prf.</p> +<p>Here is my&nbsp;config:</p> +<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="na">root</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">/home/alexis</span> +<span class="w"> </span><span class="na">root</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">ssh://notmyidea.org:20006</span> + +<span class="w"> </span><span class="na">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">.vimrc</span> +<span class="w"> </span><span class="na">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">dotfiles</span> +<span class="w"> </span><span class="na">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">dev</span> + +<span class="w"> </span><span class="na">follow</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">Name *</span> +</code></pre></div> + +<p>My vimrc is in fact a symbolic link on my laptop, but I don&#8217;t want to +specify each of the links to unison. That&#8217;s why the follow = Name * is&nbsp;for.</p> +<p>The folders you want to synchronize are maybe a bit large. If so, +considering others options such as rsync for the first import may be a +good idea (I enjoyed my university huge upload bandwith to upload <span class="caps">2GB</span> in +20mn&nbsp;;)</p> +<h2 id="run-the-script-frequently">Run the script&nbsp;frequently</h2> +<p>Once that done, you just need to run the unison command line some times +when you want to sync your two machines. I&#8217;ve wrote a tiny script to get +some feedback from the&nbsp;sync:</p> +<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">os</span> +<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span> + +<span class="n">DEFAULT_LOGFILE</span> <span class="o">=</span> <span class="s2">&quot;~/unison.log&quot;</span> +<span class="n">PROGRAM_NAME</span> <span class="o">=</span> <span class="s2">&quot;Unison syncer&quot;</span> + +<span class="k">def</span> <span class="nf">sync</span><span class="p">(</span><span class="n">logfile</span><span class="o">=</span><span class="n">DEFAULT_LOGFILE</span><span class="p">,</span> <span class="n">program_name</span><span class="o">=</span><span class="n">PROGRAM_NAME</span><span class="p">):</span> + <span class="c1"># init</span> + <span class="n">display_message</span> <span class="o">=</span> <span class="kc">True</span> + <span class="n">error</span> <span class="o">=</span> <span class="kc">False</span> + + <span class="n">before</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> + <span class="c1"># call unison to make the sync</span> + <span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">&#39;unison -batch &gt; </span><span class="si">{0}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">logfile</span><span class="p">))</span> + + <span class="c1"># get the duration of the operation</span> + <span class="n">td</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">before</span> + <span class="n">delta</span> <span class="o">=</span> <span class="p">(</span><span class="n">td</span><span class="o">.</span><span class="n">microseconds</span> <span class="o">+</span> <span class="p">(</span><span class="n">td</span><span class="o">.</span><span class="n">seconds</span> <span class="o">+</span> <span class="n">td</span><span class="o">.</span><span class="n">days</span> <span class="o">*</span> <span class="mi">24</span> <span class="o">*</span> <span class="mi">3600</span><span class="p">)</span> <span class="o">*</span> <span class="mi">10</span><span class="o">**</span><span class="mi">6</span><span class="p">)</span> <span class="o">/</span> <span class="mi">10</span><span class="o">**</span><span class="mi">6</span> + + <span class="c1"># check what was the last entry in the log</span> + <span class="n">log</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="n">logfile</span><span class="p">))</span> + <span class="n">lines</span> <span class="o">=</span> <span class="n">log</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span> + <span class="k">if</span> <span class="s1">&#39;No updates to propagate&#39;</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span> + <span class="n">display_message</span> <span class="o">=</span> <span class="kc">False</span> + <span class="k">else</span><span class="p">:</span> + <span class="n">output</span> <span class="o">=</span> <span class="p">[</span><span class="n">l</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">lines</span> <span class="k">if</span> <span class="s2">&quot;Synchronization&quot;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">]</span> + + <span class="n">message</span> <span class="o">=</span> <span class="n">output</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> + <span class="n">message</span> <span class="o">+=</span> <span class="s2">&quot; It took </span><span class="si">{0}</span><span class="s2">s.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">delta</span><span class="p">)</span> + + <span class="k">if</span> <span class="n">display_message</span><span class="p">:</span> + <span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">&#39;notify-send -i </span><span class="si">{2}</span><span class="s1"> &quot;</span><span class="si">{0}</span><span class="s1">&quot; &quot;</span><span class="si">{1}</span><span class="s1">&quot;&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">program_name</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> + <span class="s1">&#39;error&#39;</span> <span class="k">if</span> <span class="n">error</span> <span class="k">else</span> <span class="s1">&#39;info&#39;</span><span class="p">))</span> + +<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span> + <span class="n">sync</span><span class="p">()</span> +</code></pre></div> + +<p>This is probably perfectible, but that does the&nbsp;job.</p> +<p>Last step is to tell you machine to run that frequently. That&#8217;s what +crontab is made for, so let&#8217;s <code>crontab -e</code>:</p> +<div class="highlight"><pre><span></span><code> $ * */3 * * * . ~/.Xdbus; /usr/bin/python /home/alexis/dev/python/unison-syncer/sync.py +</code></pre></div> + +<p>The \~/.Xdbus allows cron to communicate with your X11 session. Here is +its&nbsp;content.</p> +<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span> + +<span class="c1"># Get the pid of nautilus</span> +<span class="nv">nautilus_pid</span><span class="o">=</span><span class="k">$(</span>pgrep<span class="w"> </span>-u<span class="w"> </span><span class="nv">$LOGNAME</span><span class="w"> </span>-n<span class="w"> </span>nautilus<span class="k">)</span> + +<span class="c1"># If nautilus isn&#39;t running, just exit silently</span> +<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>-z<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$nautilus_pid</span><span class="s2">&quot;</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span> +<span class="nb">exit</span><span class="w"> </span><span class="m">0</span> +<span class="k">fi</span> + +<span class="c1"># Grab the DBUS_SESSION_BUS_ADDRESS variable from nautilus&#39;s environment</span> +<span class="nb">eval</span><span class="w"> </span><span class="k">$(</span>tr<span class="w"> </span><span class="s1">&#39;\0&#39;</span><span class="w"> </span><span class="s1">&#39;\n&#39;</span><span class="w"> </span>&lt;<span class="w"> </span>/proc/<span class="nv">$nautilus_pid</span>/environ<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s1">&#39;^DBUS_SESSION_BUS_ADDRESS=&#39;</span><span class="k">)</span> + +<span class="c1"># Check that we actually found it</span> +<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>-z<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$DBUS_SESSION_BUS_ADDRESS</span><span class="s2">&quot;</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span> +<span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;Failed to find bus address&quot;</span><span class="w"> </span>&gt;<span class="p">&amp;</span><span class="m">2</span> +<span class="nb">exit</span><span class="w"> </span><span class="m">1</span> +<span class="k">fi</span> + +<span class="c1"># export it so that child processes will inherit it</span> +<span class="nb">export</span><span class="w"> </span>DBUS_SESSION_BUS_ADDRESS +</code></pre></div> + +<p>And it comes from +<a href="http://ubuntuforums.org/showthread.php?p=10148738#post10148738">here</a>.</p> +<p>A sync takes about 20s + the upload time on my machine, which stay +acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html +<p>Finally, thanks to a bunch of people that helped me to pay my train and +bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and +it was very productive. Here&#8217;s a taste …</p> +<p>Finally, thanks to a bunch of people that helped me to pay my train and +bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and +it was very productive. Here&#8217;s a taste of what we&#8217;ve been working&nbsp;on:</p> +<ul> +<li>the datafiles, a way to specify and to handle the installation of + files which are not python-related (pictures, manpages and so&nbsp;on).</li> +<li>mkgcfg, a tool to help you to create a setup.cfg in minutes (and + with funny&nbsp;examples)</li> +<li>converters from setup.py scripts. We do now have a piece of code + which reads your current setup.py file and fill in some fields in + the setup.cfg for&nbsp;you.</li> +<li>a compatibility layer for distutils1, so it can read the setup.cfg + you will wrote for distutils2&nbsp;:-)</li> +<li>the uninstaller, so it&#8217;s now possible to uninstall what have been + installed by distutils2 (see <span class="caps">PEP</span>&nbsp;376)</li> +<li>the installer, and the setuptools compatibility layer, which will + allow you to rely on setuptools&#8217; based distributions (and there are + plenty of&nbsp;them!)</li> +<li>The compilers, so they are more flexible than they were. Since + that&#8217;s an obscure part of the code for distutils2 commiters (it + comes directly from the distutils1 ages), having some guys who + understood the problematics here was a&nbsp;must.</li> +</ul> +<p>Some people have also tried to port their packaging from distutils1 to +distutils2. They have spotted a number of bugs and made some +improvements to the code, to make it more friendly to&nbsp;use.</p> +<p>I&#8217;m really pleased to see how newcomers went trough the code, and +started hacking so fast. I must say it wasn&#8217;t the case when we started +to work on distutils1 so that&#8217;s a very good point: people now can hack +the code quicker than they could&nbsp;before.</p> +<p>Some of the features here are not <em>completely</em> finished yet, but are on +the tubes, and will be ready for a release (hopefully) at the end of the&nbsp;week.</p> +<p>Big thanks to logilab for hosting (and sponsoring my train ticket) and +providing us food, and to bearstech for providing some money for +breakfast and&nbsp;bears^Wbeers.</p> +<p>Again, a big thanks to all the people who gave me money to pay the +transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html +<p>By now, there are two ways to retrieve data from PyPI (the Python +Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The +simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several +existing&nbsp;drawbacks.</p> +<p>Basically, if you want to …</p> +<p>By now, there are two ways to retrieve data from PyPI (the Python +Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The +simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several +existing&nbsp;drawbacks.</p> +<p>Basically, if you want to use informations coming from the simple <span class="caps">API</span>, +you will have to parse web pages manually, to extract informations using +some black vodoo magic. Badly, magic have a price, and it&#8217;s sometimes +impossible to get exactly the informations you want to get from this +index. That&#8217;s the technique currently being used by distutils2, +setuptools and&nbsp;pip.</p> +<p>On the other side, while <span class="caps">XML</span>/<span class="caps">RPC</span> is working fine, it&#8217;s requiring extra +work to the python servers each time you request something, which can +lead to some outages from time to time. Also, it&#8217;s important to point +out that, even if PyPI have a mirroring infrastructure, it&#8217;s only for +the so-called <em>simple</em> <span class="caps">API</span>, and not for the <span class="caps">XML</span>/<span class="caps">RPC</span>.</p> +<h2 id="couchdb">CouchDB</h2> +<p>Here comes CouchDB. CouchDB is a document oriented database, that knows +how to speak <span class="caps">REST</span> and <span class="caps">JSON</span>. It&#8217;s easy to use, and provides out of the +box a replication&nbsp;mechanism.</p> +<h2 id="so-what">So, what&nbsp;?</h2> +<p>Hmm, I&#8217;m sure you got it. I&#8217;ve wrote a piece of software to link +informations from PyPI to a CouchDB instance. Then you can replicate all +the PyPI index with only one <span class="caps">HTTP</span> request on the CouchDB server. You can +also access the informations from the index directly using a <span class="caps">REST</span> <span class="caps">API</span>, +speaking json.&nbsp;Handy.</p> +<p>So PyPIonCouch is using the PyPI <span class="caps">XML</span>/<span class="caps">RPC</span> <span class="caps">API</span> to get data from PyPI, and +generate records in the CouchDB&nbsp;instance.</p> +<p>The final goal is to avoid to rely on this &#8220;simple&#8221; <span class="caps">API</span>, and rely on a +<span class="caps">REST</span> insterface instead. I have set up a couchdb server on my server, +which is available at +<a href="http://couchdb.notmyidea.org/_utils/database.html?pypi">http://couchdb.notmyidea.org/_utils/database.html?pypi</a>.</p> +<p>There is not a lot to see there for now, but I&#8217;ve done the first import +from PyPI yesterday and all went fine: it&#8217;s possible to access the +metadata of all PyPI projects via a <span class="caps">REST</span> interface. Next step is to +write a client for this <span class="caps">REST</span> interface in&nbsp;distutils2.</p> +<h2 id="example">Example</h2> +<p>For now, you can use pypioncouch via the command line, or via the python +<span class="caps">API</span>.</p> +<h3 id="using-the-command-line">Using the command&nbsp;line</h3> +<p>You can do something like that for a full import. This <strong>will</strong> take +long, because it&#8217;s fetching all the projects at pypi and importing their&nbsp;metadata:</p> +<div class="highlight"><pre><span></span><code><span class="err">$</span> <span class="n">pypioncouch</span> <span class="o">--</span><span class="n">fullimport</span> <span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">your</span><span class="o">.</span><span class="n">couchdb</span><span class="o">.</span><span class="n">instance</span><span class="o">/</span> +</code></pre></div> + +<p>If you already have the data on your couchdb instance, you can just +update it with the last informations from pypi. <strong>However, I recommend +to just replicate the principal node, hosted at +<a href="http://couchdb.notmyidea.org/pypi/">http://couchdb.notmyidea.org/pypi/</a></strong>, to avoid the duplication of&nbsp;nodes:</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pypioncouch<span class="w"> </span>--update<span class="w"> </span>http://your.couchdb.instance/ +</code></pre></div> + +<p>The principal node is updated once a day by now, I&#8217;ll try to see if it&#8217;s +enough, and ajust with the&nbsp;time.</p> +<h3 id="using-the-python-api">Using the python <span class="caps">API</span></h3> +<p>You can also use the python <span class="caps">API</span> to interact with&nbsp;pypioncouch:</p> +<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">pypioncouch</span> <span class="kn">import</span> <span class="n">XmlRpcImporter</span><span class="p">,</span> <span class="n">import_all</span><span class="p">,</span> <span class="n">update</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">full_import</span><span class="p">()</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">update</span><span class="p">()</span> +</code></pre></div> + +<h2 id="whats-next">What&#8217;s next&nbsp;?</h2> +<p>I want to make a couchapp, in order to navigate PyPI easily. Here are +some of the features I want to&nbsp;propose:</p> +<ul> +<li>List all the available&nbsp;projects</li> +<li>List all the projects, filtered by&nbsp;specifiers</li> +<li>List all the projects by&nbsp;author/maintainer</li> +<li>List all the projects by&nbsp;keywords</li> +<li>Page for each&nbsp;project.</li> +<li>Provide a PyPI &#8220;Simple&#8221; <span class="caps">API</span> equivalent, even if I want to replace + it, I do think it will be really easy to setup mirrors that way, + with the out of the box couchdb&nbsp;replication</li> +</ul> +<p>I also still need to polish the import mechanism, so I can directly +store in&nbsp;couchdb:</p> +<ul> +<li>The <span class="caps">OPML</span> files for each&nbsp;project</li> +<li>The upload_time as couchdb friendly format (list of&nbsp;int)</li> +<li>The tags as lists (currently it&#8217;s only a string separated by&nbsp;spaces</li> +</ul> +<p>The work I&#8217;ve done by now is available on +<a href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it&#8217;s +still a work in progress, and everything can break at any time. However, +any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html +<p><strong>Edit: Thanks to logilab and some amazing people, I can make it to +paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> +<p>There will be a distutils2 sprint from the 27th to the 30th of january, +thanks to logilab which will host the&nbsp;event.</p> +<p>You can find more …</p> +<p><strong>Edit: Thanks to logilab and some amazing people, I can make it to +paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> +<p>There will be a distutils2 sprint from the 27th to the 30th of january, +thanks to logilab which will host the&nbsp;event.</p> +<p>You can find more informations about the sprint on the wiki page of the +event (<a href="http://wiki.python.org/moin/Distutils/SprintParis">http://wiki.python.org/moin/Distutils/SprintParis</a>).</p> +<p>I really want to go there but I&#8217;m unfortunately blocked in <span class="caps">UK</span> for money +reasons. The cheapest two ways I&#8217;ve found is about £80, which I can&#8217;t +afford. Following some advices on #distutils, I&#8217;ve set up a ChipIn +account for that, so if some people want to help me making it to go +there, they can give me some money that&nbsp;way.</p> +<p>I&#8217;ll probably work on the installer (to support old distutils and +setuptools distributions) and on the uninstaller (depending on the first +task). If I can&#8217;t make it to paris, I&#8217;ll hang around on <span class="caps">IRC</span> to give some +help while&nbsp;needed.</p> +<p>If you want to contribute some money to help me go there, feel free to +use this chipin page: +<a href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> +<p>Thanks for your support&nbsp;!</p>How to reboot your bebox using the CLI2010-10-21T00:00:00+02:002010-10-21T00:00:00+02:00tag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.html +<p>I&#8217;ve an internet connection which, for some obscure reasons, tend to be +very slow from time to time. After rebooting the box (yes, that&#8217;s a hard +solution), all the things seems to go fine&nbsp;again.</p> +<h2 id="edit-using-grep"><span class="caps">EDIT</span> : Using&nbsp;grep</h2> +<p>After a bit of reflexion, that&#8217;s also really easy …</p> +<p>I&#8217;ve an internet connection which, for some obscure reasons, tend to be +very slow from time to time. After rebooting the box (yes, that&#8217;s a hard +solution), all the things seems to go fine&nbsp;again.</p> +<h2 id="edit-using-grep"><span class="caps">EDIT</span> : Using&nbsp;grep</h2> +<p>After a bit of reflexion, that&#8217;s also really easy to do using directly +the command line tools curl, grep and tail (but really harder to&nbsp;read).</p> +<div class="highlight"><pre><span></span><code>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>-u<span class="w"> </span>joel:joel<span class="w"> </span>http://bebox.config/cgi/b/info/restart/<span class="se">\?</span>be<span class="se">\=</span><span class="m">0</span><span class="se">\&amp;</span>l0<span class="se">\=</span><span class="m">1</span><span class="se">\&amp;</span>l1<span class="se">\=</span><span class="m">0</span><span class="se">\&amp;</span>tid<span class="se">\=</span>RESTART<span class="w"> </span>-d<span class="w"> </span><span class="s2">&quot;0=17&amp;2=`curl -u joel:joel http://bebox.config/cgi/b/info/restart/\?be\=0\&amp;l0\=1\&amp;l1\=0\&amp;tid\=RESTART | grep -o &quot;</span><span class="nv">name</span><span class="o">=</span><span class="s1">&#39;2&#39;</span><span class="w"> </span><span class="nv">value</span><span class="o">=</span><span class="err">&#39;</span><span class="o">[</span><span class="m">0</span>-9<span class="o">]</span><span class="se">\+</span><span class="s2">&quot; | grep -o &quot;</span><span class="o">[</span><span class="m">0</span>-9<span class="o">]</span><span class="se">\+</span><span class="s2">&quot; | tail -n 1`&amp;1&quot;</span> +</code></pre></div> + +<h2 id="the-python-version">The Python&nbsp;version</h2> +<p>Well, that&#8217;s not the optimal solution, that&#8217;s a bit &#8220;gruik&#8221;, but it&nbsp;works.</p> +<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">urllib2</span> +<span class="kn">import</span> <span class="nn">urlparse</span> +<span class="kn">import</span> <span class="nn">re</span> +<span class="kn">import</span> <span class="nn">argparse</span> + +<span class="n">REBOOT_URL</span> <span class="o">=</span> <span class="s1">&#39;/b/info/restart/?be=0&amp;l0=1&amp;l1=0&amp;tid=RESTART&#39;</span> +<span class="n">BOX_URL</span> <span class="o">=</span> <span class="s1">&#39;http://bebox.config/cgi&#39;</span> + +<span class="k">def</span> <span class="nf">open_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span> + <span class="n">passman</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">HTTPPasswordMgrWithDefaultRealm</span><span class="p">()</span> + <span class="n">passman</span><span class="o">.</span><span class="n">add_password</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span> + <span class="n">authhandler</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">HTTPBasicAuthHandler</span><span class="p">(</span><span class="n">passman</span><span class="p">)</span> + + <span class="n">opener</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">build_opener</span><span class="p">(</span><span class="n">authhandler</span><span class="p">)</span> + + <span class="n">urllib2</span><span class="o">.</span><span class="n">install_opener</span><span class="p">(</span><span class="n">opener</span><span class="p">)</span> + + <span class="k">return</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> + +<span class="k">def</span> <span class="nf">reboot</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span> + <span class="n">data</span> <span class="o">=</span> <span class="n">open_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span> + <span class="n">token</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="s2">&quot;name\=</span><span class="se">\\</span><span class="s2">&#39;2</span><span class="se">\\</span><span class="s2">&#39; value=</span><span class="se">\\</span><span class="s2">&#39;([0-9]+)</span><span class="se">\\</span><span class="s2">&#39;&quot;</span><span class="p">,</span> <span class="n">data</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> + <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">urllib2</span><span class="o">.</span><span class="n">Request</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;0=17&amp;2=</span><span class="si">%s</span><span class="s1">&amp;1&#39;</span> <span class="o">%</span> <span class="n">token</span><span class="p">))</span> + +<span class="k">if</span> <span class="vm">__file__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span> + <span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;&quot;&quot;Reboot your bebox !&quot;&quot;&quot;</span><span class="p">)</span> + + <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="n">dest</span><span class="o">=</span><span class="s1">&#39;user&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;username&#39;</span><span class="p">)</span> + <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="n">dest</span><span class="o">=</span><span class="s1">&#39;password&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;password&#39;</span><span class="p">)</span> + <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="n">boxurl</span><span class="o">=</span><span class="s1">&#39;boxurl&#39;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">BOX_URL</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;Base box url. Default is </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">BOX_URL</span><span class="p">)</span> + + <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> + <span class="n">url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="o">.</span><span class="n">urljoin</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">boxurl</span><span class="p">,</span> <span class="n">REBOOT_URL</span><span class="p">)</span> + <span class="n">reboot</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> +</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html +<p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s +not so easy, and you can&#8217;t just tell: use the pictures in this folder to +do&nbsp;so.</p> +<p>You can have a look to the git repository if you want: +<a href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau …</a></p> +<p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s +not so easy, and you can&#8217;t just tell: use the pictures in this folder to +do&nbsp;so.</p> +<p>You can have a look to the git repository if you want: +<a href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some time ago, I&#8217;ve made a little python script to ease that, and you +can now use it too. It&#8217;s named &#8220;gnome-background-generator&#8221;, and you can +install it via pip for&nbsp;instance.</p> +<div class="highlight"><pre><span></span><code>shell +$ pip install gnome-background-generator +</code></pre></div> + +<p>Then, you have just to use it this&nbsp;way:</p> +<div class="highlight"><pre><span></span><code><span class="n">shell</span> +<span class="n">$ gnome-background-generator -p ~/Images/walls -s</span> +<span class="n">/home/alexis/Images/walls/dynamic-wallpaper.xml generated</span> +</code></pre></div> + +<p>Here is a extract of the&nbsp;`&#8212;help`:</p> +<div class="highlight"><pre><span></span><code><span class="n">shell</span> +<span class="o">$</span><span class="w"> </span><span class="n">gnome</span><span class="o">-</span><span class="n">background</span><span class="o">-</span><span class="n">generator</span><span class="w"> </span><span class="o">--</span><span class="n">help</span> +<span class="n">usage</span><span class="p">:</span><span class="w"> </span><span class="n">gnome</span><span class="o">-</span><span class="n">background</span><span class="o">-</span><span class="n">generator</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">h</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">p</span><span class="w"> </span><span class="n">PATH</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="n">OUTPUT</span><span class="p">]</span> +<span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">t</span><span class="w"> </span><span class="n">TRANSITION_TIME</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">d</span><span class="w"> </span><span class="n">DISPLAY_TIME</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">s</span><span class="p">]</span> +<span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">b</span><span class="p">]</span> + +<span class="n">A</span><span class="w"> </span><span class="n">simple</span><span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="k">tool</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">generate</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">XML</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">gnome</span> +<span class="n">wallpapers</span><span class="p">,</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">dynamic</span><span class="w"> </span><span class="n">walls</span> + +<span class="n">optional</span><span class="w"> </span><span class="n">arguments</span><span class="p">:</span> +<span class="w"> </span><span class="o">-</span><span class="n">h</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">help</span><span class="w"> </span><span class="n">show</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">help</span><span class="w"> </span><span class="n">message</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">exit</span> +<span class="w"> </span><span class="o">-</span><span class="n">p</span><span class="w"> </span><span class="n">PATH</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">path</span><span class="w"> </span><span class="n">PATH</span><span class="w"> </span><span class="n">Path</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">look</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">pictures</span><span class="o">.</span><span class="w"> </span><span class="n">If</span><span class="w"> </span><span class="n">no</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="k">is</span> +<span class="w"> </span><span class="n">specified</span><span class="p">,</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">used</span><span class="w"> </span><span class="n">too</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">outputing</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">dynamic</span><span class="o">-</span> +<span class="w"> </span><span class="n">wallpaper</span><span class="o">.</span><span class="n">xml</span><span class="w"> </span><span class="n">file</span><span class="o">.</span><span class="w"> </span><span class="n">Default</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">current</span> +<span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="p">(</span><span class="o">.</span><span class="p">)</span> +<span class="w"> </span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="n">OUTPUT</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">output</span><span class="w"> </span><span class="n">OUTPUT</span> +<span class="w"> </span><span class="n">Output</span><span class="w"> </span><span class="n">filename</span><span class="o">.</span><span class="w"> </span><span class="n">If</span><span class="w"> </span><span class="n">no</span><span class="w"> </span><span class="n">filename</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">specified</span><span class="p">,</span><span class="w"> </span><span class="n">a</span> +<span class="w"> </span><span class="n">dynamic</span><span class="o">-</span><span class="n">wallpaper</span><span class="o">.</span><span class="n">xml</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">generated</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">the</span> +<span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="n">containing</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">pictures</span><span class="o">.</span><span class="w"> </span><span class="n">You</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">also</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="s2">&quot;-&quot;</span><span class="w"> </span><span class="n">to</span> +<span class="w"> </span><span class="n">display</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">xml</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">stdout</span><span class="o">.</span> +<span class="w"> </span><span class="o">-</span><span class="n">t</span><span class="w"> </span><span class="n">TRANSITION_TIME</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">transition</span><span class="o">-</span><span class="n">time</span><span class="w"> </span><span class="n">TRANSITION_TIME</span> +<span class="w"> </span><span class="n">Time</span><span class="w"> </span><span class="p">(</span><span class="ow">in</span><span class="w"> </span><span class="n">seconds</span><span class="p">)</span><span class="w"> </span><span class="n">transitions</span><span class="w"> </span><span class="n">must</span><span class="w"> </span><span class="n">last</span><span class="w"> </span><span class="p">(</span><span class="n">default</span><span class="w"> </span><span class="n">value</span> +<span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">seconds</span><span class="p">)</span> +<span class="w"> </span><span class="o">-</span><span class="n">d</span><span class="w"> </span><span class="n">DISPLAY_TIME</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">display</span><span class="o">-</span><span class="n">time</span><span class="w"> </span><span class="n">DISPLAY_TIME</span> +<span class="w"> </span><span class="n">Time</span><span class="w"> </span><span class="p">(</span><span class="ow">in</span><span class="w"> </span><span class="n">seconds</span><span class="p">)</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">picture</span><span class="w"> </span><span class="n">must</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">displayed</span><span class="o">.</span><span class="w"> </span><span class="n">Default</span> +<span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="mi">900</span><span class="w"> </span><span class="p">(</span><span class="mi">15</span><span class="n">mn</span><span class="p">)</span> +<span class="w"> </span><span class="o">-</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">set</span><span class="o">-</span><span class="n">background</span><span class="w"> </span><span class="s1">&#39;&#39;&#39;try to set the background using gnome-appearance-</span> +<span class="s1"> properties</span> +<span class="s1"> -b, --debug</span> +</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html +<ul> +<li> +<p>date<br>&nbsp;2010-10-10</p> +</li> +<li> +<p>category<br>&nbsp;tech</p> +</li> +</ul> +<p>I&#8217;ve not managed so far to get completely rid of php, so here&#8217;s a simple +reminder about how to install php on <span class="caps">NGINX</span>, for FreeBSD. Nothing hard, +but that&#8217;s worse to have the piece of configuration somewhere&nbsp;!</p> +<div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="nx">update</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">ports</span> +<span class="err">$</span><span class="w"> </span><span class="nx">portsnap</span><span class="w"> </span><span class="nx">fetch</span><span class="w"> </span><span class="nx">update …</span></code></pre></div> +<ul> +<li> +<p>date<br>&nbsp;2010-10-10</p> +</li> +<li> +<p>category<br>&nbsp;tech</p> +</li> +</ul> +<p>I&#8217;ve not managed so far to get completely rid of php, so here&#8217;s a simple +reminder about how to install php on <span class="caps">NGINX</span>, for FreeBSD. Nothing hard, +but that&#8217;s worse to have the piece of configuration somewhere&nbsp;!</p> +<div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="nx">update</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">ports</span> +<span class="err">$</span><span class="w"> </span><span class="nx">portsnap</span><span class="w"> </span><span class="nx">fetch</span><span class="w"> </span><span class="nx">update</span> + +<span class="err">#</span><span class="w"> </span><span class="nx">install</span><span class="w"> </span><span class="nx">php5</span><span class="w"> </span><span class="nx">port</span> +<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="nx">config</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">lang</span><span class="o">/</span><span class="nx">php5</span><span class="o">-</span><span class="nx">extensions</span> +<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="kn">package</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">lang</span><span class="o">/</span><span class="nx">php5</span><span class="o">-</span><span class="nx">extensions</span> + +<span class="err">#</span><span class="w"> </span><span class="nx">install</span><span class="w"> </span><span class="nx">nginx</span> +<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="nx">config</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">nginx</span><span class="o">-</span><span class="nx">devel</span> +<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="kn">package</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">nginx</span><span class="o">-</span><span class="nx">devel</span> +</code></pre></div> + +<p>Now we have all the dependencies installed, we need to configure a bit +the&nbsp;server.</p> +<p>That&#8217;s a simple thing in fact, but it could be good to have something +that will work without effort over&nbsp;time.</p> +<p>Here&#8217;s a sample of my&nbsp;configuration:</p> +<div class="highlight"><pre><span></span><code><span class="nt">server</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="err">server_name</span><span class="w"> </span><span class="err">ndd</span><span class="p">;</span> +<span class="w"> </span><span class="err">set</span><span class="w"> </span><span class="err">$path</span><span class="w"> </span><span class="err">/path/to/your/files</span><span class="p">;</span> +<span class="w"> </span><span class="err">root</span><span class="w"> </span><span class="err">$path</span><span class="p">;</span> + +<span class="w"> </span><span class="err">location</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="err">{</span> +<span class="w"> </span><span class="err">index</span><span class="w"> </span><span class="err">index.php</span><span class="p">;</span> +<span class="w"> </span><span class="p">}</span> + +<span class="w"> </span><span class="nt">location</span><span class="w"> </span><span class="o">~*</span><span class="w"> </span><span class="o">^.+.(</span><span class="nt">jpg</span><span class="o">|</span><span class="nt">jpeg</span><span class="o">|</span><span class="nt">gif</span><span class="o">|</span><span class="nt">css</span><span class="o">|</span><span class="nt">png</span><span class="o">|</span><span class="nt">js</span><span class="o">|</span><span class="nt">ico</span><span class="o">|</span><span class="nt">xml</span><span class="o">)$</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="err">access_log</span><span class="w"> </span><span class="err">off</span><span class="p">;</span> +<span class="w"> </span><span class="err">expires</span><span class="w"> </span><span class="err">30d</span><span class="p">;</span> +<span class="w"> </span><span class="p">}</span> + +<span class="w"> </span><span class="nt">location</span><span class="w"> </span><span class="o">~</span><span class="w"> </span><span class="p">.</span><span class="nc">php</span><span class="o">$</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="err">fastcgi_param</span><span class="w"> </span><span class="err">SCRIPT_FILENAME</span><span class="w"> </span><span class="err">$path$fastcgi_script_name</span><span class="p">;</span> +<span class="w"> </span><span class="err">fastcgi_pass</span><span class="w"> </span><span class="err">backend</span><span class="p">;</span> +<span class="w"> </span><span class="err">include</span><span class="w"> </span><span class="err">fastcgi_params</span><span class="p">;</span> +<span class="w"> </span><span class="p">}</span> +<span class="err">}</span> + +<span class="nt">upstream</span><span class="w"> </span><span class="nt">backend</span><span class="w"> </span><span class="p">{</span> +<span class="w"> </span><span class="err">server</span><span class="w"> </span><span class="err">127.0.0.1:9000</span><span class="p">;</span> +<span class="p">}</span> +</code></pre></div> + +<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html +<p>Those days, I&#8217;ve wrote a little python application to fit my blogging +needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text +and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> +<p><a href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple +tool …</p> +<p>Those days, I&#8217;ve wrote a little python application to fit my blogging +needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text +and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> +<p><a href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple +tool to generate your blog as static files, letting you using your +editor of choice (vim!). It&#8217;s easy to extend, and has a template +support (via&nbsp;jinja2).</p> +<p>I&#8217;ve made it to fit <em>my</em> needs. I hope it will fit yours, but maybe it +wont, and it have not be designed to feet everyone&#8217;s&nbsp;needs.</p> +<p>Need an example ? You&#8217;re looking at it ! This weblog is using pelican +to be generated, also for the atom&nbsp;feeds.</p> +<p>I&#8217;ve released it under <span class="caps">AGPL</span>, since I want all the modifications to be +profitable to all the&nbsp;users.</p> +<p>You can find a repository to fork at +<a href="https://github.com/getpelican/pelican/">https://github.com/getpelican/pelican/</a>. feel free to hack it&nbsp;!</p> +<p>If you just want to get started, use your installer of choice (pip, +easy_install, …) And then have a look to the help (pelican&nbsp;&#8212;help)</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>pelican +</code></pre></div> + +<h2 id="usage">Usage</h2> +<p>Here&#8217;s a sample usage of&nbsp;pelican</p> +<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pelican<span class="w"> </span>. +writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/index.html +writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/tags.html +writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/categories.html +writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/archives.html +writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/category/python.html +writing +/home/alexis/projets/notmyidea.org/output/pelican-a-simple-static-blog-generator-in-python.html +Done<span class="w"> </span>! +</code></pre></div> + +<p>You also can use the &#8212;help option for the command line to get more&nbsp;informations</p> +<div class="highlight"><pre><span></span><code><span class="nv">$pelican</span><span class="w"> </span>--help +usage:<span class="w"> </span>pelican<span class="w"> </span><span class="o">[</span>-h<span class="o">]</span><span class="w"> </span><span class="o">[</span>-t<span class="w"> </span>TEMPLATES<span class="o">]</span><span class="w"> </span><span class="o">[</span>-o<span class="w"> </span>OUTPUT<span class="o">]</span><span class="w"> </span><span class="o">[</span>-m<span class="w"> </span>MARKUP<span class="o">]</span><span class="w"> </span><span class="o">[</span>-s<span class="w"> </span>SETTINGS<span class="o">]</span><span class="w"> </span><span class="o">[</span>-b<span class="o">]</span> +<span class="w"> </span>path + +A<span class="w"> </span>tool<span class="w"> </span>to<span class="w"> </span>generate<span class="w"> </span>a<span class="w"> </span>static<span class="w"> </span>blog,<span class="w"> </span>with<span class="w"> </span>restructured<span class="w"> </span>text<span class="w"> </span>input<span class="w"> </span>files. + +positional<span class="w"> </span>arguments: +<span class="w"> </span>path<span class="w"> </span>Path<span class="w"> </span>where<span class="w"> </span>to<span class="w"> </span>find<span class="w"> </span>the<span class="w"> </span>content<span class="w"> </span>files<span class="w"> </span><span class="o">(</span>default<span class="w"> </span>is +<span class="w"> </span><span class="s2">&quot;content&quot;</span><span class="o">)</span>. + +optional<span class="w"> </span>arguments: +<span class="w"> </span>-h,<span class="w"> </span>--help<span class="w"> </span>show<span class="w"> </span>this<span class="w"> </span><span class="nb">help</span><span class="w"> </span>message<span class="w"> </span>and<span class="w"> </span><span class="nb">exit</span> +<span class="w"> </span>-t<span class="w"> </span>TEMPLATES,<span class="w"> </span>--templates-path<span class="w"> </span>TEMPLATES +<span class="w"> </span>Path<span class="w"> </span>where<span class="w"> </span>to<span class="w"> </span>find<span class="w"> </span>the<span class="w"> </span>templates.<span class="w"> </span>If<span class="w"> </span>not<span class="w"> </span>specified, +<span class="w"> </span>will<span class="w"> </span>uses<span class="w"> </span>the<span class="w"> </span>ones<span class="w"> </span>included<span class="w"> </span>with<span class="w"> </span>pelican. +<span class="w"> </span>-o<span class="w"> </span>OUTPUT,<span class="w"> </span>--output<span class="w"> </span>OUTPUT +<span class="w"> </span>Where<span class="w"> </span>to<span class="w"> </span>output<span class="w"> </span>the<span class="w"> </span>generated<span class="w"> </span>files.<span class="w"> </span>If<span class="w"> </span>not<span class="w"> </span>specified, +<span class="w"> </span>a<span class="w"> </span>directory<span class="w"> </span>will<span class="w"> </span>be<span class="w"> </span>created,<span class="w"> </span>named<span class="w"> </span><span class="s2">&quot;output&quot;</span><span class="w"> </span><span class="k">in</span><span class="w"> </span>the +<span class="w"> </span>current<span class="w"> </span>path. +<span class="w"> </span>-m<span class="w"> </span>MARKUP,<span class="w"> </span>--markup<span class="w"> </span>MARKUP +<span class="w"> </span>the<span class="w"> </span>markup<span class="w"> </span>language<span class="w"> </span>to<span class="w"> </span>use.<span class="w"> </span>Currently<span class="w"> </span>only +<span class="w"> </span>ReSTreucturedtext<span class="w"> </span>is<span class="w"> </span>available. +<span class="w"> </span>-s<span class="w"> </span>SETTINGS,<span class="w"> </span>--settings<span class="w"> </span>SETTINGS +<span class="w"> </span>the<span class="w"> </span>settings<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>application.<span class="w"> </span>Default<span class="w"> </span>to<span class="w"> </span>None. +<span class="w"> </span>-b,<span class="w"> </span>--debug +</code></pre></div> + +<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html +<p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent +working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It +was a really amazing experience, for many&nbsp;reasons.</p> +<p>First of all, we had a very good team, we were 5 students working on +distutils2: <a href="http://zubin71.wordpress.com">Zubin</a>, +<a href="http://wokslog.wordpress.com/">Éric</a>, +<a href="http://gsoc.djolonga.com/">Josip</a>, +<a href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a href="http://mouadino.blogspot.com/">Mouad</a> have worked on …</p> +<p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent +working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It +was a really amazing experience, for many&nbsp;reasons.</p> +<p>First of all, we had a very good team, we were 5 students working on +distutils2: <a href="http://zubin71.wordpress.com">Zubin</a>, +<a href="http://wokslog.wordpress.com/">Éric</a>, +<a href="http://gsoc.djolonga.com/">Josip</a>, +<a href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a href="http://mouadino.blogspot.com/">Mouad</a> have worked on the PyPI testing +infrastructure. You could find what each person have done on <a href="http://bitbucket.org/tarek/distutils2/wiki/GSoC_2010_teams">the wiki +page of +distutils2</a>.</p> +<p>We were in contact with each others really often, helping us when +possible (in #distutils), and were continuously aware of the state of +the work of each participant. This, in my opinion, have bring us in a +good&nbsp;shape.</p> +<p>Then, I&#8217;ve learned a lot. Python packaging was completely new to me at +the time of the GSoC start, and I was pretty unfamiliar with python good +practices too, as I&#8217;ve been introducing myself to python in the late&nbsp;2009.</p> +<p>I&#8217;ve recently looked at some python code I wrote just three months ago, +and I was amazed to think about many improvements to made on it. I guess +this is a good indicator of the path I&#8217;ve traveled since I wrote&nbsp;it.</p> +<p>This summer was awesome because I&#8217;ve learned about python good +practices, now having some strong +<a href="http://mercurial.selenic.com/">mercurial</a> knowledge, and I&#8217;ve seen a +little how the python community&nbsp;works.</p> +<p>Then, I would like to say a big thanks to all the mentors that have +hanged around while needed, on <span class="caps">IRC</span> or via mail, and especially my mentor +for this summer, <a href="http://tarek.ziade.org">Tarek Ziadé</a>.</p> +<p>Thanks a lot for your motivation, your leadership and your cheerfulness, +even with a new-born and a new&nbsp;work!</p> +<h2 id="why">Why&nbsp;?</h2> +<p>I wanted to work on python packaging because, as the time pass, we were +having a sort of complex tools in this field. Each one wanted to add +features to distutils, but not in a standard&nbsp;way.</p> +<p>Now, we have PEPs that describes some format we agreed on (see <span class="caps">PEP</span> 345), +and we wanted to have a tool on which users can base their code on, +that&#8217;s <a href="http://hg.python.org/distutils2/">distutils2</a>.</p> +<h2 id="my-job">My&nbsp;job</h2> +<p>I had to provide a way to crawl the PyPI indexes in a simple way, and do +some installation / uninstallation&nbsp;scripts.</p> +<p>All the work done is available in <a href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket +repository</a>.</p> +<h3 id="crawling-the-pypi-indexes">Crawling the PyPI&nbsp;indexes</h3> +<p>There are two ways of requesting informations from the indexes: using +the &#8220;simple&#8221; index, that is a kind of <span class="caps">REST</span> index, and using <span class="caps">XML</span>-<span class="caps">RPC</span>.</p> +<p>I&#8217;ve done the two implementations, and a high level <span class="caps">API</span> to query those +twos. Basically, this supports the mirroring infrastructure defined in +<span class="caps">PEP</span> 381. So far, the work I&#8217;ve done is gonna be used in pip (they&#8217;ve +basically copy/paste the code, but this will change as soon as we get +something completely stable for distutils2), and that&#8217;s a good news, as +it was the main reason for what I&#8217;ve done&nbsp;that.</p> +<p>I&#8217;ve tried to have an unified <span class="caps">API</span> for the clients, to switch from one to +another implementation easily. I&#8217;m already thinking of adding others +crawlers to this stuff, and it was made to be&nbsp;extensible.</p> +<p>If you want to get more informations about the crawlers/PyPI clients, +please refer to the distutils2 documentation, especially <a href="http://distutils2.notmyidea.org/library/distutils2.index.html">the pages +about +indexes</a>.</p> +<p>You can find the changes I made about this in the +<a href="http://hg.python.org/distutils2/">distutils2</a> source code&nbsp;.</p> +<h3 id="installation-uninstallation-scripts">Installation / Uninstallation&nbsp;scripts</h3> +<p>Next step was to think about an installation script, and an uninstaller. +I&#8217;ve not done the uninstaller part, and it&#8217;s a smart part, as it&#8217;s +basically removing some files from the system, so I&#8217;ll probably do it in +a near&nbsp;future.</p> +<p><a href="http://hg.python.org/distutils2/">distutils2</a> provides a way to install +distributions, and to handle dependencies between releases. For now, +this support is only about the last version of the <span class="caps">METADATA</span> (1.2) (See, +the <span class="caps">PEP</span> 345), but I&#8217;m working on a compatibility layer for the old +metadata, and for the informations provided via <span class="caps">PIP</span> requires.txt, for&nbsp;instance.</p> +<h3 id="extra-work">Extra&nbsp;work</h3> +<p>Also, I&#8217;ve done some extra work. this&nbsp;includes:</p> +<ul> +<li>working on the <span class="caps">PEP</span> 345, and having some discussion about it (about + the names of some&nbsp;fields).</li> +<li>writing a PyPI server mock, useful for tests. you can find more + information about it on the + <a href="http://distutils.notmyidea.org">documentation</a>.</li> +</ul> +<h2 id="futures-plans">Futures&nbsp;plans</h2> +<p>As I said, I&#8217;ve enjoyed working on distutils2, and the people I&#8217;ve met +here are really pleasant to work with. So I <em>want</em> to continue +contributing on python, and especially on python packaging, because +there is still a lot of things to do in this scope, to get something +really&nbsp;usable.</p> +<p>I&#8217;m not plainly satisfied by the work I&#8217;ve done, so I&#8217;ll probably tweak +it a bit: the installer part is not yet completely finished, and I want +to add support for a real +<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"><span class="caps">REST</span></a> +index in the&nbsp;future.</p> +<p>We&#8217;ll talk again of this in the next months, probably, but we definitely +need a real +<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"><span class="caps">REST</span></a> <span class="caps">API</span> +for <a href="http://pypi.python.org">PyPI</a>, as the &#8220;simple&#8221; index <em>is</em> an ugly +hack, in my opinion. I&#8217;ll work on a serious proposition about this, +maybe involving <a href="http://couchdb.org">CouchDB</a>, as it seems to be a good +option for what we want&nbsp;here.</p> +<h2 id="issues">Issues</h2> +<p>I&#8217;ve encountered some issues during this summer. The main one is that&#8217;s +hard to work remotely, especially being in the same room that we live, +with others. I like to just think about a project with other people, a +paper and a pencil, no computers. This have been not so possible at the +start of the project, as I needed to read a lot of code to understand +the codebase, and then to read/write&nbsp;emails.</p> +<p>I&#8217;ve finally managed to work in an office, so good point for home/office&nbsp;separation.</p> +<p>I&#8217;d not planned there will be so a high number of emails to read, in +order to follow what&#8217;s up in the python world, and be a part of the +community seems to takes some times to read/write emails, especially for +those (like me) that arent so confortable with english (but this had +brought me some english fu&nbsp;!).</p> +<h2 id="thanks">Thanks&nbsp;!</h2> +<p>A big thanks to <a href="http://www.graine-libre.fr/">Graine Libre</a> and <a href="http://www.makina-corpus.com/">Makina +Corpus</a>, which has offered me to come +into their offices from time to time, to share they cheerfulness ! Many +thanks too to the Google Summer of Code program for setting up such an +initiative. If you&#8217;re a student, if you&#8217;re interested about <span class="caps">FOSS</span>, dont +hesitate any second, it&#8217;s a really good opportunity to work on +interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html +<ul> +<li> +<p>date<br>&nbsp;2010-07-06</p> +</li> +<li> +<p>category<br>&nbsp;tech</p> +</li> +</ul> +<p>Yesterday, as I was traveling to Tours, I&#8217;ve took some time to visit +Éric, another student who&#8217;s working on distutils2 this summer, as a +part of the GSoC. Basically, it was to take a drink, discuss a bit about +distutils2, our respective tasks and …</p> +<ul> +<li> +<p>date<br>&nbsp;2010-07-06</p> +</li> +<li> +<p>category<br>&nbsp;tech</p> +</li> +</ul> +<p>Yesterday, as I was traveling to Tours, I&#8217;ve took some time to visit +Éric, another student who&#8217;s working on distutils2 this summer, as a +part of the GSoC. Basically, it was to take a drink, discuss a bit about +distutils2, our respective tasks and general feelings, and to put a face +on a pseudonym. I&#8217;d really enjoyed this time, because Éric knows a lot +of things about mercurial and python good practices, and I&#8217;m eager to +learn about those. So, we have discussed about things, have not wrote so +much code, but have some things to propose so far, about documentation, +and I also provides here some bribes of conversations we&nbsp;had.</p> +<h2 id="documentation">Documentation</h2> +<p>While writing the PyPI simple index crawler documentation, I realized +that we miss some structure, or how-to about the documentation. Yep, you +read well. We lack documentation on how to make documentation. Heh. +We&#8217;re missing some rules to follow, and this lead to a not-so-structured +final documentation. We probably target three type of publics, and we +can split the documentation regarding&nbsp;those:</p> +<ul> +<li><strong>Packagers</strong> who want to distribute their&nbsp;softwares.</li> +<li><strong>End users</strong> who need to understand how to use end user commands, + like the&nbsp;installer/uninstaller</li> +<li><strong>packaging coders</strong> who <em>use</em> distutils2, as a base for building a + package&nbsp;manager.</li> +</ul> +<p>We also need to discuss about a pattern to follow while writing +documentation. How many parts do we need ? Where to put the <span class="caps">API</span> +description ? etc. That&#8217;s maybe seems to be not so important, but I +guess the readers would appreciate to have the same structure all along +distutils2&nbsp;documentation.</p> +<h2 id="mercurial">Mercurial</h2> +<p>I&#8217;m really <em>not</em> a mercurial power user. I use it on daily basis, but I +lack of basic knowledge about it. Big thanks Éric for sharing yours with +me, you&#8217;re of a great help. We have talked about some mercurial +extensions that seems to make the life simpler, while used the right +way. I&#8217;ve not used them so far, so consider this as a personal&nbsp;note.</p> +<ul> +<li>hg histedit, to edit the&nbsp;history</li> +<li>hg crecord, to select the changes to&nbsp;commit</li> +</ul> +<p>We have spent some time to review a merge I made sunday, to re-merge it, +and commit the changes as a new changeset. Awesome. These things make me +say I <strong>need</strong> to read <a href="http://hgbook.red-bean.com/read/">the hg book</a>, +and will do as soon as I got some spare time: mercurial seems to be +simply great. So &#8230; Great. I&#8217;m a powerful merger now&nbsp;!</p> +<h2 id="on-using-tools">On using&nbsp;tools</h2> +<p>Because we <em>also</em> are <em>hackers</em>, we have shared a bit our ways to code, +the tools we use, etc. Both of us were using vim, and I&#8217;ve discovered +vimdiff and hgtk, which will completely change the way I navigate into +the mercurial history. We aren&#8217;t &#8220;power users&#8221;, so we have learned from +each other about vim tips. You can find <a href="http://github.com/ametaireau/dotfiles">my dotfiles on +github</a>, if it could help. +They&#8217;re not perfect, and not intended to be, because changing all the +time, as I learn. Don&#8217;t hesitate to have a look, and to propose +enhancements if you have&nbsp;!</p> +<h2 id="on-being-pythonic">On being&nbsp;pythonic</h2> +<p>My background as an old Java user disserves me so far, as the paradigms +are not the same while coding in python. Hard to find the more pythonic +way to do, and sometimes hard to unlearn my way to think about software +engineering. Well, it seems that the only solution is to read code, and +to re-read import this from times to times ! <a href="http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html">Coding like a +pythonista</a> +seems to be a must-read, so, I know what to&nbsp;do.</p> +<h2 id="conclusion">Conclusion</h2> +<p>It was really great. Next time, we&#8217;ll need to focus a bit more on +distutils2, and to have a bullet list of things to do, but days like +this one are opportunities to catch ! We&#8217;ll probably do another sprint +in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html +<p>I&#8217;m working for about a month for distutils2, even if I was being a bit +busy (as I had some class courses and exams to work&nbsp;on)</p> +<p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so +far. You can also find, if …</p> +<p>I&#8217;m working for about a month for distutils2, even if I was being a bit +busy (as I had some class courses and exams to work&nbsp;on)</p> +<p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so +far. You can also find, if you&#8217;re interested, my weekly summaries in <a href="http://wiki.notmyidea.org/distutils2_schedule">a +dedicated wiki page</a>.</p> +<h2 id="general-feelings">General&nbsp;feelings</h2> +<p>First, and it&#8217;s a really important point, the GSoC is going very well, +for me as for other students, at least from my perspective. It&#8217;s a +pleasure to work with such enthusiast people, as this make the global +atmosphere very pleasant to&nbsp;live.</p> +<p>First of all, I&#8217;ve spent time to read the existing codebase, and to +understand what we&#8217;re going to do, and what&#8217;s the rationale to do&nbsp;so.</p> +<p>It&#8217;s really clear for me now: what we&#8217;re building is the foundations of +a packaging infrastructure in python. The fact is that many projects +co-exists, and comes all with their good concepts. Distutils2 tries to +take the interesting parts of all, and to provide it in the python +standard libs, respecting the recently written <span class="caps">PEP</span> about&nbsp;packaging.</p> +<p>With distutils2, it will be simpler to make &#8220;things&#8221; compatible. So if +you think about a new way to deal with distributions and packaging in +python, you can use the Distutils2 APIs to do&nbsp;so.</p> +<h2 id="tasks">Tasks</h2> +<p>My main task while working on distutils2 is to provide an installation +and an un-installation command, as described in <span class="caps">PEP</span> 376. For this, I +first need to get informations about the existing distributions (what&#8217;s +their version, name, metadata, dependencies,&nbsp;etc.)</p> +<p>The main index, you probably know and use, is PyPI. You can access it at +<a href="http://pypi.python.org">http://pypi.python.org</a>.</p> +<h2 id="pypi-index-crawling">PyPI index&nbsp;crawling</h2> +<p>There is two ways to get these informations from PyPI: using the simple +<span class="caps">API</span>, or via xml-rpc&nbsp;calls.</p> +<p>A goal was to use the version specifiers defined +in<a href="http://www.python.org/dev/peps/pep-0345/"><span class="caps">PEP</span> 345</a> and to provides a +way to sort the grabbed distributions depending our needs, to pick the +version we&nbsp;want/need.</p> +<h3 id="using-the-simple-api">Using the simple <span class="caps">API</span></h3> +<p>The simple <span class="caps">API</span> is composed of <span class="caps">HTML</span> pages you can access at +<a href="http://pypi.python.org/simple/">http://pypi.python.org/simple/</a>.</p> +<p>Distribute and Setuptools already provides a crawler for that, but it +deals with their internal mechanisms, and I found that the code was not +so clear as I want, that&#8217;s why I&#8217;ve preferred to pick up the good ideas, +and some implementation details, plus re-thinking the global&nbsp;architecture.</p> +<p>The rules are simple: each project have a dedicated page, which allows +us to get informations&nbsp;about:</p> +<ul> +<li>the distribution download locations (for some&nbsp;versions)</li> +<li>homepage&nbsp;links</li> +<li>some other useful informations, as the bugtracker address, for&nbsp;instance.</li> +</ul> +<p>If you want to find all the distributions of the &#8220;EggsAndSpam&#8221; project, +you could do the following (do not take so attention to the names here, +as the <span class="caps">API</span> will probably change a&nbsp;bit):</p> +<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="n">index</span> <span class="o">=</span> <span class="n">SimpleIndex</span><span class="p">()</span> +<span class="o">&gt;&gt;&gt;</span> <span class="n">index</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&quot;EggsAndSpam&quot;</span><span class="p">)</span> +<span class="p">[</span><span class="n">EggsAndSpam</span> <span class="mf">1.1</span><span class="p">,</span> <span class="n">EggsAndSpam</span> <span class="mf">1.2</span><span class="p">,</span> <span class="n">EggsAndSpam</span> <span class="mf">1.3</span><span class="p">]</span> +</code></pre></div> + +<p>We also could use version&nbsp;specifiers:</p> +<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="n">index</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&quot;EggsAndSpam (&lt; =1.2)&quot;</span><span class="p">)</span> +<span class="p">[</span><span class="n">EggsAndSpam</span> <span class="mf">1.1</span><span class="p">,</span> <span class="n">EggsAndSpam</span> <span class="mf">1.2</span><span class="p">]</span> +</code></pre></div> + +<p>Internally, what&#8217;s done here is the&nbsp;following:</p> +<ul> +<li>it process the <a href="http://pypi.python.org/simple/FooBar/">http://pypi.python.org/simple/FooBar/</a> page, + searching for download&nbsp;URLs.</li> +<li>for each found distribution download <span class="caps">URL</span>, it creates an object, + containing informations about the project name, the version and the + <span class="caps">URL</span> where the archive&nbsp;remains.</li> +<li>it sort the found distributions, using version numbers. The default + behavior here is to prefer source distributions (over binary ones), + and to rely on the last &#8220;final&#8221; distribution (rather than beta, + alpha etc.&nbsp;ones)</li> +</ul> +<p>So, nothing hard or difficult&nbsp;here.</p> +<p>We provides a bunch of other features, like relying on the new PyPI +mirroring infrastructure or filter the found distributions by some +criterias. If you&#8217;re curious, please browse the <a href="http://distutils2.notmyidea.org/">distutils2 +documentation</a>.</p> +<h3 id="using-xml-rpc">Using&nbsp;xml-rpc</h3> +<p>We also can make some xmlrpc calls to retreive informations from PyPI. +It&#8217;s a really more reliable way to get informations from from the index +(as it&#8217;s just the index that provides the informations), but cost +processes on the PyPI distant&nbsp;server.</p> +<p>For now, this way of querying the xmlrpc client is not available on +Distutils2, as I&#8217;m working on it. The main pieces are already present +(I&#8217;ll reuse some work I&#8217;ve made from the SimpleIndex querying, and <a href="http://github.com/ametaireau/pypiclient">some +code already set up</a>), what I +need to do is to provide a xml-rpc PyPI mock server, and that&#8217;s on what +I&#8217;m actually working&nbsp;on.</p> +<h2 id="processes">Processes</h2> +<p>For now, I&#8217;m trying to follow the &#8220;documentation, then test, then code&#8221; +path, and that seems to be really needed while working with a community. +Code is hard to read/understand, compared to documentation, and it&#8217;s +easier to&nbsp;change.</p> +<p>While writing the simple index crawling work, I must have done this to +avoid some changes on the <span class="caps">API</span>, and some loss of&nbsp;time.</p> +<p>Also, I&#8217;ve set up <a href="http://wiki.notmyidea.org/distutils2_schedule">a +schedule</a>, and the goal +is to be sure everything will be ready in time, for the end of the +summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html +<ul> +<li> +<p>date<br>&nbsp;2010-06-25</p> +</li> +<li> +<p>category<br>&nbsp;tech</p> +</li> +</ul> +<p>Wednesday, we give a presentation, with some friends, about the CouchDB +Database, to <a href="http://www.toulibre.org">the Toulouse local <span class="caps">LUG</span></a>. Thanks a +lot to all the presents for being there, it was a pleasure to talk about +this topic with you. Too bad the season is over now an …</p> +<ul> +<li> +<p>date<br>&nbsp;2010-06-25</p> +</li> +<li> +<p>category<br>&nbsp;tech</p> +</li> +</ul> +<p>Wednesday, we give a presentation, with some friends, about the CouchDB +Database, to <a href="http://www.toulibre.org">the Toulouse local <span class="caps">LUG</span></a>. Thanks a +lot to all the presents for being there, it was a pleasure to talk about +this topic with you. Too bad the season is over now an I quit Toulouse +next&nbsp;year.</p> +<p>During our brainstorming about the topic, we used some paper, and we +wanted to make a presentation the simpler way. First thing that come to +my mind was using <a href="http://docutils.sourceforge.net/rst.html">restructured +text</a>, so I&#8217;ve wrote a simple +file containing our different bullet points. In fact, there is quite +nothing to do then, to have a working&nbsp;presentation.</p> +<p>So far, I&#8217;ve used <a href="http://code.google.com/p/rst2pdf/">the rst2pdf +program</a>, and a simple template, to +generate output. It&#8217;s probably simple to have similar results using +latex + beamer, I&#8217;ll try this next time, but as I&#8217;m not familiar with +latex syntax, restructured text was a great&nbsp;option.</p> +<p>Here are <a href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.pdf">the final <span class="caps">PDF</span> +output</a>, +<a href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.rst">Rhe ReST +source</a>, +<a href="http://files.lolnet.org/alexis/rst-presentations/slides.style">the theme +used</a>, +and the command line to generate the <span class="caps">PDF</span>:</p> +<div class="highlight"><pre><span></span><code>rst2pdf couchdb.rst -b1 -s ../slides.style +</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html +<p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> +during the past week, taking part of the +<a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short +summary of what I&#8217;ve done so&nbsp;far.</p> +<p>As my courses are not over yet, I&#8217;ve not worked as much as I wanted, and +this will continues until …</p> +<p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> +during the past week, taking part of the +<a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short +summary of what I&#8217;ve done so&nbsp;far.</p> +<p>As my courses are not over yet, I&#8217;ve not worked as much as I wanted, and +this will continues until the end of June. My main tasks are about +making installation and uninstallation commands, to have a simple way to +install distributions via +<a href="http://hg.python.org/distutils2/">Distutils2</a>.</p> +<p>To do this, we need to rely on informations provided by the Python +Package Index (<a href="http://pypi.python.org/">PyPI</a>), and there is at least +two ways to retreive informations from here: <span class="caps">XML</span>-<span class="caps">RPC</span> and the &#8220;simple&#8221; +<span class="caps">API</span>.</p> +<p>So, I&#8217;ve been working on porting some +<a href="http://bitbucket.org/tarek/distribute/">Distribute</a> related stuff to +<a href="http://hg.python.org/distutils2/">Distutils2</a>, cutting off all non +distutils&#8217; things, as we do not want to depend from Distribute&#8217;s +internals. My main work has been about reading the whole code, writing +tests about this and making those tests&nbsp;possible.</p> +<p>In fact, there was a need of a pypi mocked server, and, after reading +and introducing myself to the distutils behaviors and code, I&#8217;ve taken +some time to improve the work <a href="http://bitbucket.org/konrad">Konrad</a> +makes about this&nbsp;mock.</p> +<h2 id="a-pypi-server-mock">A PyPI Server&nbsp;mock</h2> +<p>The mock is embeded in a thread, to make it available during the tests, +in a non blocking way. We first used <a href="http://wsgi.org"><span class="caps">WSGI</span></a> and +<a href="http://docs.python.org/library/wsgiref.html">wsgiref</a> in order control +what to serve, and to log the requests made to the server, but finally +realised that <a href="http://docs.python.org/library/wsgiref.html">wsgiref</a> is +not python 2.4 compatible (and we <em>need</em> to be python 2.4 compatible in&nbsp;Distutils2).</p> +<p>So, we switched to +<a href="http://docs.python.org/library/basehttpserver.html">BaseHTTPServer</a> and +<a href="http://docs.python.org/library/simplehttpserver.html">SimpleHTTPServer</a>, +and updated our tests accordingly. It&#8217;s been an opportunity to realize +that <a href="http://wsgi.org"><span class="caps">WSGI</span></a> has been a great step forward for making +<span class="caps">HTTP</span> servers, and expose a really simplest way to discuss with <span class="caps">HTTP</span>&nbsp;!</p> +<p>You can find <a href="http://bitbucket.org/ametaireau/distutils2/changesets">the modifications I +made</a>, and the +<a href="http://bitbucket.org/ametaireau/distutils2/src/tip/docs/source/test_framework.rst">related +docs</a> +about this on <a href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket distutils2 +clone</a>.</p> +<h2 id="the-pypi-simple-api">The PyPI Simple <span class="caps">API</span></h2> +<p>So, back to the main problematic: make a python library to access and +request information stored on PyPI, via the simple <span class="caps">API</span>. As I said, I&#8217;ve +just grabbed the work made from +<a href="http://bitbucket.org/tarek/distribute/">Distribute</a>, and played a bit +with, in order to view what are the different use cases, and started to +write the related&nbsp;tests.</p> +<h2 id="the-work-to-come">The work to&nbsp;come</h2> +<p>So, once all use cases covered with tests, I&#8217;ll rewrite a bit the +grabbed code, and do some software design work (to not expose all things +as privates methods, have a clear <span class="caps">API</span>, and other things like this), then +update the tests accordingly and write a documentation to make this&nbsp;clear.</p> +<p>Next step is to a little client, as I&#8217;ve <a href="http://github.com/ametaireau/pypiclient">already started +here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html +<p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of +Code</a> program, and will work on +<a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +<p>So, it&#8217;s about building the successor of Distutils2, ie. &#8220;the python +package manager&#8221;. Today, there is too many ways to package …</p></blockquote> +<p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of +Code</a> program, and will work on +<a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +<p>So, it&#8217;s about building the successor of Distutils2, ie. &#8220;the python +package manager&#8221;. Today, there is too many ways to package a python +application (pip, setuptools, distribute, distutils, etc.) so there is +a huge effort to make in order to make all this packaging stuff +interoperable, as pointed out by +the <a href="http://www.python.org/dev/peps/pep-0376/"><span class="caps">PEP</span> 376</a>.</p> +</blockquote> +<p>In more details, I&#8217;m going to work on the Installer / Uninstaller features of Distutils2, and on a PyPI <span class="caps">XML</span>-<span class="caps">RPC</span> client for distutils2. Here are the already defined&nbsp;tasks:</p> +<ul> +<li>Implement Distutils2 APIs described in <span class="caps">PEP</span>&nbsp;376.</li> +<li>Add the uninstall&nbsp;command.</li> +<li>think about a basic installer / uninstaller script. (with deps) &#8212; + similar to&nbsp;pip/easy_install</li> +<li>in a pypi&nbsp;subpackage;</li> +<li>Integrate a module similar to setuptools&#8217;&nbsp;package_index&#8217;</li> +<li>PyPI <span class="caps">XML</span>-<span class="caps">RPC</span> client for distutils 2: + <a href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> +</ul> +<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Python ? go !2009-12-17T00:00:00+01:002009-12-17T00:00:00+01:00tag:blog.notmyidea.org,2009-12-17:/python-go.html +<p>Cela fait maintenant un peu plus d&#8217;un mois que je travaille sur un +projet en <a href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a href="http://python.org/">Python</a>. Je prends +un plaisir non dissimulé à découvrir ce langage (et à l&#8217;utiliser), qui +ne cesse de me surprendre. Les premiers mots qui me …</p> +<p>Cela fait maintenant un peu plus d&#8217;un mois que je travaille sur un +projet en <a href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a href="http://python.org/">Python</a>. Je prends +un plaisir non dissimulé à découvrir ce langage (et à l&#8217;utiliser), qui +ne cesse de me surprendre. Les premiers mots qui me viennent à l&#8217;esprit +à propos de Python, sont &#8220;logique&#8221; et &#8220;simple&#8221;. Et pourtant puissant +pour autant. Je ne manque d&#8217;ailleurs pas une occasion pour faire un peu +d&#8217;<em>évangélisation</em> auprès des quelques personnes qui veulent bien&nbsp;m&#8217;écouter.</p> +<h2 id="the-zen-of-python">The Zen of&nbsp;Python</h2> +<p>Avant toute autre chose, je pense utile de citer Tim Peters, et <a href="http://www.python.org/dev/peps/pep-0020/">le +<span class="caps">PEP20</span></a>, qui constituent une +très bonne introduction au langage, qui prends la forme d&#8217;un <em>easter +egg</em> présent dans&nbsp;python</p> +<div class="highlight"><pre><span></span><code>&gt;&gt;&gt;<span class="w"> </span>import<span class="w"> </span>this +The<span class="w"> </span>Zen<span class="w"> </span>of<span class="w"> </span>Python,<span class="w"> </span>by<span class="w"> </span>Tim<span class="w"> </span>Peters + +Beautiful<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>ugly. +Explicit<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>implicit. +Simple<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>complex. +Complex<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>complicated. +Flat<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>nested. +Sparse<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>dense. +Readability<span class="w"> </span>counts. +Special<span class="w"> </span>cases<span class="w"> </span>aren<span class="s1">&#39;t special enough to break the rules.</span> +<span class="s1">Although practicality beats purity.</span> +<span class="s1">Errors should never pass silently.</span> +<span class="s1">Unless explicitly silenced.</span> +<span class="s1">In the face of ambiguity, refuse the temptation to guess.</span> +<span class="s1">There should be one-- and preferably only one --obvious way to do it.</span> +<span class="s1">Although that way may not be obvious at first unless you&#39;</span>re<span class="w"> </span>Dutch. +Now<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>never. +Although<span class="w"> </span>never<span class="w"> </span>is<span class="w"> </span>often<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>*right*<span class="w"> </span>now. +If<span class="w"> </span>the<span class="w"> </span>implementation<span class="w"> </span>is<span class="w"> </span>hard<span class="w"> </span>to<span class="w"> </span>explain,<span class="w"> </span>it<span class="s1">&#39;s a bad idea.</span> +<span class="s1">If the implementation is easy to explain, it may be a good idea.</span> +<span class="s1">Namespaces are one honking great idea -- let&#39;</span>s<span class="w"> </span><span class="k">do</span><span class="w"> </span>more<span class="w"> </span>of<span class="w"> </span>those! +</code></pre></div> + +<p>J&#8217;ai la vague impression que c&#8217;est ce que j&#8217;ai toujours cherché à faire +en <span class="caps">PHP</span>, et particulièrement dans <a href="http://www.spiral-project.org">le framework +Spiral</a>, mais en ajoutant ces concepts +dans une sur-couche au langage. Ici, c&#8217;est directement de <em>l&#8217;esprit</em> de +python qu&#8217;il s&#8217;agit, ce qui signifie que la plupart des bibliothèques +python suivent ces concepts. Elle est pas belle la vie&nbsp;?</p> +<h2 id="comment-commencer-et-par-ou">Comment commencer, et par ou&nbsp;?</h2> +<p>Pour ma part, j&#8217;ai commencé par la lecture de quelques livres et +articles intéressants, qui constituent une bonne entrée en matière sur +le sujet (La liste n&#8217;est bien évidemment pas exhaustive et vos +commentaires sont les bienvenus)&nbsp;:</p> +<ul> +<li><a href="http://diveintopython.adrahon.org/">Dive into&nbsp;python</a></li> +<li><a href="http://www.swaroopch.com/notes/Python_fr:Table_des_Matières">A byte of&nbsp;python</a></li> +<li><a href="http://www.amazon.fr/Python-Petit-guide-lusage-développeur/dp/2100508830">Python: petit guide à l&#8217;usage du développeur + agile</a> + de <a href="http://tarekziade.wordpress.com/">Tarek&nbsp;Ziadé</a></li> +<li><a href="http://docs.python.org/index.html">La documentation officielle + python</a>, bien sûr&nbsp;!</li> +<li><a href="http://video.pycon.fr/videos/pycon-fr-2009/">Les vidéos du + pyconfr 2009</a>!</li> +<li>Un peu de temps, et une console python ouverte&nbsp;:)</li> +</ul> +<p>J&#8217;essaye par ailleurs de partager au maximum les ressources que je +trouve de temps à autres, que ce soit <a href="http://www.twitter.com/ametaireau">via +twitter</a> ou <a href="http://delicious.com/ametaireau">via mon compte +delicious</a>. Allez jeter un œil <a href="http://delicious.com/ametaireau/python">au tag +python</a> sur mon profil, peut +être que vous trouverez des choses intéressantes, qui&nbsp;sait!</p> +<h2 id="un-python-sexy">Un python&nbsp;sexy</h2> +<p>Quelques fonctionnalités qui devraient vous mettre l&#8217;eau à la&nbsp;bouche:</p> +<ul> +<li><a href="http://docs.python.org/library/stdtypes.html#comparisons">Le chaînage des opérateurs de + comparaison</a> + est possible (a\&lt;b \&lt;c dans une&nbsp;condition)</li> +<li>Assignation de valeurs multiples (il est possible de faire a,b,c = + 1,2,3 par&nbsp;exemple)</li> +<li><a href="http://docs.python.org/tutorial/datastructures.html">Les listes</a> + sont simples à manipuler&nbsp;!</li> +<li>Les <a href="http://docs.python.org/tutorial/datastructures.html#list-comprehensions">list + comprehension</a>, + ou comment faire des opérations complexes sur les listes, de manière&nbsp;simple.</li> +<li>Les + <a href="http://docs.python.org/library/doctest.html?highlight=doctest">doctests</a>: + ou comment faire des tests directement dans la documentation de vos + classes, tout en la documentant avec de vrais&nbsp;exemples.</li> +<li>Les + <a href="http://www.python.org/doc/essays/metaclasses/meta-vladimir.txt">métaclasses</a>, + ou comment contrôler la manière dont les classes se&nbsp;construisent</li> +<li>Python est <a href="http://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language">un langage à typage fort + dynamique</a>: + c&#8217;est ce qui m&#8217;agaçait avec <span class="caps">PHP</span> qui est un langage à typage faible&nbsp;dynamique.</li> +</ul> +<p>Cous pouvez également aller regarder <a href="http://video.pycon.fr/videos/free/53/">l&#8217;atelier donné par Victor Stinner +durant le Pyconfr 09</a>. Have fun&nbsp;!</p> \ No newline at end of file diff --git a/feeds/journal.atom.xml b/feeds/journal.atom.xml index 93fd362..8441864 100644 --- a/feeds/journal.atom.xml +++ b/feeds/journal.atom.xml @@ -892,9 +892,9 @@ L&#8217;avantage de ce matériel c&#8217;est que c&#8217;est la < <p>Et quand on passe des tests à l’échelle, (de 20L à 1500L), on est moyennement rassurés&nbsp;!</p> <p>Après quelques brassins validés, on est un peu plus relax sur le sujet, et on a mis en place de quoi faire des expérimentations à petite échelle de manière simple : vu qu&#8217;on produit du moût toutes les semaines, on en utilise une partie pour faire quelques tests : changement de levure, adjonctions, changement des températures de fermentation,&nbsp;etc.</p> <p>Ah ça, c’est pas les idées qui nous manquent :-) Et c&#8217;est une super manière&nbsp;d&#8217;expérimenter.</p> -<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/experimentations/sobacha.png"></p> -<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/experimentations/monstrueuse-normalite.png"></p> -<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/experimentations/chainon-manquant.png"></p> +<p><img alt="Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié" src="/images/un-an/sobacha.png"></p> +<p><img alt="Étiquette de Monstrueuse Normalité, une New England IPA" src="/images/un-an/monstrueuse-normalite.png"></p> +<p><img alt="Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi" src="/images/un-an/chainon-manquant.png"></p> <h2 id="ouverture-au-public-evenements-et-equilibre">Ouverture au public, évènements et&nbsp;équilibre</h2> <p>On a pris le parti d&#8217;ouvrir le magasin toutes les fins de semaine (le jeudi et vendredi de 17h à 19h) et on est hyper contents de faire visiter la brasserie aux personnes qui passent de temps à autre. Pour nous, ça fait partie des plaisirs du métier. Par contre, on avait clairement sous estimé le temps que ça nous prendrait. On accueille beaucoup et les gens sont curieux. La fabrication de bière reste encore aujourd’hui quelque chose de nouveau pour la plupart, et il faut satisfaire cette curiosité (il faut plus de brasseries&nbsp;!).</p> <p>Ce qui se passe en ce moment sur la scène brassicole est génial : beaucoup de nouvelles brasseries proposent des produits exceptionnels, et les évènements se multiplient aux quatre coins de la France. On adore partager, goûter, discuter, mais on ne pensait pas être autant sollicités par des évènements extérieurs, souvent sur des week-end, et parfois loin. <strong>On souhaite garder un équilibre entre notre vie personnelle et notre vie professionnelle</strong>. Aller aux évènements aussi par plaisir. Être partout est probablement un des maux de notre temps ;-) À force de voir des brasseurs exténués, il y a de quoi se poser des questions sur la pérennité sur le long terme d’un rythme aussi&nbsp;effréné.</p> @@ -1355,8 +1355,6 @@ sphère privée ce qui devrait l&#8217;être à&nbsp;priori.</p> Enigmail et de le configurer correctement. Ce n&#8217;est pas très compliqué et permet d&#8217;avoir des échanges chiffrés. <a href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à&nbsp;pas.</p> -<p>La clé publique pour me contacter est -<a href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et vous&nbsp;?</p> <p>Je vous invite à aller voir le documentaire Citizen Four, qui passe en salles. Si vous ni avez pas accès, vous pouvez le visionner ici, et éventuellement faire un don aux auteurs ou associations qui gravitent @@ -1553,7 +1551,7 @@ de génération de formulaires en ligne, qui ne soit pas centré sur les services de&nbsp;google…</p> <p>Allez, au boulot&nbsp;!</p> <p><span class="caps">PS</span>: je me rends compte après relecture que ce billet fait echo à un -billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="%7Bfilename%7D2011.05.travailler-moins-mieux.rst">sur le +billet que j&#8217;ai écris juste alors que je terminais mes études, <a href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler.html">sur le sens du travail et de l&#8217;informatique</a>, ça fait du bien&nbsp;:)</p>Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00tag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html @@ -1570,7 +1568,7 @@ restent&nbsp;intacts.</p> <p>Deux ans ça parait énorme, c&#8217;est le temps le plus long que j&#8217;ai passé à travailler sur un projet, avec quasiment les mêmes personnes. Si vous suivez un peu ces carnets, vous savez surement que j&#8217;ai beaucoup -travaillé avec <a href="ziade.org">Tarek</a> par&nbsp;exemple.</p> +travaillé avec <a href="https://ziade.org">Tarek</a> par&nbsp;exemple.</p> <p>Ça a été (et c&#8217;est toujours) un réel plaisir de bosser avec la personne dont j&#8217;avais lu les livres pour apprendre le python, merci&nbsp;!</p> <h2 id="services">Services</h2> @@ -1812,7 +1810,7 @@ que je veux me garder de coté, des pensées que je souhaite partager… Un endroit ou je peux venir écrire quelque chose et le compléter plus&nbsp;tard.</p> <p>Du coup, le flux Atom contiens désormais quelques notes sur des sujets variés. Ces notes ne sont pas relayées sur la page d&#8217;accueil, mais vous -pouvez les trouver dans <a href="%7Ccategory%7Cnotes">la section notes</a>.</p> +pouvez les trouver dans <a href="/notes">la section notes</a>.</p> <p>Je ne sais pas encore si il s&#8217;agit du meilleur endroit pour ça, mais peu importe, essayons. A bas la pudeur&nbsp;rédactionelle.</p> <p>J&#8217;ai du au passage chambouler un peu vos agrégateurs, pardonnez moi&nbsp;:)</p> diff --git a/feeds/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.atom.xml b/feeds/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.atom.xml index eeb79c5..0b09c5b 100644 --- a/feeds/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.atom.xml +++ b/feeds/kerry-patterson-stephen-r-covey-joseph-grenny-ron-mcmillan-et-al-switzler.atom.xml @@ -71,18 +71,22 @@ <li>Clarifiez ce que vous voulez réellement : pour vous, pour les autres, et pour la&nbsp;relation.</li> <li>Demandez-vous ce que vous devriez faire pour aller vers ce que vous souhaitez réellement&nbsp;?</li> </ul> -<p><strong>Refusez le dualisme</strong> : -- 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&#8217;un <strong>et</strong> l&#8217;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&nbsp;sain.</p> +<p><strong>Refusez le dualisme</strong>&nbsp;:</p> +<ul> +<li>Alors que vous considérez ce que vous voulez, notez quand vous vous piégez vous-même dans un&nbsp;dualisme.</li> +<li>Cherchez comment faire l&#8217;un <strong>et</strong>&nbsp;l&#8217;autre.</li> +<li>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&nbsp;sain.</li> +</ul> <h3 id="decider-de-ses-histoires">Décider De Ses&nbsp;Histoires</h3> <p>Les histoires créent des émotions. Les émotions n&#8217;arrivent pas d&#8217;elles-mêmes, et sont liées à des histoires qu&#8217;on se&nbsp;raconte.</p> <p>Il peut être utile de séparer les faits des histoires qu&#8217;on se raconte pour pouvoir repenser nos&nbsp;émotions.</p> -<p>Le schéma peut être le suivant : -1. Voir et entendre (les faits) -2. Se raconter une histoire -3. Ressentir -4.&nbsp;Agir</p> +<p>Le schéma peut être le suivant&nbsp;:</p> +<ol> +<li>Voir et entendre (les&nbsp;faits)</li> +<li>Se raconter une&nbsp;histoire</li> +<li>Ressentir</li> +<li>Agir</li> +</ol> <h2 id="partie-2-comment-ouvrir-la-bouche">Partie 2 : Comment Ouvrir la&nbsp;Bouche</h2> <h3 id="apprendre-a-regarder">Apprendre à&nbsp;Regarder</h3> <p>Comment se rendre compte que la sécurité est mise en jeu ? Il faut apprendre à regarder et à capter les signes. Quand une conversation devient stressante, on a tendance à faire les mauvaises choses. Apprenez à regarder&nbsp;:</p> @@ -95,17 +99,21 @@ </ul> <h3 id="securiser-la-conversation">Sécuriser la&nbsp;Conversation</h3> <p>Pour sécuriser la conversation, il faut réussir à sortir du contenu de la conversation d&#8217;abord. L&#8217;idée étant de se rendre compte quand les gens deviennent violents ou silencieux, pour renouer le dialogue. Une fois que c&#8217;est fait on peut reprendre la&nbsp;discussion.</p> -<p>Comprendre ce qui crée un risque pour la sécurité : -- <strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations ? -- <strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</p> +<p>Comprendre ce qui crée un risque pour la sécurité&nbsp;:</p> +<ul> +<li><strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations&nbsp;?</li> +<li><strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</li> +</ul> <p>Pour commencer la discussion, <strong>partagez vos bonnes intentions</strong> : qu&#8217;est-ce que vous voulez ? Pour vous et pour l&#8217;autre personne&nbsp;?</p> <p><strong>Excusez-vous</strong> lorsque c&#8217;est&nbsp;approprié.</p> <p><strong>Contrastez</strong> pour régler les incompréhensions : Commencez par ce que vous ne voulez pas dire, puis expliquez ce que vous voulez&nbsp;dire.</p> -<p>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 -- Brainstormez les nouvelles&nbsp;stratégies</p> +<p>Créez un objectif commun lorsque vous vous rendez compte que les choses sont compliquées&nbsp;:</p> +<ul> +<li>Dites que votre objectif est de trouver un but&nbsp;commun.</li> +<li>Reconnaissez les buts derrière les&nbsp;stratégies</li> +<li>Inventez un but&nbsp;commun</li> +<li>Brainstormez les nouvelles&nbsp;stratégies</li> +</ul> <h3 id="decrire-sa-vision-des-choses">Décrire Sa Vision Des&nbsp;Choses</h3> <h3 id="comprendre-les-visions-des-autres">Comprendre Les Visions Des&nbsp;Autres</h3> <h3 id="ecouter">Écouter</h3> diff --git a/feeds/lectures.atom.xml b/feeds/lectures.atom.xml index 21596c9..08387de 100644 --- a/feeds/lectures.atom.xml +++ b/feeds/lectures.atom.xml @@ -266,18 +266,22 @@ L&#8217;analyse, l’élaboration, la remise en question des relations de po <li>Clarifiez ce que vous voulez réellement : pour vous, pour les autres, et pour la&nbsp;relation.</li> <li>Demandez-vous ce que vous devriez faire pour aller vers ce que vous souhaitez réellement&nbsp;?</li> </ul> -<p><strong>Refusez le dualisme</strong> : -- 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&#8217;un <strong>et</strong> l&#8217;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&nbsp;sain.</p> +<p><strong>Refusez le dualisme</strong>&nbsp;:</p> +<ul> +<li>Alors que vous considérez ce que vous voulez, notez quand vous vous piégez vous-même dans un&nbsp;dualisme.</li> +<li>Cherchez comment faire l&#8217;un <strong>et</strong>&nbsp;l&#8217;autre.</li> +<li>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&nbsp;sain.</li> +</ul> <h3 id="decider-de-ses-histoires">Décider De Ses&nbsp;Histoires</h3> <p>Les histoires créent des émotions. Les émotions n&#8217;arrivent pas d&#8217;elles-mêmes, et sont liées à des histoires qu&#8217;on se&nbsp;raconte.</p> <p>Il peut être utile de séparer les faits des histoires qu&#8217;on se raconte pour pouvoir repenser nos&nbsp;émotions.</p> -<p>Le schéma peut être le suivant : -1. Voir et entendre (les faits) -2. Se raconter une histoire -3. Ressentir -4.&nbsp;Agir</p> +<p>Le schéma peut être le suivant&nbsp;:</p> +<ol> +<li>Voir et entendre (les&nbsp;faits)</li> +<li>Se raconter une&nbsp;histoire</li> +<li>Ressentir</li> +<li>Agir</li> +</ol> <h2 id="partie-2-comment-ouvrir-la-bouche">Partie 2 : Comment Ouvrir la&nbsp;Bouche</h2> <h3 id="apprendre-a-regarder">Apprendre à&nbsp;Regarder</h3> <p>Comment se rendre compte que la sécurité est mise en jeu ? Il faut apprendre à regarder et à capter les signes. Quand une conversation devient stressante, on a tendance à faire les mauvaises choses. Apprenez à regarder&nbsp;:</p> @@ -290,17 +294,21 @@ L&#8217;analyse, l’élaboration, la remise en question des relations de po </ul> <h3 id="securiser-la-conversation">Sécuriser la&nbsp;Conversation</h3> <p>Pour sécuriser la conversation, il faut réussir à sortir du contenu de la conversation d&#8217;abord. L&#8217;idée étant de se rendre compte quand les gens deviennent violents ou silencieux, pour renouer le dialogue. Une fois que c&#8217;est fait on peut reprendre la&nbsp;discussion.</p> -<p>Comprendre ce qui crée un risque pour la sécurité : -- <strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations ? -- <strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</p> +<p>Comprendre ce qui crée un risque pour la sécurité&nbsp;:</p> +<ul> +<li><strong>Objectif commun</strong> : Est-ce que les autres pensent que leurs objectifs sont importants pour vous ? Est-ce qu&#8217;ils ont confiance dans mes motivations&nbsp;?</li> +<li><strong>Respect mutuel</strong> : Est-ce que les autres pensent que vous les respectez&nbsp;?</li> +</ul> <p>Pour commencer la discussion, <strong>partagez vos bonnes intentions</strong> : qu&#8217;est-ce que vous voulez ? Pour vous et pour l&#8217;autre personne&nbsp;?</p> <p><strong>Excusez-vous</strong> lorsque c&#8217;est&nbsp;approprié.</p> <p><strong>Contrastez</strong> pour régler les incompréhensions : Commencez par ce que vous ne voulez pas dire, puis expliquez ce que vous voulez&nbsp;dire.</p> -<p>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 -- Brainstormez les nouvelles&nbsp;stratégies</p> +<p>Créez un objectif commun lorsque vous vous rendez compte que les choses sont compliquées&nbsp;:</p> +<ul> +<li>Dites que votre objectif est de trouver un but&nbsp;commun.</li> +<li>Reconnaissez les buts derrière les&nbsp;stratégies</li> +<li>Inventez un but&nbsp;commun</li> +<li>Brainstormez les nouvelles&nbsp;stratégies</li> +</ul> <h3 id="decrire-sa-vision-des-choses">Décrire Sa Vision Des&nbsp;Choses</h3> <h3 id="comprendre-les-visions-des-autres">Comprendre Les Visions Des&nbsp;Autres</h3> <h3 id="ecouter">Écouter</h3> diff --git a/feeds/technologie.atom.xml b/feeds/technologie.atom.xml deleted file mode 100644 index 5221da6..0000000 --- a/feeds/technologie.atom.xml +++ /dev/null @@ -1,6234 +0,0 @@ - -Alexis Métaireau - technologiehttps://blog.notmyidea.org/2022-08-29T00:00:00+02:00Installation de Mosquitto, InfluxDB, Telegraf et Grafana2022-08-29T00:00:00+02:002022-08-29T00:00:00+02:00tag:blog.notmyidea.org,2022-08-29:/installation-de-mosquitto-influxdb-telegraf-et-grafana.html<p>Récemment, on a m&#8217;a demandé un petit coup de main pour aider à l&#8217;installation d&#8217;une pile logicielle qui permet de stocker des données temporelles et en faire des&nbsp;graphiques.</p> -<p>Voici donc quelques notes prises durant l&#8217;installation du système, concues pour que des personnes qui n&#8217;y …</p><p>Récemment, on a m&#8217;a demandé un petit coup de main pour aider à l&#8217;installation d&#8217;une pile logicielle qui permet de stocker des données temporelles et en faire des&nbsp;graphiques.</p> -<p>Voici donc quelques notes prises durant l&#8217;installation du système, concues pour que des personnes qui n&#8217;y connaissent pas grand chose puissent s&#8217;y&nbsp;retrouver.</p> -<p>L&#8217;objectif, c&#8217;est d&#8217;avoir des cartes Arduino qui envoient des données de manière régulière sur un système qui va nous permettre de les stocker et d&#8217;en faire des&nbsp;graphiques.</p> -<p>Pour ça, nous allons utiliser&nbsp;:</p> -<ul> -<li>Un <em>Broker</em> <a href="https://mosquitto.org/">Mosquitto</a> qui va permettre de receptionner les données depuis les différents <em>clients</em>, puis de les dispatcher à qui en a besoin&nbsp;;</li> -<li>Une base de données <a href="https://www.influxdata.com/products/influxdb-overview/">InfluxDB</a>, qui permet de stocker des données temporelles&nbsp;;</li> -<li>Un <em>agent</em> <a href="https://www.influxdata.com/time-series-platform/telegraf/">Telegraf</a> qui va prendre les données du broker et les stocker dans la base de données&nbsp;InfluxDB.</li> -<li><a href="https://grafana.com/">Grafana</a>, une <em>application web</em> qui permet de visualiser les données stockées dans&nbsp;InfluxDB.</li> -</ul> -<p>Voici donc un document qui résume les étapes que j&#8217;ai suivies pour mettre en place les différents élements utiles&nbsp;:</p> -<h2 id="installer-et-se-connecter-au-serveur">Installer et se connecter au&nbsp;serveur</h2> -<p>Dans notre cas, on est passé par un <span class="caps">VPS</span> chez <span class="caps">OVH</span>, qui tourne sous <a href="https://www.debian.org/">Debian 11</a>, qui a le mérite d&#8217;être une distribution Linux stable, reconnue et (relativement) simple à&nbsp;utiliser.</p> -<p>Dans un terminal, vous pouvez vous connecter en utilisant la ligne de commande suivante&nbsp;:</p> -<p><em>Les lignes suivantes sont des lignes d&#8217;invite de commande, on les rencontre assez souvent dans les documentations sur le web. Le signe <code>$</code> signifie le début de la ligne de commande. Le signe <code>#</code> signifie le début des&nbsp;commentaires.</em></p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>utilisateur@adresseip -</code></pre></div> - -<p>Une fois connecté, on va mettre à jour les logiciels qui sont présents sur le&nbsp;serveur. </p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>update<span class="w"> </span><span class="c1"># mise à jour des dépôts (la liste des logiciels).</span> -$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>upgrade<span class="w"> </span><span class="c1"># mise à jour des logiciels.</span> -</code></pre></div> - -<h2 id="configurer-les-dns">Configurer les <span class="caps">DNS</span></h2> -<p>Nous allons avoir besoin de deux sous domaines qui redirigent vers le serveur. Bien sur, il faut adapter <code>ndd.tld</code> et le remplacer par votre nom de domaine&nbsp;:</p> -<ol> -<li>moquitto.ndd.tld</li> -<li>graphs.ndd.tld</li> -</ol> -<p>Pour faire ça, chez <span class="caps">OVH</span> ça se passe dans la console de « <span class="caps">OVH</span> Cloud », direction « Noms de domaines », et puis il faut rajouter deux enregistrements de type « A » qui pointent vers l&#8217;adresse <span class="caps">IP</span> du&nbsp;serveur.</p> -<p>En temps normal, l&#8217;adresse <span class="caps">IP</span> vous est fournie par <span class="caps">OVH</span>. Si vous avez un doute, vous pouvez l&#8217;obtenir depuis le serveur avec la commande <code>ip a</code>.</p> -<h2 id="installer-mosquitto">Installer&nbsp;Mosquitto</h2> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>mosquitto<span class="w"> </span><span class="c1"># installation depuis les dépots officiels</span> -</code></pre></div> - -<p>Une fois installé, <a href="https://mosquitto.org/documentation/authentication-methods/">il faut sécuriser l&#8217;installation avec un utilisateur et un mot de passe</a>.</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>mosquitto_passwd<span class="w"> </span>-c<span class="w"> </span>/etc/mosquitto/passwd<span class="w"> </span>&lt;username&gt; -</code></pre></div> - -<p>Ensuite dans le fichier de configuration il faut spécifier où est le fichier qui contient les mots de passe. Pour éditer je recommande l&#8217;utilisation de l&#8217;éditeur de texte <code>nano</code>. </p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>nano<span class="w"> </span>/etc/mosquitto/mosquitto.conf -</code></pre></div> - -<p>Voici les lignes à rajouter&nbsp;:</p> -<div class="highlight"><pre><span></span><code>listener 1883 -password_file /etc/mosquitto/passwd -</code></pre></div> - -<p>Puis il faut relancer le service mosquitto&nbsp;:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span>restart<span class="w"> </span>mosquitto -</code></pre></div> - -<p>Avant de pouvoir utiliser mosquitto, il faut <a href="https://docs.ovh.com/gb/en/dedicated/firewall-network/">régler le firewall</a> de chez <span class="caps">OVH</span> pour qu&#8217;il accepte de laisser passer les messages pour le broker <span class="caps">MQTT</span>.</p> -<p>Il faut ajouter une règle dans le Firewall qui laisse passer toutes les connections <span class="caps">TCP</span>, avec l&#8217;option « établie&nbsp;».</p> -<h3 id="verifions-que-tout-fonctionne-comme-prevu">Vérifions que tout fonctionne comme prévu&nbsp;:</h3> -<p>Dans une console,&nbsp;écoutons…</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>mosquitto_sub<span class="w"> </span>-h<span class="w"> </span>mosquitto.ndd.tld<span class="w"> </span>-p<span class="w"> </span><span class="m">1883</span><span class="w"> </span>-u<span class="w"> </span>&lt;username&gt;<span class="w"> </span>-P<span class="w"> </span>&lt;password&gt;<span class="w"> </span>-t<span class="w"> </span>topic -</code></pre></div> - -<p>Et dans une autre envoyons un message&nbsp;:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>mosquitto_pub<span class="w"> </span>-h<span class="w"> </span>mosquitto.ndd.tld<span class="w"> </span>-p<span class="w"> </span><span class="m">1883</span><span class="w"> </span>-u<span class="w"> </span>&lt;username&gt;<span class="w"> </span>-P<span class="w"> </span>&lt;password&gt;<span class="w"> </span>-t<span class="w"> </span>topic<span class="w"> </span>-m<span class="w"> </span><span class="m">30</span> -</code></pre></div> - -<p>Vous deviez voir « 30 » apparaitre dans la première console. Si c&#8217;est bon, tout fonctionne&nbsp;!</p> -<h2 id="installation-dinfluxdb-et-telegraf">Installation d&#8217;InfluxDB et&nbsp;Telegraf</h2> -<p>Coup de bol, InfluxDB propose directement des packets pour Debian, sur leur dépot, qu&#8217;il faut donc ajouter en suivant ces quelques lignes&nbsp;:</p> -<div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>apt<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>gnupg2<span class="w"> </span>curl<span class="w"> </span>wget -wget<span class="w"> </span>-qO-<span class="w"> </span>https://repos.influxdata.com/influxdb.key<span class="w"> </span><span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>apt-key<span class="w"> </span>add<span class="w"> </span>- -<span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;deb https://repos.influxdata.com/debian </span><span class="k">$(</span>lsb_release<span class="w"> </span>-cs<span class="k">)</span><span class="s2"> stable&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>tee<span class="w"> </span>/etc/apt/sources.list.d/influxdb.list -sudo<span class="w"> </span>apt<span class="w"> </span>update -</code></pre></div> - -<p>Puis <code>sudo apt install influxdb telegraf</code> pour&nbsp;l&#8217;installer.</p> -<p>Ensuite, vous pouvez le lancer maintenant et indiquer au système de le lancer tout seul au démarrage&nbsp;:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>--now<span class="w"> </span>influxdb -$<span class="w"> </span>sudo<span class="w"> </span>systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>--now<span class="w"> </span>telegraf -</code></pre></div> - -<h3 id="configuration-de-telegraf">Configuration de&nbsp;Telegraf</h3> -<p>Telegraf permet de faire le lien entre les messages envoyés sur le broker <span class="caps">MQTT</span> et la base de données&nbsp;InfluxDB.</p> -<p>Ici, il faut rentrer un peu plus dans le vif du sujet, et ça dépends des messages que vous avez à&nbsp;stocker.</p> -<p>Dans notre cas, nous avons trois types de messages&nbsp;:</p> -<ul> -<li>/BatVoltage,&nbsp;int</li> -<li>/Temperature,&nbsp;int</li> -<li>/<span class="caps">GPS</span>,&nbsp;string</li> -</ul> -<p>Voici un fichier de configuration, qui reste à modifier en fonction des&nbsp;données.</p> -<div class="highlight"><pre><span></span><code><span class="k">[global_tags]</span> -<span class="k">[agent]</span> -<span class="w"> </span><span class="na">interval</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;10s&quot;</span> -<span class="w"> </span><span class="na">round_interval</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">true</span> -<span class="w"> </span><span class="na">metric_batch_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">1000</span> -<span class="w"> </span><span class="na">metric_buffer_limit</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">10000</span> -<span class="w"> </span><span class="na">collection_jitter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0s&quot;</span> -<span class="w"> </span><span class="na">flush_interval</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;10s&quot;</span> -<span class="w"> </span><span class="na">flush_jitter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0s&quot;</span> -<span class="w"> </span><span class="na">precision</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;0s&quot;</span> -<span class="w"> </span><span class="na">hostname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;&quot;</span> -<span class="w"> </span><span class="na">omit_hostname</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">false</span> - -<span class="k">[[outputs.influxdb]]</span> -<span class="w"> </span><span class="na">urls</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">[&quot;http://127.0.0.1:8086&quot;]</span> -<span class="w"> </span><span class="na">database</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;telegraf&quot;</span> - -<span class="k">[[inputs.mqtt_consumer]]</span> -<span class="w"> </span><span class="na">servers</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">[&quot;tcp://127.0.0.1:1883&quot;]</span> -<span class="w"> </span><span class="na">name_override</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;mqtt_consumer_float&quot;</span> -<span class="w"> </span><span class="na">topics</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">[</span> -<span class="w"> </span><span class="na">&quot;Topic/BatVoltage&quot;,</span> -<span class="w"> </span><span class="na">&quot;Topic/Temperature&quot;,</span> -<span class="w"> </span><span class="na">]</span> -<span class="w"> </span><span class="na">username</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;&lt;username&gt;&quot;</span> -<span class="w"> </span><span class="na">password</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;&lt;password&gt;&quot;</span> -<span class="w"> </span><span class="na">data_format</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;value&quot;</span> -<span class="w"> </span><span class="na">data_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;integer&quot;</span> -</code></pre></div> - -<h2 id="installation-de-grafana">Installation de&nbsp;Grafana</h2> -<div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>apt-transport-https -sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>-y<span class="w"> </span>software-properties-common<span class="w"> </span>wget -sudo<span class="w"> </span>wget<span class="w"> </span>-q<span class="w"> </span>-O<span class="w"> </span>/usr/share/keyrings/grafana.key<span class="w"> </span>https://packages.grafana.com/gpg.key -<span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;deb [signed-by=/usr/share/keyrings/grafana.key] https://packages.grafana.com/oss/deb stable main&quot;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>sudo<span class="w"> </span>tee<span class="w"> </span>-a<span class="w"> </span>/etc/apt/sources.list.d/grafana.list -sudo<span class="w"> </span>apt<span class="w"> </span>update -sudo<span class="w"> </span>apt-get<span class="w"> </span>install<span class="w"> </span>grafana -sudo<span class="w"> </span>/bin/systemctl<span class="w"> </span>daemon-reload -sudo<span class="w"> </span>/bin/systemctl<span class="w"> </span><span class="nb">enable</span><span class="w"> </span>grafana-server -sudo<span class="w"> </span>/bin/systemctl<span class="w"> </span>start<span class="w"> </span>grafana-server -</code></pre></div> - -<h3 id="nginx">Nginx</h3> -<div class="highlight"><pre><span></span><code>sudo apt install nginx certbot python3-certbot-nginx -</code></pre></div> - -<p>Puis il faut créer un fichier de configuration dans <code>/etc/nginx/sites-enabled/graphs.ndd.tld</code> avec le contenu suivant&nbsp;:</p> -<div class="highlight"><pre><span></span><code><span class="k">map</span><span class="w"> </span><span class="nv">$http_upgrade</span><span class="w"> </span><span class="nv">$connection_upgrade</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="kn">default</span><span class="w"> </span><span class="s">upgrade</span><span class="p">;</span> -<span class="w"> </span><span class="kn">&#39;&#39;</span><span class="w"> </span><span class="s">close</span><span class="p">;</span> -<span class="p">}</span> - -<span class="k">upstream</span><span class="w"> </span><span class="s">grafana</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="kn">server</span><span class="w"> </span><span class="n">localhost</span><span class="p">:</span><span class="mi">3000</span><span class="p">;</span> -<span class="p">}</span> - -<span class="k">server</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="kn">listen</span><span class="w"> </span><span class="mi">80</span><span class="p">;</span> -<span class="w"> </span><span class="kn">server_name</span><span class="w"> </span><span class="s">graphs.ndd.tld</span><span class="p">;</span> -<span class="w"> </span><span class="kn">root</span><span class="w"> </span><span class="s">/usr/share/nginx/html</span><span class="p">;</span> -<span class="w"> </span><span class="kn">index</span><span class="w"> </span><span class="s">index.html</span><span class="w"> </span><span class="s">index.htm</span><span class="p">;</span> - -<span class="w"> </span><span class="kn">location</span><span class="w"> </span><span class="s">/</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Host</span><span class="w"> </span><span class="nv">$http_host</span><span class="p">;</span> -<span class="w"> </span><span class="kn">proxy_pass</span><span class="w"> </span><span class="s">http://grafana</span><span class="p">;</span> -<span class="w"> </span><span class="p">}</span> - -<span class="w"> </span><span class="c1"># Proxy Grafana Live WebSocket connections.</span> -<span class="w"> </span><span class="kn">location</span><span class="w"> </span><span class="s">/api/live/</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="kn">proxy_http_version</span><span class="w"> </span><span class="mi">1</span><span class="s">.1</span><span class="p">;</span> -<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Upgrade</span><span class="w"> </span><span class="nv">$http_upgrade</span><span class="p">;</span> -<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Connection</span><span class="w"> </span><span class="nv">$connection_upgrade</span><span class="p">;</span> -<span class="w"> </span><span class="kn">proxy_set_header</span><span class="w"> </span><span class="s">Host</span><span class="w"> </span><span class="nv">$http_host</span><span class="p">;</span> -<span class="w"> </span><span class="kn">proxy_pass</span><span class="w"> </span><span class="s">http://grafana</span><span class="p">;</span> -<span class="w"> </span><span class="p">}</span> -<span class="p">}</span> -</code></pre></div> - -<p>Une fois ces fichiers de configuration en place, il faut penser à la mise en place du <span class="caps">SSL</span> qui permet d&#8217;avoir une connexion sécurisée&nbsp;(https).</p> -<p>Il suffit de lancer cette ligne de commande et de suivre les questions posées&nbsp;:</p> -<div class="highlight"><pre><span></span><code>sudo certbot --nginx -</code></pre></div> - -<p>Voilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu&#8217;à configurer le Grafana pour grapher les données enregistrées dans&nbsp;InfluxDB.</p>Groupement d’achats & partage d’expérience2018-03-03T00:00:00+01:002018-03-03T00:00:00+01:00tag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.html<p>Il y a quelques années, on s&#8217;est motivé entre copains copines pour créer un groupement&nbsp;d&#8217;achat.</p> -<p>L&#8217;idée est&nbsp;simple:</p> -<ul> -<li>commander en gros, pour faire baisser les&nbsp;prix</li> -<li>se passer d&#8217;intermédiaires et favoriser les circuits&nbsp;courts</li> -<li>aller à la rencontre des producteurs locaux et&nbsp;échanger</li> -</ul> -<p>Notre groupement …</p><p>Il y a quelques années, on s&#8217;est motivé entre copains copines pour créer un groupement&nbsp;d&#8217;achat.</p> -<p>L&#8217;idée est&nbsp;simple:</p> -<ul> -<li>commander en gros, pour faire baisser les&nbsp;prix</li> -<li>se passer d&#8217;intermédiaires et favoriser les circuits&nbsp;courts</li> -<li>aller à la rencontre des producteurs locaux et&nbsp;échanger</li> -</ul> -<p>Notre groupement dessert actuellement 18 foyers et une 60aine de&nbsp;personnes.</p> -<p>Au fur et à mesure de la vie du groupement, on a développé quelques outils pour se simplifier la vie. Voici un retour d&#8217;expérience et quelques astuces / outils, au cas où l&#8217;envie vous prenne à vous aussi&nbsp;:)</p> -<h1 id="organisation">Organisation</h1> -<p>On organise environs trois ou quatre distributions par an. Le <em>modus operandi</em> est le&nbsp;suivant:</p> -<ul> -<li>chaque product·eur·rice à un·e référent·e, qui s&#8217;occupe de faire le&nbsp;lien;</li> -<li>une personne est désignée pour coordonner la&nbsp;distribution;</li> -<li>4 semaines avant la distribution, les référent·e·s mettent à jour les prix / produits dans le tableau de&nbsp;commandes;·e·</li> -<li>3 semaines avant la distribution, les commandes sont&nbsp;ouvertes;</li> -<li>2 semaines avant la distribution, les commandes sont&nbsp;closes;</li> -<li>Les référent·e·s ont ensuite deux semaines pour récupérer les commandes pour la&nbsp;distribution</li> -</ul> -<h1 id="quels-produits">Quels produits&nbsp;?</h1> -<p>On essaye d&#8217;avoir uniquement des produits qui se conservent (on a également quelques autres produits plus frais, mais avec d&#8217;autres&nbsp;modalités).</p> -<p>Entre autres: bières, légumes secs, conserves, jus, miel, pâtes, semoule, café, vinaigres, pommes de terre, oignons, huiles,&nbsp;farines.</p> -<p>On essaye de faire du local puis du bio au plus proche plutôt que de trouver nécessairement les prix les plus bas. C&#8217;est une discussion qui revient assez -souvent, et donc un point à évoquer lors de la création pour avoir une posture -claire sur le sujet (tout le monde n&#8217;est pas animé par la même éthique&nbsp;!).</p> -<h1 id="paiements">Paiements</h1> -<p>Pour les paiements, on utilise autant que possible des chèques. Chaque référent·e paye la·le product·rice·eur en son nom, et lui demande d&#8217;attendre la date de la distribution pour l&#8217;encaissement. La plupart des producteurs acceptent d&#8217;être payés sous&nbsp;quinzaine.</p> -<p>Le jour de la distribution, tout le monde apporte son chéquier. Nous avons mis -en place une moulinette qui s&#8217;occupe de faire la répartition des chèques automatiquement, chaque membre se retrouve à faire en moyenne un ou deux&nbsp;chèques.</p> -<p>Chaque référent·e est ainsi remboursé·e de la somme avancée, et chaque -membre du groupement d&#8217;achat paye ce qu&#8217;il doit payer. Nous n&#8217;avons -volontairement pas de structure juridique et pas de compte en banque. Les -paiements s&#8217;effectuent directement entre&nbsp;nous.</p> -<h1 id="transports">Transports</h1> -<p>Chaque référent·e commande les produits, puis ensuite s&#8217;occupe de les rapatrier. À Rennes, on a la chance d&#8217;avoir pas mal de producteurs aux alentours, donc c&#8217;est assez&nbsp;simple.</p> -<p>Le mieux est de ramener les produits juste un peu avant la distribution au lieu de distribution, ça permet d&#8217;éviter de les stocker trop longtemps, et d&#8217;éviter aux producteurs d&#8217;attendre trop longtemps avant d&#8217;encaisser les&nbsp;chèques.</p> -<p>Pour les grosses commandes, les voitures se remplissent bien, mais ma petite Clio suffit, que ce soit dit&nbsp;!</p> -<h1 id="la-distribution">La&nbsp;distribution</h1> -<p>Un peu en amont de la distribution, il faut organiser l&#8217;espace. Des tas par membre sont constitués pour faciliter les choses le jour de la&nbsp;distribution.</p> -<p>Le jour même, on se retrouve, on charge ses marchandises, on échange quelques chèques et on papote ! On en profite&nbsp;pour:</p> -<ul> -<li>discuter de la date de la prochaine&nbsp;distribution;</li> -<li>trouver une nouvelle personne pour la&nbsp;coordonner;</li> -<li>discuter de nouveaux&nbsp;produits;</li> -<li>refaire le&nbsp;monde;</li> -<li>changer de référents pour les&nbsp;producteurs.</li> -</ul> -<p>Et c&#8217;est reparti pour un tour&nbsp;;)</p> -<h1 id="nos-outils">Nos&nbsp;outils</h1> -<p>On utilise un tableur en ligne pour partager les prix et prendre les commandes. On a essayé d&#8217;utiliser <em>ethercalc</em> au début mais ça ne fonctionnait pas pour nous à l&#8217;époque (trop de petits bugs). On a donc préféré utiliser Google docs&nbsp;(ouch).</p> -<p>Il est d&#8217;ailleurs possible d&#8217;y intégrer de nouvelles fonctionnalités assez facilement, du coup Fred et Rémy ont planché sur un moyen d&#8217;automatiser la répartition des chèques (qu&#8217;on faisait dans un premier temps à la main - assez&nbsp;péniblement).</p> -<p>Le système n&#8217;est pas parfait mais fonctionne quand même assez bien&nbsp;!</p> -<p>Quelques ressources,&nbsp;donc:</p> -<ul> -<li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des&nbsp;chèques</a></li> -<li><a href="https://docs.google.com/spreadsheets/d/1bnPRSvf2Q2RDxKerWnEqUyJjuCFePnVMq6pWo8LeA_k/edit?usp=sharing">une version « à remplir » de notre tableau de commandes</a> (le mieux est d&#8217;en faire une copie&nbsp;!).</li> -</ul> -<p>Bon groupement d&#8217;achat&nbsp;;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00tag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais …</p><p>Quand je navigue en ligne, j&#8217;aime bien prendre des notes sur ce que je lis. C&#8217;est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j&#8217;ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c&#8217;est à&nbsp;dire:</p> -<ul> -<li>enregistrer une sélection de texte ainsi que son contexte: heure, site&nbsp;web.</li> -<li>fonctionner sur&nbsp;Firefox;</li> -<li>stocker mes notes à un endroit que je contrôle (ce sont mes données, après tout&nbsp;!)</li> -<li>rester en dehors de mon chemin: je suis en train de lire, pas en train d&#8217;organiser mes&nbsp;notes.</li> -<li>automatiquement partager les notes sur une page&nbsp;web.</li> -</ul> -<p>J&#8217;ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j&#8217;ai baptisé « Webnotes ». C&#8217;est <a href="https://addons.mozilla.org/en-US/firefox/addon/wwebnotes/">une extension Firefox</a>, qui se configure assez simplement, et qui stocke les données dans une instance de <a href="http://kinto-storage.org/">Kinto</a>.</p> -<p><img src="https://github.com/almet/webnotes/blob/master/webnotes.gif?raw=true" /></p> -<p>C&#8217;est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué&nbsp;!</p> -<p>Mes notes sont disponibles <a href="https://notes.notmyidea.org">sur notes.notmyidea.org</a>, et voici <a href="https://github.com/almet/webnotes">le lien vers les sources</a>, si ça vous intéresse de regarder comment ça fonctionne&nbsp;!</p>Comment est-ce que vous générez vos formulaires ?2016-05-31T00:00:00+02:002016-05-31T00:00:00+02:00tag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.html<p><span class="caps">TL</span>; <span class="caps">DR</span>: Je viens à peine de <em>releaser</em> la première version d&#8217;un service de génération de formulaires. -Allez jeter un coup d&#8217;œil sur <a href="https://www.fourmilieres.net">https://www.fourmilieres.net</a></p> -<p><em>En février 2012, je parlais ici <a href="https://blog.notmyidea.org/carto-forms.html">d&#8217;un service de génération de formulaires</a>. -Depuis, pas mal d&#8217;eau à coulé sous …</em></p><p><span class="caps">TL</span>; <span class="caps">DR</span>: Je viens à peine de <em>releaser</em> la première version d&#8217;un service de génération de formulaires. -Allez jeter un coup d&#8217;œil sur <a href="https://www.fourmilieres.net">https://www.fourmilieres.net</a></p> -<p><em>En février 2012, je parlais ici <a href="https://blog.notmyidea.org/carto-forms.html">d&#8217;un service de génération de formulaires</a>. -Depuis, pas mal d&#8217;eau à coulé sous les ponts, on est passé par pas mal d&#8217;étapes pour -finalement arriver à une première version de ce service de génération de -formulaires (à la </em>google forms<em>).</em></p> -<p>En tant qu&#8217;organisateurs d&#8217;évènements (petits et gros), je me retrouve souvent -dans une situation ou je dois créer des formulaires pour recueillir des -informations. Actuellement, la meilleure solution disponible est <em>Google Forms</em>, -mais celle ci à plusieurs problèmes, à commencer par le fait que le code n&#8217;est -pas libre et que les données sont stockées chez&nbsp;Google.</p> -<p>La plupart du temps, le besoin est assez simple: je veux spécifier quelques -questions, et donner un lien à mes amis pour qu&#8217;ils puissent y répondre. -Je reviens ensuite plus tard pour voir la liste des réponses&nbsp;apportées.</p> -<p><img alt="Capture de l'interface de création du formulaire" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-build.png"></p> -<h2 id="fonctionnalites">Fonctionnalités</h2> -<p>Il existe pas mal de solutions techniques qui essayent de répondre à la même -problématique, mais la plupart d&#8217;entre elles sont assez souvent compliquées, -nécessitent de se créer un compte, et/ou ne vous laisse pas la main libre sur -les données générées, voire le code est assez difficile à faire évoluer ou à&nbsp;déployer.</p> -<p>Je voulais donc quelque chose de simple à utiliser <em>et</em> pour les créateurs de -formulaires <em>et</em> pour les utilisateurs finaux. Pas de chichis, juste quelques -vues, et des URLs à sauvegarder une fois l&#8217;opération&nbsp;terminée.</p> -<p><img alt="Capture de l'écran avec les URLs générées" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-created.png"> -<img alt="Capture d'écran d'un exemple de formulaire" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-form.png"></p> -<h3 id="pas-de-compte">Pas de&nbsp;compte</h3> -<p>Vous n&#8217;avez pas besoin d&#8217;avoir un compte sur le site pour commencer à l&#8217;utiliser. -Vous créez simplement un nouveau formulaire puis envoyez le lien à vos amis pour -qu&#8217;eux puissent à leur tour le&nbsp;remplir.</p> -<p><img alt="Capture de la page d'accueil, ou aucun compte n'est requis" src="https://blog.notmyidea.org/images/formbuilder/formbuilder-welcome.png"></p> -<h3 id="gardez-la-main-sur-vos-donnees">Gardez la main sur vos&nbsp;données</h3> -<p>Une fois que vous avez récupéré les réponses à vos questions, vous pouvez -récupérer les données sur votre machines dans un fichier <code>.csv</code>.</p> -<p><img alt="Capture de la page de resultats, il est possible de télécharger en CSV." src="https://blog.notmyidea.org/images/formbuilder/formbuilder-results.png"></p> -<h3 id="api"><span class="caps">API</span></h3> -<p>L&#8217;ensemble des données sont en fait stockées dans <a href="https://kinto.readthedocs.org">Kinto</a> -qui est interrogeable très facilement en <span class="caps">HTTP</span>. Ce qui fait qu&#8217;il est très facile de -réutiliser les formulaires que vous avez construits (ou leurs réponses) depuis -d&#8217;autres&nbsp;outils.</p> -<h3 id="auto-hebergeable">Auto-hébergeable</h3> -<p>Un des objectifs de ce projet est de vous redonner la main sur vos données. -Bien sur, vous pouvez utiliser l&#8217;instance qui est mise à votre disposition sur -<a href="https://www.fourmilieres.net">wwww.fourmilieres.net</a>, mais vous pouvez -également l&#8217;héberger vous même très -simplement, et vous êtes d&#8217;ailleurs fortement encouragés à le faire ! Notre -objectif n&#8217;est pas de stocker l&#8217;ensemble des formulaires du monde, mais de -(re)donner le contrôle aux utilisateurs&nbsp;!</p> -<h2 id="on-commence-petit">On commence&nbsp;petit…</h2> -<p>Cette <em>release</em> n&#8217;est (bien sur) pas parfaite, et il reste encore pas mal de -travail sur cet outil, mais je pense qu&#8217;il s&#8217;agit d&#8217;une base de travail -intéressante pour un futur où Google n&#8217;a pas la main sur toutes nos&nbsp;données.</p> -<p>La liste des champs supportés est pour l&#8217;instant assez faible (Texte court, -Texte long, Oui/Non, choix dans une liste) mais elle à vocation à s&#8217;étendre, en -fonction des besoins de&nbsp;chacun.</p> -<p>J&#8217;ai d&#8217;ailleurs créé <a href="https://www.fourmilieres.net/#/form/cfd878264cec4ed2">un formulaire pour que vous puissiez me faire part de vos -retours</a>, n&#8217;hésitez pas&nbsp;!</p> -<h2 id="et-euh-comment-ca-marche">Et, euh, comment ça marche&nbsp;?</h2> -<p>Le <em>formbuilder</em>, comme j&#8217;aime l&#8217;appeler se compose en fin de compte de deux -parties&nbsp;distinctes:</p> -<ul> -<li><a href="https://kinto.readthedocs.org">Kinto</a>, un service qui stocke - des données coté serveur et qui les expose via des <strong>APIs <span class="caps">HTTP</span></strong></li> -<li><a href="https://github.com/kinto/formbuilder">Le formbuilder</a>, une application - JavaScript qui ne tourne que coté client (dans votre navigateur) qui permet - de construire les formulaires et d&#8217;envoyer les données sur les <em>APIs</em> coté&nbsp;serveur.</li> -</ul> -<p>Au niveau de la <em>stack</em> technique, le <strong>formbuilder</strong> est codé en ReactJS. Un -des points techniques intéressants du projet est qu&#8217;il génère en fin de compte du -<a href="http://jsonschema.net/"><span class="caps">JSON</span> Schema</a>, un format de validation de données <em><span class="caps">JSON</span></em>.</p> -<p>Donc, reprenons! Vous arrivez sur la page d&#8217;accueil puis cliquez sur -&#8220;Create a new form&#8221;, puis vous vous retrouvez face à une interface ou vous pouvez -ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez sur -&#8220;Create the&nbsp;form&#8221;.</p> -<ul> -<li>Le <span class="caps">JSON</span> Schema est alors envoyé au serveur Kinto, qui l&#8217;utilisera pour valider - les données qu&#8217;il recevra par la&nbsp;suite.</li> -<li>Ce <span class="caps">JSON</span> Schema sera aussi utilisé lors de l&#8217;affichage du formulaire aux - personnes qui le&nbsp;remplissent.</li> -<li>Un jeton d&#8217;accès est généré et ajouté à l&#8217;<span class="caps">URL</span>, il s&#8217;agit de l&#8217;identifiant du&nbsp;formulaire.</li> -<li>Un second jeton d&#8217;accès administrateur et généré, il vous faut le garder de - coté pour avoir accès aux&nbsp;réponses.</li> -</ul> -<p>Bref, en espérant que ça vous serve ! Un petit pas dans la direction des données -rendues à leurs utilisateurs&nbsp;!</p>Avez vous confiance en SSL?2016-03-25T00:00:00+01:002016-03-25T00:00:00+01:00tag:blog.notmyidea.org,2016-03-25:/avez-vous-confiance-en-ssl.html<p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d&#8217;autodéfense numérique</a>, -j&#8217;ai passé un peu de temps à creuser sur l&#8217;utilisation de <span class="caps">SSL</span> puisque -contrairement à ce que la plupart des personnes ont encore tendance à croire, -le petit cadenas (qui prouve qu&#8217;une connexion <span class="caps">SSL</span> est en cours) n&#8217;est …</p><p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d&#8217;autodéfense numérique</a>, -j&#8217;ai passé un peu de temps à creuser sur l&#8217;utilisation de <span class="caps">SSL</span> puisque -contrairement à ce que la plupart des personnes ont encore tendance à croire, -le petit cadenas (qui prouve qu&#8217;une connexion <span class="caps">SSL</span> est en cours) n&#8217;est -<strong>absolument</strong> pas&nbsp;suffisant.</p> -<p>Allez hop, c&#8217;est parti&nbsp;pour:</p> -<ul> -<li>un tour d&#8217;horizon du fonctionnement de&nbsp;SSl</li> -<li>quelques moyens contourner cette &#8220;protection&#8221; en faisant une attaque en&nbsp;pratique</li> -<li>un tour des solutions existantes actuellement et de pourquoi je ne les trouve - pas vraiment&nbsp;satisfaisantes.</li> -</ul> -<h2 id="comment-fonctionne-ssl">Comment fonctionne <span class="caps">SSL</span>?</h2> -<p>Pour expliquer les problèmes de <span class="caps">SSL</span>, j&#8217;ai d&#8217;abord besoin d&#8217;expliquer comment -tout ça&nbsp;fonctionne.</p> -<p><span class="caps">SSL</span> repose sur l&#8217;utilisation de certificats, qui sont générés par des autorités -de certification (<em>Certificate Authority</em> que je nomme <em><span class="caps">CA</span></em> dans la suite de&nbsp;l&#8217;article).</p> -<p>Les certificats <span class="caps">SSL</span> permettent deux&nbsp;choses:</p> -<ul> -<li>De garantir que les communications entre les navigateurs (vous) et les sites - Web ne sont connues que du détenteur du certificat du site et de vous&nbsp;même.</li> -<li>De garantir que le site sur lequel vous vous connectez est bien celui que - vous&nbsp;imaginez.</li> -</ul> -<p>Le navigateur, lors d&#8217;une visite d&#8217;un site, va télécharger le certificat -associé puis vérifier que le certificat en question a bien été généré par un -des <em><span class="caps">CA</span></em> en qui il a&nbsp;confiance.</p> -<p>Imaginons maintenant qu&#8217;une des <em><span class="caps">CA</span></em> essaye de savoir ce qui s&#8217;échange entre -mon navigateur et le site de ma banque (protégé par <span class="caps">SSL</span>). Comment cela se -passerait il&nbsp;?</p> -<p>N&#8217;importe quel <em><span class="caps">CA</span></em> peut donc générer des certificats pour n&#8217;importe quel site, -et le navigateur vérifierait, lui, que le certificat a bien été généré par une -<em><span class="caps">CA</span></em>.</p> -<p>Tout cela ne poserait pas de soucis si les <em><span class="caps">CA</span></em> étaient gérés de manière fiable, -mais il s&#8217;agit d&#8217;un travail compliqué, et certains <em><span class="caps">CA</span></em> ont par le passé montré -des&nbsp;faiblesses.</p> -<p>Par exemple, <a href="https://en.wikipedia.org/wiki/DigiNotar">DigiNotar</a> (un <em><span class="caps">CA</span></em> des Pays-Bas) -a été compromise et les attaquant.e.s ont pu générer des certificats <span class="caps">SSL</span> -frauduleux, ce qui leur a permis d&#8217;attaquer des sites tels que Facebook ou&nbsp;GMail.</p> -<p>Vous pouvez retrouver une liste des risques et menaces autour des <em><span class="caps">CA</span></em> <a href="http://wiki.cacert.org/Risk/History">sur le -wiki de CACert</a>.</p> -<h2 id="attaque-de-lhomme-du-milieu-avec-ssl">Attaque de l&#8217;homme du milieu avec <span class="caps">SSL</span></h2> -<p>A force de dire que c&#8217;était très facile à faire, j&#8217;ai eu envie d&#8217;essayer -d&#8217;espionner des connections protégées par <span class="caps">SSL</span>, et effectivement c&#8217;est -carrément flippant tellement c&#8217;est&nbsp;simple.</p> -<p>En l&#8217;espace de quelques minutes, il est possible de faire une <em>attaque de -l&#8217;homme du milieu</em> en utilisant par exemple un outil nommé <a href="http://docs.mitmproxy.org/en/stable">mitm-proxy</a>.</p> -<p>Pour déchiffrer l&#8217;ensemble du trafic <span class="caps">SSL</span>, j&#8217;ai simplement eu à lancer quelques -commandes et avoir un <em><span class="caps">CA</span></em> dans lequel le navigateur de la victime a confiance. -Je l&#8217;ai ajouté dans le navigateur cible pour simuler que je l&#8217;avais déjà -(c&#8217;est le cas si un des 1200 <span class="caps">CA</span> se fait pirater, ce qui me semble une surface -d&#8217;attaque assez&nbsp;large).</p> -<p>Je les colle ici si ça vous&nbsp;intéresse:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>sudo<span class="w"> </span>aptitude<span class="w"> </span>install<span class="w"> </span>mitmproxy -$<span class="w"> </span>mitm-proxy<span class="w"> </span>-T<span class="w"> </span>--host -</code></pre></div> - -<p>Il faut faire croire à votre victime que vous êtes la passerelle vers -l&#8217;extérieur et à la passerelle que vous êtes la&nbsp;victime:</p> -<div class="highlight"><pre><span></span><code>arpspoof<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-t<span class="w"> </span>victime<span class="w"> </span>gateway -arpspoof<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-t<span class="w"> </span>gateway<span class="w"> </span>victime -</code></pre></div> - -<p>Puis dire à notre fausse passerelle de rediriger le trafic des ports 80 et 443 -vers notre&nbsp;proxy:</p> -<div class="highlight"><pre><span></span><code>sudo<span class="w"> </span>sysctl<span class="w"> </span>-w<span class="w"> </span>net.ipv4.ip_forward<span class="o">=</span><span class="m">1</span> -sudo<span class="w"> </span>iptables<span class="w"> </span>-t<span class="w"> </span>nat<span class="w"> </span>-A<span class="w"> </span>PREROUTING<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-p<span class="w"> </span>tcp<span class="w"> </span>--dport<span class="w"> </span><span class="m">443</span><span class="w"> </span>-j<span class="w"> </span>REDIRECT<span class="w"> </span>--to-port<span class="w"> </span><span class="m">4443</span> -sudo<span class="w"> </span>iptables<span class="w"> </span>-t<span class="w"> </span>nat<span class="w"> </span>-A<span class="w"> </span>PREROUTING<span class="w"> </span>-i<span class="w"> </span>wlan0<span class="w"> </span>-p<span class="w"> </span>tcp<span class="w"> </span>--dport<span class="w"> </span><span class="m">80</span><span class="w"> </span>-j<span class="w"> </span>REDIRECT<span class="w"> </span>--to-port<span class="w"> </span><span class="m">4443</span> -</code></pre></div> - -<p>Et paf, <strong>on voit tout ce qui passe entre la machine et le serveur <span class="caps">SSL</span></strong>. On peut -d&#8217;ailleurs même imaginer faire tourner ces quelques commandes sur un -raspberry pi, pour aller encore plus&nbsp;vite…</p> -<h3 id="key-pinning-dans-les-navigateurs">Key-pinning dans les&nbsp;navigateurs</h3> -<p>Actuellement, n&#8217;importe quel <em><span class="caps">CA</span></em> peut générer des certificats pour -n&#8217;importe quel site, et c&#8217;est en grande partie ce qui pose souci. Une des -manières de faire évoluer la situation est d&#8217;épingler les certificats de -certains sites directement dans les&nbsp;navigateurs.</p> -<p>Cette approche a le mérite de fonctionner très bien <a href="https://dxr.mozilla.org/mozilla-central/source/security/manager/ssl/StaticHPKPins.h?from=StaticHPKPins.h">pour un petit nombre de -sites critiques (Google, Facebook, etc)</a>.</p> -<h3 id="http-public-key-pinning-hpkp"><span class="caps">HTTP</span> Public Key Pinning (<span class="caps">HPKP</span>)</h3> -<p><a href="https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning"><em><span class="caps">HTTP</span> Public Key Pinning</em></a> -est également une solution de <em>pinning</em> qui permet d&#8217;établir une confiance lors -de la première connexion avec le site. C&#8217;est ce qu&#8217;on appelle du <em>Trust on First -Use</em> ou <em><span class="caps">TOFU</span></em>.</p> -<p>Le navigateur va alors mettre ces informations dans un cache et vérifiera que -les certificats correspondent bien lors des prochaines&nbsp;visites.</p> -<p><em><span class="caps">HPKP</span></em> est disponible dans Firefox depuis Janvier 2015 et dans Chrome -depuis Octobre&nbsp;2015.</p> -<h3 id="certificate-transparency-des-journaux-auditables">Certificate transparency: des journaux&nbsp;auditables</h3> -<p>Une autre approche est celle proposée par <em>certificate transparency</em>:</p> -<blockquote> -<p>Certificate Transparency aims to remedy these certificate-based threats by -making the issuance and existence of <span class="caps">SSL</span> certificates open to scrutiny by -domain owners, CAs, and domain&nbsp;users.</p> -<p>&#8212; <a href="https://www.certificate-transparency.org/what-is-ct">Certificate&nbsp;Transparency</a></p> -</blockquote> -<p>Autrement dit, avec ce système les <em><span class="caps">CA</span></em> doivent rendre public le fait qu&#8217;ils -aient signé de nouveaux certificats intermédiaires. La signature est ajoutée à -un journal sur lequel il n&#8217;est possible que&nbsp;d&#8217;écrire.</p> -<p>Les navigateurs vont alors vérifier que les certificats utilisés sont bien des -certificats qui ont été ajoutés au&nbsp;journal.</p> -<p>Ici, toute l&#8217;intelligence est dans la vérification de ces journaux, qui -permettent donc de valider/invalider des certificats racines ou&nbsp;intermédiaires.</p> -<p>Il me semble donc qu&#8217;il serait possible d&#8217;ajouter un certificat frauduleux le -temps d&#8217;une attaque (et celui ci serait détecté et supprimé&nbsp;ensuite).</p> -<p><em>Certificate-Transparency</em> n&#8217;est donc pas une solution contre une écoute -globale mise en place par les gouvernements par&nbsp;exemple.</p> -<p>Si vous lisez bien l&#8217;anglais, je vous invite à aller lire -<a href="http://security.stackexchange.com/a/52838">cette description du problème et de la solution</a> -que je trouve très bien&nbsp;écrite.</p> -<h3 id="dane-dnssec"><span class="caps">DANE</span> + <span class="caps">DNSSEC</span></h3> -<blockquote> -<p>The <span class="caps">DANE</span> working group has developed a framework for securely -retrieving keying information from the <span class="caps">DNS</span> [<span class="caps">RFC6698</span>]. This -framework allows secure storing and looking up server public key -information in the <span class="caps">DNS</span>. This provides a binding between a domain -name providing a particular service and the key that can be used -to establish encrypted connection to that&nbsp;service.</p> -<p>&#8212; <a href="https://datatracker.ietf.org/wg/dane/charter/">Dane <span class="caps">WG</span></a></p> -</blockquote> -<p>Une autre solution est appelée &#8220;<span class="caps">DANE</span>&#8221; et repose par dessus le protocole -<em><span class="caps">DNSSEC</span></em>.</p> -<p>Je connais assez mal <em><span class="caps">DNSSEC</span></em> donc j&#8217;ai passé un peu de temps à lire des -documents. L&#8217;impression finale que ça me laisse est que le problème est -exactement le même que pour <span class="caps">SSL</span>: un certain nombre de personnes détiennent les -clés et toute la sécurité repose sur cette confiance. Or il est possible que -ces clés soient détenues par des personnes non dignes de&nbsp;confiance.</p> -<blockquote> -<p>Secure <span class="caps">DNS</span> (<span class="caps">DNSSEC</span>) uses cryptographic digital signatures signed with a -trusted public key certificate to determine the authenticity of data. -&#8212;&nbsp;https://en.wikipedia.org/wiki/DNS_spoofing</p> -</blockquote> -<p>Et&nbsp;aussi:</p> -<blockquote> -<p>It is widely believed[1] that securing the <span class="caps">DNS</span> is critically important for -securing the Internet as a whole, but deployment of <span class="caps">DNSSEC</span> specifically has -been hampered (As of 22 January 2010) by several&nbsp;difficulties:</p> -<ul> -<li>The need to design a backward-compatible standard that can scale to the - size of the&nbsp;Internet</li> -<li>Prevention of &#8220;zone enumeration&#8221; (see below) where&nbsp;desired</li> -<li>Deployment of <span class="caps">DNSSEC</span> implementations across a wide variety of <span class="caps">DNS</span> servers - and resolvers&nbsp;(clients)</li> -<li>Disagreement among implementers over who should own the top-level domain - root keys Overcoming the perceived complexity of <span class="caps">DNSSEC</span> and <span class="caps">DNSSEC</span>&nbsp;deployment</li> -</ul> -</blockquote> -<h2 id="solutions-basees-sur-la-blockchain">Solutions basées sur la&nbsp;blockchain</h2> -<p>Une dernière piste semble être l&#8217;utilisation de la <em>blockchain</em> pour distribuer -des clés par&nbsp;site.</p> -<p>La solution <em>DNSChain</em> me paraissait tout d&#8217;abord un bon point de départ mais -la lecture de <a href="https://www.indolering.com/okturtles-dnschain-unblock-us">quelques critiques</a> -et interventions du développeur du projet m&#8217;ont fait changer&nbsp;d&#8217;avis.</p> -<p>Reste encore la piste de <em>Namecoin Control</em> que je n&#8217;ai pas encore creusée. -Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la -bienvenue sur ces&nbsp;sujets!</p>Retours sur un atelier ZeroNet2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00tag:blog.notmyidea.org,2016-03-17:/retours-sur-un-atelier-zeronet.html<p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> dans les locaux de l&#8217;<span class="caps">INSA</span> de&nbsp;Rennes.</p> -<p>L&#8217;évènement s&#8217;étant rempli au delà de toutes les espérances, on m&#8217;a proposé de -venir y tenir un atelier, que j&#8217;ai proposé sur <a href="https://zeronet.io">ZeroNet</a>, un -petit projet fort sympathique qui pourrait devenir une …</p><p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> dans les locaux de l&#8217;<span class="caps">INSA</span> de&nbsp;Rennes.</p> -<p>L&#8217;évènement s&#8217;étant rempli au delà de toutes les espérances, on m&#8217;a proposé de -venir y tenir un atelier, que j&#8217;ai proposé sur <a href="https://zeronet.io">ZeroNet</a>, un -petit projet fort sympathique qui pourrait devenir une nouvelle manière de -distribuer le Web, permettant notamment d&#8217;éviter la&nbsp;censure.</p> -<p>Avant toute autre chose, merci énormément à l&#8217;équipe de la bibliothèque de -l&#8217;<span class="caps">INSA</span> pour l&#8217;organisation de cet évènement qui à une réelle portée&nbsp;politique.</p> -<h2 id="un-peu-dhistoire">Un peu&nbsp;d&#8217;histoire</h2> -<p>Il me semble que Tim Bernes Lee (l&#8217;inventeur du Web) avait prévu le Web comme un -protocole décentralisé. Chacun hébergerait ses données et les servirait aux -autres, qui pourraient alors y&nbsp;accéder.</p> -<p>Avec ce fonctionnement, impossible alors d&#8217;accéder à des sites si leur auteur -n&#8217;est pas en ligne. Qu&#8217;à cela ne tienne, on s&#8217;est mis à avoir des machines qui -restent connectées au réseau 24 heures par jour. Et puis une machine ne -suffisant plus, on a eu des fermes de machines dans des <em>data centers</em> etc afin -de supporter les milliers d&#8217;utilisateurs des&nbsp;sites.</p> -<h2 id="un-web-decentralise">Un Web&nbsp;décentralisé</h2> -<p>ZeroNet permet (entre autres) de répondre à ce problème en proposant une manière alternative de <strong>distribuer le Web</strong>, en pair à pair. Lors d&#8217;une visite d&#8217;un&nbsp;site:</p> -<ol> -<li>Vous contactez un <em>tracker</em> BitTorrent pour connaitre la liste des autres - visiteurs du site (les <em>pairs</em>).</li> -<li>Vous demandez aux <em>pairs</em> de vous donner les fichiers du&nbsp;site.</li> -<li>Vous validez que les fichiers servis sont bien les bons (en vérifiant la - signature&nbsp;attachée).</li> -</ol> -<p>N&#8217;importe quel visiteur devient alors un <em>pair</em>, qui sert le site aux autres&nbsp;visiteurs.</p> -<p>Parmi les nombreux avantages de cette approche, je note particulièrement&nbsp;que:</p> -<ul> -<li>Il est très difficile de censurer un site — Il est sur l&#8217;ensemble des machines - des&nbsp;visiteurs.</li> -<li>Les attaques par <em>fingerprinting</em> sont impossibles: le navigateur Web se - connecte à un serveur <em>proxy</em>&nbsp;local.</li> -<li>Vous détenez directement vos données et (par design) ne les donnez pas à des - silos (Facebook, Google,&nbsp;etc.)</li> -</ul> -<p>Si vous êtes interessés par une démonstration rapide, j&#8217;ai enregistré une vidéo -de 10 minutes où je parle en anglais avec une voix très&nbsp;grave.</p> -<video controls="" src="http://alexis.notmyidea.org/zeronet.webm" width=800></video> - -<h2 id="atelier">Atelier</h2> -<p>Pour l&#8217;atelier, j&#8217;ai choisi de faire une présentation rapide du projet (<a href="https://blog.notmyidea.org/docs/zeronet-presentation-fr.pdf">j&#8217;ai -traduit les slides</a> anglais -pour l&#8217;occasion — <a href="https://docs.google.com/presentation/d/158C_-V1ueNaaKHMBMBgGOVhunb9xrXzB3hC_g1N53c0/edit?usp=sharing">accès aux sources</a>) -avant d&#8217;installer ZeroNet sur les machines et de l&#8217;utiliser pour publier un&nbsp;site.</p> -<h3 id="partager-sur-le-reseau-local">Partager sur le réseau&nbsp;local</h3> -<p>Nous avons eu des soucis à cause du réseau (un peu congestionné) sur lequel -les ports utilisés pour la discussion entre <em>pairs</em> étaient fermés. Il est bien -sur possible de faire tourner le tout de manière indépendante du reste du réseau, -mais je n&#8217;avais pas prévu le&nbsp;coup.</p> -<p>Voici donc comment faire pour contourner le&nbsp;souci:</p> -<ol> -<li>Installer et lancer un <em>tracker</em> BitTorrent (De manière surprenante, - <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=685575">rien n&#8217;est packagé pour debian pour l&#8217;instant</a>) - J&#8217;ai choisi d&#8217;installer <a href="http://erdgeist.org/arts/software/opentracker/#build-instructions">OpenTracker</a></li> -<li>Ensuite lancer ZeroNet avec des options&nbsp;spécifiques.</li> -</ol> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>python<span class="w"> </span>zeronet.py<span class="w"> </span>--trackers<span class="w"> </span>udp://localhost:6969<span class="w"> </span>--ip_external<span class="w"> </span><span class="m">192</span>.168.43.207 -$<span class="w"> </span>python<span class="w"> </span>zeronet.py<span class="w"> </span>--trackers<span class="w"> </span>udp://192.168.43.207:6969<span class="w"> </span>--ip_external<span class="w"> </span><span class="m">192</span>.168.43.172 -</code></pre></div> - -<p>Il est nécessaire de spécifier l&#8217;adresse <span class="caps">IP</span> externe que chaque nœud expose pour -éviter qu&#8217;elle n&#8217;essaye d&#8217;aller la trouver par elle même: nous voulons l&#8217;adresse -du réseau local, et non pas l&#8217;adresse&nbsp;internet.</p> -<p>La prochaine fois je tenterais de venir avec un HotSpot Wifi et un tracker -BitTorrent dans la&nbsp;poche!</p> -<h2 id="questions-reponses">Questions /&nbsp;Réponses</h2> -<p>Il y avait quelques questions intéressantes auxquelles je n&#8217;ai pas toujours su -répondre sur le moment. Après quelques recherches, je rajoute des détails&nbsp;ici.</p> -<h3 id="torrent-tor-breche-de-secu">Torrent + Tor = brèche de sécu&nbsp;?</h3> -<p>Il me semblait avoir entendu parler de problèmes de <em>dé-anonymisation</em> -<a href="https://hal.inria.fr/file/index/docid/471556/filename/TorBT.pdf">lors de l&#8217;utilisation de BitTorrent par dessus Tor</a>.</p> -<blockquote> -<p>Dans certains cas, certains clients torrents (uTorrent, BitSpirit, etc) -écrivent directement votre adresse <span class="caps">IP</span> dans l&#8217;information qui est envoyée -au tracker et/ou aux autres pairs. -—&nbsp;https://blog.torproject.org/blog/bittorrent-over-tor-isnt-good-idea</p> -</blockquote> -<p><a href="https://github.com/HelloZeroNet/ZeroNet/issues/274">Ce n&#8217;est pas le cas de ZeroNet</a>, ce qui évacue le&nbsp;souci.</p> -<h3 id="zeromail-cest-lent-non">ZeroMail, c&#8217;est lent non&nbsp;?</h3> -<p>Une des applications de démo, <em>ZeroMail</em>, propose un mécanisme qui permet de -s&#8217;envoyer des messages chiffrés sur un réseau pair à pair. L&#8217;approche choisie -est de chiffrer les messages avec la clé du destinataire et de le mettre dans -un <em>pot commun</em>. Tout le monde essaye de déchiffrer tous les messages, mais ne -peut déchiffrer que les&nbsp;siens.</p> -<p>Cela permet de ne <strong>pas</strong> fuiter de méta-données, <a href="https://blog.notmyidea.org/les-problemes-de-pgp.html">à l&#8217;inverse de <span class="caps">PGP</span></a>.</p> -<p>Je n&#8217;ai en fait pas de réponse claire à donner à cette question: l&#8217;auteur de -ZeroNet me disait que <span class="caps">10MB</span> (la limite de taille d&#8217;un site, par défaut) -correspondait à beaucoup de place pour stocker des messages, et qu&#8217;il était -possible de supprimer les anciens messages une fois qu&#8217;ils sont lus par&nbsp;exemple.</p> -<p>Une autre solution à laquelle je pensait était de créer un <em>ZeroSite</em> pour -chaque récipient, mais on connait à ce moment là le nombre de messages qu&#8217;un -utilisateur peut&nbsp;recevoir.</p> -<p>Je vois plusieurs problèmes avec le design actuel de ZeroMail (il me semble -assez facile d&#8217;y faire un déni de service par exemple). A&nbsp;creuser.</p> -<h3 id="comment-heberger-des-tres-gros-sites">Comment héberger des très gros sites&nbsp;?</h3> -<p>Par exemple, comment faire pour héberger Wikipedia&nbsp;?</p> -<p>Il semble que la meilleure manière de faire serait de séparer Wikipedia en -un tas de petites ressources (par catégorie par ex.). Les gros médias pourraient -être considérés optionnels (et donc téléchargés uniquement à la&nbsp;demande)</p> -<h3 id="est-ce-quon-a-vraiment-besoin-dun-tracker">Est-ce qu&#8217;on à vraiment besoin d&#8217;un tracker&nbsp;?</h3> -<p>Le support d&#8217;une <span class="caps">DHT</span> <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, -mais pour l&#8217;instant pas encore implémenté. L&#8217;utilisation de la <span class="caps">DHT</span> BitTorrent -n&#8217;est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas <span class="caps">UDP</span></a>.</p>Service de nuages : Garantir l’intégrité des données via des signatures2016-03-01T00:00:00+01:002016-03-01T00:00:00+01:00tag:blog.notmyidea.org,2016-03-01:/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.html<p class="first last">Comment garantir l&#8217;intégrité des données en utilisant les&nbsp;signatures.</p> -<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> -<p>Dans le cadre du projet <a class="reference external" href="https://wiki.mozilla.org/Firefox/Go_Faster">Go Faster</a>, nous souhaitons distribuer des -mises à jour de parties de <em>Firefox</em> de manière séparée des mises à jour majeures -(qui ont lieu toutes les 6&nbsp;semaines).</p> -<p>Les données que nous souhaitons mettre à jour sur les clients sont multiples. -Entre autres, nous souhaitons gérer <a class="reference external" href="https://blog.mozilla.org/security/2015/03/03/revoking-intermediate-certificates-introducing-onecrl/">la mise à jour des listes de révocation -(<span class="caps">CRL</span>) de certificats <span class="caps">SSL</span></a>.</p> -<p>Il est évidemment nécessaire de s&#8217;assurer que les données qui sont téléchargées -sur les client sont légitimes : que personne ne tente d&#8217;invalider des -certificats alors qu&#8217;ils sont valides, et que l&#8217;ensemble des mises à jour sont -bel et bien récupérées sur le&nbsp;client.</p> -<p>La signature garantit qu&#8217;une mise à jour contient tous les enregistrements, mais il -est toujours possible de bloquer l&#8217;accès au service (par exemple avec le <em>china -great firewall</em>).</p> -<p>Ce mécanisme fonctionne pour les listes de certificats à révoquer, mais pas -uniquement. Nous comptons réutiliser ce même fonctionnement dans le futur pour -la mise à jour d&#8217;autres parties de Firefox, et vous pouvez également en tirer -parti pour d&#8217;autres cas&nbsp;d&#8217;utilisation.</p> -<p>Nous souhaitons utiliser <a class="reference external" href="https://kinto.readthedocs.org">Kinto</a> afin -de distribuer ces jeux de données. Un des avantages est que l&#8217;on peut -facilement <em>cacher</em> les collections derrière un <span class="caps">CDN</span>.</p> -<p>Par contre, nous ne souhaitons pas que les clients fassent -confiance aveuglément, ni au serveur Kinto, ni au <span class="caps">CDN</span>.</p> -<p>Effectivement, un attaquant, contrôlant l&#8217;un ou l&#8217;autre, pourrait -alors envoyer les mises à jour qu&#8217;il souhaite à l&#8217;ensemble des clients -ou supprimer des certificats révoqués. Imaginez le carnage&nbsp;!</p> -<p>Afin de résoudre ce problème, considérons les conditions&nbsp;suivantes:</p> -<ul class="simple"> -<li>La personne qui a le pouvoir de mettre à jour les <span class="caps">CRL</span> (<em>l&#8217;updater</em>) -a accès à une cle de signature (ou mieux, <a class="reference external" href="https://fr.wikipedia.org/wiki/Hardware_Security_Module">un <span class="caps">HSM</span></a>) qui lui permet de -signer la&nbsp;collection;</li> -<li>Le pendant public de ce certificat est stocké et distribué dans&nbsp;Firefox;</li> -<li>Le <em>hashing</em> et la <em>signature</em> sont faits côté client pour éviter certains -vecteurs d&#8217;attaque (si un attaquant a la main sur le serveur Kinto par&nbsp;exemple).</li> -</ul> -<p>Le chiffrement à sens unique, aussi appellé <em>hashing</em> est un moyen de toujours -obtenir le même résultat à partir de la même&nbsp;entrée.</p> -<div class="section" id="premier-envoi-de-donnees-sur-kinto"> -<h2>Premier envoi de données sur&nbsp;Kinto</h2> -<p>L&#8217;ensemble des données est récupéré depuis une source <em>sécurisée</em> puis mis dans -une collection <span class="caps">JSON</span>. Chaque élément contient un identifiant unique généré sur -le&nbsp;client.</p> -<p>Par exemple, un enregistrement peut ressembler à&nbsp;:</p> -<div class="highlight"><pre><span></span><span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;b7dded96-8df0-8af8-449a-8bc47f71b4c4&quot;</span><span class="p">,</span> -<span class="w"> </span><span class="s2">&quot;fingerprint&quot;</span><span class="o">:</span><span class="w"> </span><span class="s2">&quot;11:D5:D2:0A:9A:F8:D9:FC:23:6E:5C:5C:30:EC:AF:68:F5:68:FB:A3&quot;</span><span class="p">}</span> -</pre></div> -<p>Le <em>hash</em> de la collection est ensuite calculé, signé puis envoyé au serveur -(voir plus bas pour les&nbsp;détails).</p> -<p>La signature est déportée sur un service qui ne s&#8217;occupe que de ça, puisque la -sécurité du certificat qui s&#8217;occupe des signatures est extrêmement&nbsp;importante.</p> -</div> -<div class="section" id="comment-verifier-l-integrite-des-donnees"> -<h2>Comment vérifier l&#8217;intégrité des données&nbsp;?</h2> -<p>Premièrement, il faut récupérer l&#8217;ensemble des enregistrements présents sur -le serveur, ainsi que le <em>hash</em> et la signature&nbsp;associée.</p> -<p>Ensuite, vérifier la signature du <em>hash</em>, pour s&#8217;assurer que celui-ci provient -bien d&#8217;un tiers de&nbsp;confiance.</p> -<p>Finalement, recalculer le <em>hash</em> localement et valider qu&#8217;il correspond bien à -celui qui a été&nbsp;signé.</p> -</div> -<div class="section" id="ajouter-de-nouvelles-donnees"> -<h2>Ajouter de nouvelles&nbsp;données</h2> -<p>Pour l&#8217;ajout de nouvelles données, il est nécessaire de s&#8217;assurer que les -données que l&#8217;on a localement sont valides avant de faire quoi que ce soit&nbsp;d&#8217;autre.</p> -<p>Une fois ces données validées, il suffit de procéder comme la première fois, et -d&#8217;envoyer à nouveau le <em>hash</em> de la collection au&nbsp;serveur.</p> -</div> -<div class="section" id="comment-calculer-ce-hash"> -<h2>Comment calculer ce hash&nbsp;?</h2> -<p>Pour calculer le <em>hash</em> de la collection, il est nécessaire&nbsp;:</p> -<ol class="arabic simple"> -<li>D&#8217;ordonner l&#8217;ensemble des éléments de la collection (par leur id)&nbsp;;</li> -<li>Pour chaque élément, sérialiser les champs qui nous intéressent (les -concaténer clé +&nbsp;valeur)</li> -<li>Calculer le <em>hash</em> depuis la&nbsp;sérialisation.</li> -</ol> -<p>Nous sommes encore incertains de la manière dont le hash va être calculé. Les <a class="reference external" href="https://tools.ietf.org/html/draft-ietf-jose-json-web-signature-41"><span class="caps">JSON</span> Web Signature</a> semblent -une piste intéressante. En attendant, une implementation naïve en python -pourrait ressembler à ceci&nbsp;:</p> -<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">json</span> -<span class="kn">import</span> <span class="nn">hashlib</span> - -<span class="n">data</span> <span class="o">=</span> <span class="p">[</span> - <span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;b7dded96-8df0-8af8-449a-8bc47f71b4c4&quot;</span><span class="p">,</span> - <span class="s2">&quot;fingerprint&quot;</span><span class="p">:</span> <span class="s2">&quot;11:D5:D2:0A:9A:F8:D9:FC:23:6E:5C:5C:30:EC:AF:68:F5:68:FB:A3&quot;</span><span class="p">},</span> - <span class="p">{</span><span class="s2">&quot;id&quot;</span><span class="p">:</span> <span class="s2">&quot;dded96b7-8f0d-8f8a-49a4-7f771b4c4bc4&quot;</span><span class="p">,</span> - <span class="s2">&quot;fingerprint&quot;</span><span class="p">:</span> <span class="s2">&quot;33:6E:5C:5C:30:EC:AF:68:F5:68:FB:A3:11:D5:D2:0A:9A:F8:D9:FC&quot;</span><span class="p">}]</span> - -<span class="n">m</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">()</span> -<span class="n">m</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">sort_keys</span><span class="o">=</span><span class="kc">True</span><span class="p">))</span> -<span class="n">collection_hash</span> <span class="o">=</span> <span class="n">m</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span> -</pre></div> -</div> -Let’s Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> -<blockquote> -<p>It’s time for the Web to take a big step forward in terms …</p></blockquote><p><em>Note : Cet article n&#8217;est plus à jour. Il est maintenant (2018) possible d&#8217;installer des certificats <span class="caps">SSL</span> Let&#8217;s Encrypt d&#8217;une manière beaucoup plus simple, en utilisant certbot (et le plugin nginx <code>certbot --nginx</code>).</em></p> -<blockquote> -<p>It’s time for the Web to take a big step forward in terms of security -and privacy. We want to see <span class="caps">HTTPS</span> become the default. Let’s Encrypt -was built to enable that by making it as easy as possible to get and -manage&nbsp;certificates.</p> -<p>&#8212; <a href="https://letsencrypt.org/">Let&#8217;s&nbsp;Encrypt</a></p> -</blockquote> -<p>Depuis début Décembre, la nouvelle <em>autorité de certification</em> Let&#8217;s -Encrypt est passée en version <em>Beta</em>. Les certificats <span class="caps">SSL</span> sont un moyen -de 1. chiffrer la communication entre votre navigateur et le serveur et -2. un moyen d&#8217;être sur que le site Web auquel vous accédez est celui -auquel vous pensez vous connecter (pour éviter des <a href="https://fr.wikipedia.org/wiki/Attaque_de_l'homme_du_milieu">attaques de l&#8217;homme -du milieu</a>).</p> -<p>Jusqu&#8217;à maintenant, il était nécessaire de payer une entreprise pour -faire en sorte d&#8217;avoir des certificats qui évitent d&#8217;avoir ce genre -d&#8217;erreurs dans vos&nbsp;navigateurs:</p> -<p><img alt="Message de firefox lorsque une connexion n'est pas -sécurisée." src="%7Bfilename%7D/static/unsecure-connection.png"></p> -<p>Maintenant, grâce à Let&#8217;s Encrypt il est possible d&#8217;avoir des -certificats <span class="caps">SSL</span> <strong>gratuits</strong>, ce qui représente un grand pas en avant -pour la sécurité de nos&nbsp;communications.</p> -<p>Je viens de mettre en place un procédé (assez simple) qui permet de -configurer votre serveur pour générer des certificats <span class="caps">SSL</span> valides avec -Let&#8217;s Encrypt et le répartiteur de charge -<a href="http://www.haproxy.org/">HAProxy</a>.</p> -<p>Je me suis basé pour cet article sur -d&#8217;<a href="https://blog.infomee.fr/p/letsencrypt-haproxy">autres</a> -<a href="http://blog.victor-hery.com/article22/utiliser-let-s-encrypt-avec-haproxy">articles</a>, -dont je vous recommande la lecture pour un complément&nbsp;d&#8217;information.</p> -<h2 id="validation-des-domaines-par-lets-encrypt">Validation des domaines par Let&#8217;s&nbsp;Encrypt</h2> -<p>Je vous passe les détails d&#8217;installation du client de Let&#8217;s Encrypt, qui -sont <a href="https://github.com/letsencrypt/letsencrypt#installation">très bien expliqués sur leur -documentation</a>.</p> -<p>Une fois installé, vous allez taper une commande qui va ressembler&nbsp;à:</p> -<div class="highlight"><pre><span></span><code>letsencrypt-auto certonly --renew-by-default ---webroot -w /home/www/letsencrypt-requests/ \ --d hurl.kinto-storage.org \ --d forums.kinto-storage.org -</code></pre></div> - -<p>Le <em>webroot</em> est l&#8217;endroit ou les preuves de détention du domaine vont -être&nbsp;déposées.</p> -<p>Lorsque les serveurs de Let&#8217;s Encrypt vont vouloir vérifier que vous -êtes bien à l&#8217;origine des demandes de certificats, ils vont envoyer une -requête <span class="caps">HTTP</span> sur <code>http://domaine.org/.well-known/acme-challenge</code>, ou il -voudra trouver des informations qu&#8217;il aura généré via la commande -<code>letsencrypt-auto</code>.</p> -<p>J&#8217;ai choisi de faire une règle dans haproxy pour diriger toutes les -requêtes avec le chemin <code>.well-known/acme-challenge</code> vers un <em>backend</em> -nginx qui sert des fichiers statiques (ceux contenus dans -<code>/home/www/letsencrypt-requests/</code>).</p> -<p>Voici la section de la configuration de HAProxy (et <a href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L63-L72">la configuration -complete</a> -si ça peut être&nbsp;utile):</p> -<div class="highlight"><pre><span></span><code><span class="nv">frontend</span><span class="w"> </span><span class="nv">http</span> -<span class="w"> </span><span class="nv">bind</span><span class="w"> </span><span class="mi">0</span>.<span class="mi">0</span>.<span class="mi">0</span>.<span class="mi">0</span>:<span class="mi">80</span> -<span class="w"> </span><span class="nv">mode</span><span class="w"> </span><span class="nv">http</span> -<span class="w"> </span><span class="nv">default_backend</span><span class="w"> </span><span class="nv">nginx_server</span> - -<span class="w"> </span><span class="nv">acl</span><span class="w"> </span><span class="nv">letsencrypt_check</span><span class="w"> </span><span class="nv">path_beg</span><span class="w"> </span><span class="o">/</span>.<span class="nv">well</span><span class="o">-</span><span class="nv">known</span><span class="o">/</span><span class="nv">acme</span><span class="o">-</span><span class="nv">challenge</span> -<span class="w"> </span><span class="nv">use_backend</span><span class="w"> </span><span class="nv">letsencrypt_backend</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nv">letsencrypt_check</span> - -<span class="w"> </span><span class="nv">redirect</span><span class="w"> </span><span class="nv">scheme</span><span class="w"> </span><span class="nv">https</span><span class="w"> </span><span class="nv">code</span><span class="w"> </span><span class="mi">301</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">!</span>{<span class="w"> </span><span class="nv">ssl_fc</span><span class="w"> </span>}<span class="w"> </span><span class="o">!</span><span class="nv">letsencrypt_check</span> - -<span class="nv">backend</span><span class="w"> </span><span class="nv">letsencrypt_backend</span> -<span class="w"> </span><span class="nv">http</span><span class="o">-</span><span class="nv">request</span><span class="w"> </span><span class="nv">set</span><span class="o">-</span><span class="nv">header</span><span class="w"> </span><span class="nv">Host</span><span class="w"> </span><span class="nv">letsencrypt</span>.<span class="nv">requests</span> -<span class="w"> </span><span class="nv">dispatch</span><span class="w"> </span><span class="mi">127</span>.<span class="mi">0</span>.<span class="mi">0</span>.<span class="mi">1</span>:<span class="mi">8000</span> -</code></pre></div> - -<p>Et celle de <span class="caps">NGINX</span>:</p> -<div class="highlight"><pre><span></span><code>server { - listen 8000; - server_name letsencrypt.requests; - root /home/www/letsencrypt-requests; -} -</code></pre></div> - -<h2 id="installation-des-certificats-dans-haproxy">Installation des certificats dans&nbsp;HAProxy</h2> -<p>Vos certificats <span class="caps">SSL</span> devraient être générés dans <code>/etc/letsencrypt/live</code>, -mais ils ne sont pas au format attendu par haproxy. Rien de grave, la -commande suivant convertit l&#8217;ensemble des certificats en une version -compatible avec&nbsp;HAProxy:</p> -<div class="highlight"><pre><span></span><code>cat /etc/letsencrypt/live/domaine.org/privkey.pem /etc/letsencrypt/live/domaine.org/fullchain.pem &gt; /etc/ssl/letsencrypt/domaine.org.pem -</code></pre></div> - -<p>Et ensuite dans la configuration de haproxy, pour le (nouveau) -<em>frontend</em>&nbsp;https:</p> -<div class="highlight"><pre><span></span><code>bind 0.0.0.0:443 ssl no-sslv3 crt /etc/ssl/letsencrypt -</code></pre></div> - -<p>Faites bien attention à avoir un <em>frontend</em> https pour tous vos sites en -<span class="caps">HTTPS</span>. <a href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L38-L60">Pour moi cela ressemble à -ça</a>.</p> -<p>Une fois tout ceci fait, redémarrez votre service haproxy et zou&nbsp;!</p> -<h2 id="automatisation">Automatisation</h2> -<p>Pour automatiser un peu tout ça, j&#8217;ai choisi de faire ça comme&nbsp;suit:</p> -<ul> -<li>Un fichier domaine dans <code>letsencrypt/domains/domain.org</code> qui - contient le script <code>letsencrypt</code>.</li> -<li>Un fichier d&#8217;installation de certificats dans - <code>letsencrypt/install-certs.sh</code> qui s&#8217;occupe d&#8217;installer les - certificats déjà&nbsp;générés.</li> -</ul> -<p>Et voila ! <a href="https://github.com/almet/infra/">Le tout est dans un dépot -github</a>, si jamais ça peut vous servir, -tant mieux&nbsp;!</p>Ateliers d’autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des -outils pour faire face à la surveillance généralisée, et notamment en -rapport au chiffrement des données. Une de mes envies de l&#8217;époque était -l&#8217;animation&nbsp;d&#8217;ateliers.</p> -<blockquote> -<p>Je compte&nbsp;donc:</p> -<ul> -<li>Organiser des ateliers de …</li></ul></blockquote><p>Il y a huit mois, je me rendais compte de l&#8217;importance du choix des -outils pour faire face à la surveillance généralisée, et notamment en -rapport au chiffrement des données. Une de mes envies de l&#8217;époque était -l&#8217;animation&nbsp;d&#8217;ateliers.</p> -<blockquote> -<p>Je compte&nbsp;donc:</p> -<ul> -<li>Organiser des ateliers de sensibilisation aux outils de - communication, envers mes&nbsp;proches;</li> -<li>Utiliser la communication chiffrée le plus souvent possible, au - moins pour rendre le déchiffrement des messages plus longue, - &#8220;noyer le&nbsp;poisson&#8221;.</li> -</ul> -<p>&#8212; <a href="http://blog.notmyidea.org/chiffrement.html">Chiffrement</a></p> -</blockquote> -<p>J&#8217;ai mis un peu de temps à mettre le pied à l&#8217;étrier, mais je ressors -finalement du premier atelier que j&#8217;ai co-animé avec geb, auprès d&#8217;un -public de&nbsp;journalistes.</p> -<p>Pour cette première édition l&#8217;idée était à la fois d&#8217;aller à la -rencontre d&#8217;un public que je connais mal, de leur donner des outils pour -solutionner les problèmes auxquels ils font parfois face, et de me faire -une idée de ce que pouvait être un atelier sur l&#8217;autodéfense&nbsp;numérique.</p> -<p>L&#8217;objectif pour ce premier atelier était&nbsp;de:</p> -<ol> -<li>Échanger autour des besoins et <strong>faire ressortir des histoires</strong> ou - le manque d&#8217;outillage / connaissances à posé problème, dans des - situations&nbsp;concrètes;</li> -<li>Se rendre compte des &#8220;conduites à risque&#8221;, <strong>faire peur</strong> aux - personnes formées pour qu&#8217;elles se rendent compte de l&#8217;état actuel - des&nbsp;choses;</li> -<li><strong>Proposer des solutions concrètes</strong> aux problèmes soulevés, ainsi - que le minimum de connaissance théorique pour les&nbsp;appréhender.</li> -</ol> -<h2 id="1-faire-ressortir-les-problemes">1. Faire ressortir les&nbsp;problèmes</h2> -<p>Afin de faire ressortir les problèmes, nous avons choisi de constituer -des petits groupes de discussion, afin de faire des &#8220;Groupes d&#8217;Interview -Mutuels&#8221;, ou &#8220;<span class="caps">GIM</span>&#8221;:</p> -<blockquote> -<p>l’animateur invite les participants à se regrouper par trois, avec des -personnes qu’on connaît moins puis invite chacun à livrer une -expérience vécue en lien avec le thème de la réunion et les deux -autres à poser des questions leur permettant de bien saisir ce qui a -été&nbsp;vécu.</p> -<p>&#8212; «<a href="http://www.scoplepave.org/pour-s-ecouter">Pour s&#8217;écouter</a>», <span class="caps">SCOP</span> -Le&nbsp;Pavé.</p> -</blockquote> -<p>De ces <em>GIMs</em> nous avons pu ressortir quelques histoires, gravitant -autour&nbsp;de:</p> -<ul> -<li><strong>La protection des sources (d&#8217;information)</strong>: Comment faire pour - aider quelqu&#8217;un à faire &#8220;fuiter&#8221; des données depuis l&#8217;intérieur - d&#8217;une entreprise&nbsp;?</li> -<li><strong>Le chiffrement de ses données</strong>: Comment éviter de faire &#8220;fuiter&#8221; - des données importantes lors d&#8217;une perquisition de matériel&nbsp;?</li> -</ul> -<h2 id="2-faire-peur">2. Faire&nbsp;peur</h2> -<p>Un des premiers objectifs est de faire peur, afin que tout le monde se -rende compte à quel point il est facile d&#8217;accéder à certaines données. -<a href="http://blog.barbayellow.com/">Grégoire</a> m&#8217;avait conseillé quelques -petites accroches qui ont ma foi bien&nbsp;marché:</p> -<p>J&#8217;ai demandé aux présent.e.s&nbsp;de:</p> -<ul> -<li>donner leur mot de passe à voix haute devant les autres: a priori - personne ne le&nbsp;fera;</li> -<li>venir se connecter à leur compte email depuis mon ordinateur. J&#8217;ai - piégé une personne, qui est venu pour taper son mot de&nbsp;passe.</li> -</ul> -<p>Cela à été un bon moyen de parler de l&#8217;importance des traces que l&#8217;on -peut laisser sur un ordinateur, et de la confiance qu&#8217;il faut avoir dans -le matériel que l&#8217;on utilise, à fortiori si ce ne sont pas les&nbsp;vôtres.</p> -<p>Pour continuer à leur faire peur, après une brève explication de ce -qu&#8217;est <span class="caps">SSL</span> nous avons montré comment il était facile de scruter le -réseau à la recherche de mots de passe en&nbsp;clair.</p> -<h2 id="3-proposer-des-solutions-concretes">3. Proposer des solutions&nbsp;concrêtes</h2> -<p>Une fois que tout le monde avait pleinement pris sonscience des -problématiques et n&#8217;osait plus utiliser son ordinateur ou son -téléphone, on à commencé à parler de quelques solutions. Plusieurs -approches étaient possibles ici, nous avons choisi de présenter quelques -outils qui nous semblaient répondre aux&nbsp;attentes:</p> -<ul> -<li>On a expliqué ce qu&#8217;était <a href="https://tails.boum.org">Tails</a>, et - comment l&#8217;utiliser et le&nbsp;dupliquer.</li> -<li>On a pu faire un tour des outils existants sur Tails, notamment - autour de l&#8217;<em>anonymisation</em> de fichiers et la suppression effective - de&nbsp;contenus.</li> -<li>Certaines personnes ont pu créer une clé tails avec la persistance - de&nbsp;configurée.</li> -<li>Nous nous sommes connectés au réseau - <a href="https://www.torproject.org">Tor</a> et testé que nos adresses <span class="caps">IP</span> - changeaient bien à la&nbsp;demande.</li> -<li>Nous avons utilisé <a href="https://crypto.cat">CryptoCat</a> par dessus Tor, - afin de voir comment avoir une conversation confidentielle dans - laquelle il est possible d&#8217;échanger des&nbsp;fichiers.</li> -</ul> -<h2 id="retours">Retours</h2> -<p>D&#8217;une manière générale, pour une formation de trois heures et demi, je -suis assez content de l&#8217;exercice, et de l&#8217;ensemble des sujets que nous -avons pu couvrir. Il y a beaucoup de place pour l&#8217;amélioration, -notamment en amont (j&#8217;avais par exemple oublié d&#8217;amener avec moi -suffisamment de clés <span class="caps">USB</span> pour utiliser&nbsp;Tails).</p> -<p>La plupart des retours qu&#8217;on a pu avoir jusqu&#8217;à maintenant sont -positifs, et il y a l&#8217;envie d&#8217;aller plus loin sur l&#8217;ensemble de ces&nbsp;sujets.</p> -<h2 id="la-suite">La&nbsp;suite</h2> -<p>Il y a beaucoup de sujets que nous n&#8217;avons pas abordés, ou uniquement -survolés, à cause du manque de temps disponible. Idéalement, il faudrait -au moins une journée entière pour couvrir quelques sujets plus en détail -(on peut imaginer avoir une partie théorique le matin et une partie -pratique l&#8217;après-midi par&nbsp;exemple).</p> -<p>J&#8217;ai choisi volontairement de ne pas aborder le chiffrement des messages -via <span class="caps">PGP</span> parce que <a href="%7Bfilename%7D2015.05.pgp-problemes.rst">je pense que la protection que ce média propose n&#8217;est -pas suffisante</a>, mais je suis -en train de revenir sur ma décision: il pourrait être utile de présenter -l&#8217;outil, à minima, en insistant sur certaines de ses&nbsp;faiblesses.</p> -<p>Un compte twitter à été créé recemment autour des crypto-party à Rennes, -si vous êtes interessés, <a href="https://twitter.com/CryptoPartyRNS">allez jeter un coup -d&#8217;œil</a>!</p> -<p>Je n&#8217;ai pas trouvé de ressources disponibles par rapport à des plans de -formation sur le sujet, j&#8217;ai donc décidé de publier les nôtres, afin de -co-construire avec d&#8217;autres des plans de&nbsp;formation.</p> -<p>Ils sont pour l&#8217;instant disponibles <a href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The -Docs</a>. Tous les -retours sont évidemment les bienvenus&nbsp;!</p>Le mail doit-il mourir ?2015-11-24T00:00:00+01:002015-11-24T00:00:00+01:00tag:blog.notmyidea.org,2015-11-24:/le-mail-doit-il-mourir.html<p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> -<p>Et même si j&#8217;arrive à convaincre certains de …</p><p>J&#8217;utilise quotidiennement le protocole email, tant bien que mal, tout en sachant que l&#8217;ensemble de mes messages passent en clair sur le réseau pour la plupart de mes conversations, puisque trop peu de monde utilise le chiffrement des&nbsp;messages.</p> -<p>Et même si j&#8217;arrive à convaincre certains de mes proches à installer <span class="caps">PGP</span>, je ne suis pas satisfait du résultat: les méta-données (qui contacte qui à quel -moment, et pour lui dire quoi) transitent de toute manière, elles, en clair, à la vue de&nbsp;tous.</p> -<p>Ce problème est lié directement au protocole email: il est <em>necessaire</em> de faire fuiter ces meta-données (au moins le destinataire) pour avoir un protocole -mail&nbsp;fonctionnel.</p> -<p>Le mail répond à un besoin de communication asynchrone qui permet des conversations plus réfléchies qu&#8217;un simple chat (miaou). Il est tout à fait possible d&#8217;utiliser certaines technologies existantes afin de construire le futur de l&#8217;email, pour&nbsp;lequel:</p> -<ul> -<li>Les méta-données seraient chiffrées — Il n&#8217;est pas possible de savoir qui - communique avec qui, et&nbsp;quand;</li> -<li>Le chiffrement serait fort (et protégé d&#8217;une phrase de passe&nbsp;?);</li> -<li>La fuite d&#8217;une clé de chiffrement utilisée dans un échange ne permette pas de - déchiffrer l&#8217;ensemble des échanges (forward&nbsp;secrecy);</li> -<li>Il ne soit pas possible de réutiliser les données comme preuve pour - incriminer l&#8217;emmeteur du message&nbsp;(deniability);</li> -</ul> -<p>Avec au moins ces besoins en tête, il semble qu&#8217;une revue de l&#8217;ensemble des projets existants pointe du doigt vers <a href="https://github.com/agl/pond">pond</a>, ou vers <a href="https://www.whispersystems.org">Signal</a>.</p> -<p>Malheureusement, Pond est le projet d&#8217;une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en&nbsp;question.</p>Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I -want to share with the crypto community to actually see if any solution -exists to solve this particular&nbsp;problem.</em></p> -<p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in -web-based cryptographic applications is the fact that there is no way …</p><p><em>I&#8217;m not a crypto expert, nor pretend to be one. These are thoughts I -want to share with the crypto community to actually see if any solution -exists to solve this particular&nbsp;problem.</em></p> -<p>One <a href="http://www.tonyarcieri.com/whats-wrong-with-webcrypto">often pointed</a> flaw in -web-based cryptographic applications is the fact that there is no way to -trust online software distributions. Put differently, you don&#8217;t actually -trust the software authors but are rather trusting the software -distributors and certificate authorities&nbsp;(CAs).</p> -<p>I&#8217;ve been talking with a few folks in the past months about that and -they suggested me to publish something to discuss the matter. So here I&nbsp;come!</p> -<h2 id="the-problem-attack-vectors">The problem (Attack&nbsp;vectors)</h2> -<p>Let&#8217;s try to describe a few potential&nbsp;attacks:</p> -<p><em>Application Authors</em> just released a new version of their open source -web crypto messaging application. An <em>Indie Hoster</em> installs it on their -servers so a wide audience can actually use&nbsp;it.</p> -<p>Someone alters the files on <em>Indie Hoster</em> servers, effectively -replacing them with other <em>altered files</em> with less security properties -/ a backdoor. This someone could either be an <em>Evil Attacker</em> which -found its way trough, the <em>Indie Hoster</em> or a <span class="caps">CDN</span> which delivers the&nbsp;files,</p> -<p>Trusted <em>Certificate Authorities</em> (&#8220;governments&#8221; or &#8220;hacking team&#8221;) can -also trick the User Agents (i.e. Firefox) into thinking they&#8217;re talking -to <em>Indie Hoster</em> even though they&#8217;re actually talking to a different&nbsp;server.</p> -<p><strong>Altered files</strong> are then being served to the User Agents, and <em>Evil -Attacker</em> now has a way to actually attack the end&nbsp;users.</p> -<h2 id="problem-mitigation">Problem&nbsp;Mitigation</h2> -<p>Part of the problem is solved by the recently introduced <a href="https://w3c.github.io/webappsec/specs/subresourceintegrity/">Sub Resource -Integrity</a> -(<span class="caps">SRI</span>). To quote them: &#8220;[it] defines a mechanism by which user agents -may verify that a fetched resource has been delivered without unexpected&nbsp;manipulation.&#8221;.</p> -<p><span class="caps">SRI</span> is a good start, but isn&#8217;t enough: it ensures the assets (JavaScript -files, mainly) loaded from a specific <span class="caps">HTML</span> page are the ones the author -of the <span class="caps">HTML</span> page intends. However, <span class="caps">SRI</span> doesn&#8217;t allow the User Agent to -ensure the <span class="caps">HTML</span> page is the one he&nbsp;wants.</p> -<p>In other words, we miss a way to create trust between <em>Application -Authors</em> and <em>User Agents</em>. The User-Agent currently has to trust the -<em>Certificate Authorities</em> and the delivery (<em>Indie Hoster</em>).</p> -<p>For desktop software distribution: <em>Crypto Experts</em> audit the software, -sign it somehow and then this signature can be checked locally during -installation or runtime. It&#8217;s not automated, but at least it&#8217;s&nbsp;possible.</p> -<p>For web applications, we don&#8217;t have such a mechanism, but it should be -possible. Consider the&nbsp;following:</p> -<ul> -<li><em>App Authors</em> publish a new version of their software; They provide - a hash of each of their distributed files (including the <span class="caps">HTML</span>&nbsp;files);</li> -<li><em>Crypto Experts</em> audit these files and sign the hashes&nbsp;somehow;</li> -<li><em>User Agents</em> can chose to trust some specific <em>Crypto Experts</em>;</li> -<li>When a <em>User Agent</em> downloads files, it checks if they&#8217;re signed by - a trusted&nbsp;party.</li> -</ul> -<h2 id="chosing-who-you-trust">Chosing who you&nbsp;trust</h2> -<p>In terms of user experience, handling certificates is hard, and that&#8217;s -where the community matters. Distributions such as -<a href="https://tails.boom.org">Tails</a> could chose who they trust to verify the -files, and issue warnings / refuse to run the application in case files -aren&#8217;t&nbsp;verified.</p> -<p>But, as highligted earlier, CAs are hard to trust. A new instance of the -same <span class="caps">CA</span> system wouldn&#8217;t make that much differences, expect the fact that -distributions could ship with a set of trusted authorities (for which -revocation would still need to be taken care&nbsp;of).</p> -<blockquote> -<p>[&#8230;] users are vulnerable to MitM attacks by the authority, which -can vouch for, or be coerced to vouch for, false keys. This weakness -has been highlighted by recent <span class="caps">CA</span> scandals. Both schemes can also be -attacked if the authority does not verify keys before vouching for&nbsp;them.</p> -<p>&#8212; <a href="http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf">SoK : Secure -Messaging</a>;</p> -</blockquote> -<p>It seems that some other systems could allow for something more&nbsp;reliable:</p> -<blockquote> -<p>Melara et al proposed <span class="caps">CONIKS</span>, using a series of chained commitments to -Merkle prefix trees to build a key directory [&#8230;] for which -individual users can efficiently verify the consistency of their own -entry in the directory without relying on a third&nbsp;party.</p> -<p>This “self- auditing log” approach makes the system partially have no -auditing required (as general auditing of non-equivocation is still -required) and also enables the system to be privacy preserving as the -entries in the directory need not be made public. This comes at a mild -bandwidth cost not reflected in our table, estimated to be about 10 -kilobytes per client per day for&nbsp;self-auditing.</p> -<p>&#8212; <a href="http://cacr.uwaterloo.ca/techreports/2015/cacr2015-02.pdf">SoK : Secure -Messaging</a>;</p> -</blockquote> -<p>Now, I honestly have no idea if this thing solves the whole problem, and -I&#8217;m pretty sure this design has many security problems attached to&nbsp;it.</p> -<p>However, that&#8217;s a problem I would really like to see solved one day, so -here the start of the discussion, don&#8217;t hesitate to <a href="/pages/about.html">get in -touch</a>!</p> -<h2 id="addendum">Addendum</h2> -<p>It seems possible to increase the level a user has in a Web Application -by adding indicators in the User-Agent. For instance, when using an -application that&#8217;s actually signed by someone considered trustful by the -User-Agent (or the distributor of the User-Agent), a little green icon -could be presented to the User, so they know that they can be confident -about&nbsp;this.</p> -<p>A bit like User-Agents do for <span class="caps">SSL</span>, but for the actual signature of the -files being&nbsp;viewed.</p>Service de nuages : Pourquoi avons-nous fait Cliquet ?2015-07-14T00:00:00+02:002015-07-14T00:00:00+02:00tag:blog.notmyidea.org,2015-07-14:/pourquoi-cliquet<p class="first last">Basé sur Pyramid, Cliquet est un projet qui permet de se concentrer sur l&#8217;essentiel -lors de la conception&nbsp;d&#8217;APIs.</p> -<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> -<p><strong>tldr; Cliquet est un toolkit Python pour construire des APIs, qui implémente -les bonnes pratiques en terme de mise en production et de protocole <span class="caps">HTTP</span>.</strong></p> -<div class="section" id="les-origines"> -<h2>Les&nbsp;origines</h2> -<p>L&#8217;objectif pour le premier trimestre 2015 était de construire un service de -stockage et de <a class="reference external" href="https://blog.notmyidea.org/service-de-nuages-fr.html">synchronisation de listes de lecture</a>.</p> -<p>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&nbsp;déployés.</p> -<p>De même, nous voulions tirer parti du protocole de <em>Firefox Sync</em>, robuste et éprouvé, -pour la synchronisation des données&nbsp;«offline».</p> -<p>Plutôt qu&#8217;écrire un <a class="reference external" href="http://blog.octo.com/en/design-a-rest-api/">énième</a> -<a class="reference external" href="http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api">article</a> de blog, -nous avons préféré les rassembler dans ce qu&#8217;on a appellé «un&nbsp;protocole».</p> -<p>Comme pour l&#8217;architecture envisagée nous avions deux projets à construire, qui -devaient obéir globalement à ces mêmes règles, nous avons décidé de mettre en -commun l&#8217;implémentation de ce protocole et de ces bonnes pratiques dans un&nbsp;«toolkit».</p> -<p><em>Cliquet</em> est&nbsp;né.</p> -<img alt="Cliquet logo" class="align-center" src="https://blog.notmyidea.org/images/cliquet/cliquet-logo.png" /> -<div class="section" id="les-intentions"> -<h3>Les&nbsp;intentions</h3> -<blockquote class="epigraph"> -Quelle structure <span class="caps">JSON</span> pour mon <span class="caps">API</span> ? Quelle syntaxe pour filtrer la liste -via la querystring ? Comment gérer les écritures concurrentes ? -Et synchroniser les données dans mon application cliente ?</blockquote> -<p>Désormais, quand un projet souhaite bénéficier d&#8217;une <span class="caps">API</span> <span class="caps">REST</span> pour stocker et consommer -des données, il est possible d&#8217;utiliser le <strong>protocole <span class="caps">HTTP</span></strong> proposé -et de se concentrer sur l&#8217;essentiel. Cela vaut aussi pour les clients, où -la majorité du code d&#8217;interaction avec le serveur est&nbsp;réutilisable.</p> -<blockquote class="epigraph"> -Comment pouvons-nous vérifier que le service est opérationnel ? Quels indicateurs StatsD ? -Est-ce que Sentry est bien configuré ? Comment déployer une nouvelle version -sans casser les applications clientes ?</blockquote> -<p>Comme <em>Cliquet</em> fournit tout ce qui est nécessaire pour être conforme avec les -exigences de la <strong>mise en production</strong>, le passage du prototype au service opérationnel -est très rapide ! De base le service répondra aux attentes en terme supervision, configuration, -déploiement et dépréciation de version. Et si celles-ci évoluent, il suffira -de faire évoluer le&nbsp;toolkit.</p> -<blockquote class="epigraph"> -Quel backend de stockage pour des documents <span class="caps">JSON</span> ? Comment faire si l&#8217;équipe -de production impose PostgreSQL ? Et si on voulait passer à Redis ou en -mémoire pour lancer les tests ?</blockquote> -<p>En terme d&#8217;implémentation, nous avons choisi de <strong>fournir des abstractions</strong>. -En effet, nous avions deux services dont le coeur consistait -à exposer un <em><span class="caps">CRUD</span></em> en <em><span class="caps">REST</span></em>, persistant des données <span class="caps">JSON</span> dans un backend. -Comme <em>Pyramid</em> et <em>Cornice</em> ne fournissent rien de tout prêt pour ça, -nous avons voulu introduire des classes de bases pour abstraire les notions -de resource <span class="caps">REST</span> et de backend de&nbsp;stockage.</p> -<p>Dans le but de tout rendre optionnel et «pluggable», <strong>tout est configurable</strong> -depuis le fichier <tt class="docutils literal">.ini</tt> de l&#8217;application. Ainsi tous les projets qui utilisent -le toolkit se déploieront de la même manière : seuls quelques éléments de configuration -les&nbsp;distingueront.</p> -<img alt="Une réunion à Paris..." class="align-center" src="https://blog.notmyidea.org/images/cliquet/cliquet-notes-whiteboard.jpg" /> -</div> -</div> -<div class="section" id="le-protocole"> -<h2>Le&nbsp;protocole</h2> -<blockquote class="epigraph"> -Est-ce suffisant de parler d&#8217;«<span class="caps">API</span> <span class="caps">REST</span>» ? Est-ce bien nécessaire de -relire la spec <span class="caps">HTTP</span> à chaque fois ? Pourquoi réinventer un protocole complet -à chaque fois ?</blockquote> -<p>Quand nous développons un (micro)service Web, nous dépensons généralement beaucoup -trop d&#8217;énergie à (re)faire des choix&nbsp;(arbitraires).</p> -<p>Nul besoin de lister ici tout ce qui concerne la dimension -de la spécification <span class="caps">HTTP</span> pure, qui nous impose le format des headers, -le support de <span class="caps">CORS</span>, la négocation de contenus (types mime), la différence entre -authentification et autorisation, la cohérence des code&nbsp;status&#8230;</p> -<p>Les choix principaux du protocole concernent surtout&nbsp;:</p> -<ul class="simple"> -<li><strong>Les resources <span class="caps">REST</span></strong> : Les deux URLs d&#8217;une resource (pour la collection -et les enregistrements) acceptent des verbes et des headers&nbsp;précis.</li> -<li><strong>Les formats</strong> : le format et la structure <span class="caps">JSON</span> des réponses est imposé, ainsi -que la pagination des listes ou la syntaxe pour filtrer/trier les resources via la <a class="reference external" href="https://en.wikipedia.org/wiki/Query_string">querystring</a>.</li> -<li><strong>Les timestamps</strong> : un numéro de révision qui s&#8217;incrémente à chaque opération -d&#8217;écriture sur une collection&nbsp;d&#8217;enregistrements.</li> -<li><strong>La synchronisation</strong> : une série de leviers pour récupérer et renvoyer des -changements sur les données, sans perte ni collision, en utilisant les&nbsp;timestamps.</li> -<li><strong>Les permissions</strong> : les droits d&#8217;un utilisateur sur une collection ou un enregistrement -(<em>encore frais et sur le point d&#8217;être documenté</em>) <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a>.</li> -<li><strong>Opérations par lot</strong>: une <span class="caps">URL</span> qui permet d&#8217;envoyer une série de requêtes -décrites en <span class="caps">JSON</span> et d&#8217;obtenir les réponses&nbsp;respectives.</li> -</ul> -<p>Dans la dimension opérationnelle du protocole, on trouve&nbsp;:</p> -<ul class="simple"> -<li><strong>La gestion de version</strong> : cohabitation de plusieurs versions en production, -avec alertes dans les entêtes pour la fin de vie des anciennes&nbsp;versions.</li> -<li><strong>Le report des requêtes</strong> : entêtes interprétées par les clients, activées en cas de -maintenance ou de surchage, pour ménager le&nbsp;serveur.</li> -<li><strong>Le canal d&#8217;erreurs</strong> : toutes les erreurs renvoyées par le serveur ont le même -format <span class="caps">JSON</span> et ont un numéro&nbsp;précis.</li> -<li><strong>Les utilitaires</strong> : URLs diverses pour répondre aux besoins exprimés par -l&#8217;équipe d&#8217;administrateurs (monitoring, metadonnées, paramètres&nbsp;publiques).</li> -</ul> -<p>Ce protocole est une compilation des bonnes pratiques pour les APIs <span class="caps">HTTP</span> (<em>c&#8217;est notre métier !</em>), -des conseils des administrateurs système dont c&#8217;est le métier de mettre à disposition des services -pour des millions d&#8217;utilisateurs et des retours d&#8217;expérience de l&#8217;équipe -de <em>Firefox Sync</em> pour la gestion de la concurrence et de&nbsp;l&#8217;«offline-first».</p> -<p>Il est <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/api/index.html">documenté en détail</a>.</p> -<p>Dans un monde idéal, ce protocole serait versionné, et formalisé dans une <span class="caps">RFC</span>. -En rêve, il existerait même plusieurs implémentations avec des technologies différentes -(Python, Go, Node, etc.). <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a></p> -<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>Voir notre <a class="reference external" href="https://blog.notmyidea.org/service-de-nuages-la-gestion-des-permissions-fr.html">article dédié sur les permissions</a></td></tr> -</tbody> -</table> -<table class="docutils footnote" frame="void" id="footnote-2" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td>Rappel: nous sommes une toute petite équipe !</td></tr> -</tbody> -</table> -</div> -<div class="section" id="le-toolkit"> -<h2>Le&nbsp;toolkit</h2> -<div class="section" id="choix-techniques"> -<h3>Choix&nbsp;techniques</h3> -<p><em>Cliquet</em> implémente le protocole en Python (<em>2.7, 3.4+, pypy</em>), avec <a class="reference external" href="http://trypyramid.com/">Pyramid</a> <a class="footnote-reference" href="#footnote-3" id="footnote-reference-3">[3]</a>.</p> -<p><strong>Pyramid</strong> est un framework Web qui va prendre en charge tout la partie <span class="caps">HTTP</span>, -et qui s&#8217;avère pertinent aussi bien pour des petits projets que des plus&nbsp;ambitieux.</p> -<p><strong>Cornice</strong> est une extension de <em>Pyramid</em>, écrite en partie par Alexis et Tarek, -qui permet d&#8217;éviter d&#8217;écrire tout le code <em>boilerplate</em> quand on construit une -<span class="caps">API</span> <span class="caps">REST</span> avec&nbsp;Pyramid.</p> -<p>Avec <em>Cornice</em>, on évite de réécrire à chaque fois le code qui va -cabler les verbes <span class="caps">HTTP</span> aux méthodes, valider les entêtes, choisir le sérialiseur -en fonction des entêtes de négociation de contenus, renvoyer les codes <span class="caps">HTTP</span> -rigoureux, gérer les entêtes <span class="caps">CORS</span>, fournir la validation <span class="caps">JSON</span> à partir de&nbsp;schémas&#8230;</p> -<p><strong>Cliquet</strong> utilise les deux précédents pour implémenter le protocole et fournir -des abstractions, mais on a toujours <em>Pyramid</em> et <em>Cornice</em> sous la main pour -aller au delà de ce qui est proposé&nbsp;!</p> -<table class="docutils footnote" frame="void" id="footnote-3" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-3">[3]</a></td><td>Au tout début nous avons commencé une implémentation avec <em>Python-Eve</em> -(Flask), mais n&#8217;étions pas satisfaits de l&#8217;approche pour la configuration -de l&#8217;<span class="caps">API</span>. En particulier du côté magique.</td></tr> -</tbody> -</table> -</div> -<div class="section" id="concepts"> -<h3>Concepts</h3> -<p>Bien évidemment, les concepts du toolkit reflètent ceux du protocole mais il y -a des éléments&nbsp;supplémentaires:</p> -<ul class="simple"> -<li><strong>Les backends</strong> : abstractions pour le stockage, le cache et les permissions -(<em>ex. PostgreSQL, Redis, en-mémoire, &#8230;</em>)</li> -<li><strong>La supervision</strong> : logging <span class="caps">JSON</span> et indicateurs temps-réel (<em>StatsD</em>) pour suivre les -performances et la santé du&nbsp;service.</li> -<li><strong>La configuration</strong> : chargement de la configuration depuis les variables -d&#8217;environnement et le fichier <tt class="docutils literal">.ini</tt></li> -<li><strong>La flexibilité</strong> : dés/activation ou substitution de la majorité des composants -depuis la&nbsp;configuration.</li> -<li><strong>Le profiling</strong> : utilitaires de développement pour trouver les <a class="reference external" href="https://fr.wiktionary.org/wiki/goulet_d%E2%80%99%C3%A9tranglement">goulets -d&#8217;étranglement</a>.</li> -</ul> -<img alt="Cliquet concepts" class="align-center" src="https://blog.notmyidea.org/images/cliquet/cliquet-concepts.png" /> -<p>Proportionnellement, l&#8217;implémentation du protocole pour les resources <span class="caps">REST</span> est -la plus volumineuse dans le code source de <em>Cliquet</em>. -Cependant, comme nous l&#8217;avons décrit plus haut, <em>Cliquet</em> fournit tout un -ensemble d&#8217;outillage et de bonnes pratiques, et reste -donc tout à fait pertinent pour n&#8217;importe quel type d&#8217;<span class="caps">API</span>, même sans -manipulation de données&nbsp;!</p> -<p>L&#8217;objectif de la boîte à outils est de faire en sorte qu&#8217;un développeur puisse constuire -une application simplement, en étant sûr qu&#8217;elle réponde aux exigeances de la -mise en production, tout en ayant la possibilité de remplacer certaines parties -au fur et à mesure que ses besoins se&nbsp;précisent.</p> -<p>Par exemple, la persistence fournie par défault est <em>schemaless</em> (e.g <em><span class="caps">JSONB</span></em>), -mais rien n&#8217;empêcherait d&#8217;implémenter le stockage dans un modèle&nbsp;relationnel.</p> -<p>Comme les composants peuvent être remplacés depuis la configuration, il est -tout à fait possible d&#8217;étendre <em>Cliquet</em> avec des notions métiers ou des -technologies exotiques ! Nous avons posé quelques idées dans <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/ecosystem.html">la documentation -de l&#8217;éco-système</a>.</p> -<p>Dans les prochaines semaines, nous allons introduire la notion d&#8217;«évènements» (ou signaux), -qui permettraient aux extensions de s&#8217;interfacer beaucoup plus&nbsp;proprement.</p> -<p>Nous attachons beaucoup d&#8217;importance à la clareté du code, la pertinence des -<em>patterns</em>, des tests et de la documentation. Si vous avez des commentaires, -des critiques ou des interrogations, n&#8217;hésitez pas à <a class="reference external" href="https://github.com/mozilla-services/cliquet/issues">nous en faire part</a>&nbsp;!</p> -</div> -</div> -<div class="section" id="cliquet-a-l-action"> -<h2>Cliquet, à&nbsp;l&#8217;action.</h2> -<p>Nous avons écrit un <a class="reference external" href="http://cliquet.readthedocs.org/en/latest/quickstart.html">guide de démarrage</a>, -qui n&#8217;exige pas de connaître <em>Pyramid</em>.</p> -<p>Pour illustrer la simplicité et les concepts, voici quelques extraits&nbsp;!</p> -<div class="section" id="etape-1"> -<h3>Étape&nbsp;1</h3> -<p>Activer <em>Cliquet</em>:</p> -<div class="highlight"><pre><span></span><span class="hll"><span class="kn">import</span> <span class="nn">cliquet</span> -</span><span class="kn">from</span> <span class="nn">pyramid.config</span> <span class="kn">import</span> <span class="n">Configurator</span> - -<span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">global_config</span><span class="p">,</span> <span class="o">**</span><span class="n">settings</span><span class="p">):</span> - <span class="n">config</span> <span class="o">=</span> <span class="n">Configurator</span><span class="p">(</span><span class="n">settings</span><span class="o">=</span><span class="n">settings</span><span class="p">)</span> - -<span class="hll"> <span class="n">cliquet</span><span class="o">.</span><span class="n">initialize</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="s1">&#39;1.0&#39;</span><span class="p">)</span> -</span> <span class="k">return</span> <span class="n">config</span><span class="o">.</span><span class="n">make_wsgi_app</span><span class="p">()</span> -</pre></div> -<p>À partir de là, la plupart des outils de <em>Cliquet</em> sont activés et&nbsp;accessibles.</p> -<p>Par exemple, les URLs <em>hello</em> (<tt class="docutils literal">/v1/</tt>) ou <em>supervision</em> (<tt class="docutils literal">/v1/__heartbeat__</tt>). -Mais aussi les backends de stockage, de cache, etc. -qu&#8217;il est possible d&#8217;utiliser dans des vues classiques <em>Pyramid</em> ou <em>Cornice</em>.</p> -</div> -<div class="section" id="etape-2"> -<h3>Étape&nbsp;2</h3> -<p>Ajouter des&nbsp;vues:</p> -<div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">global_config</span><span class="p">,</span> <span class="o">**</span><span class="n">settings</span><span class="p">):</span> - <span class="n">config</span> <span class="o">=</span> <span class="n">Configurator</span><span class="p">(</span><span class="n">settings</span><span class="o">=</span><span class="n">settings</span><span class="p">)</span> - - <span class="n">cliquet</span><span class="o">.</span><span class="n">initialize</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="s1">&#39;1.0&#39;</span><span class="p">)</span> -<span class="hll"> <span class="n">config</span><span class="o">.</span><span class="n">scan</span><span class="p">(</span><span class="s2">&quot;myproject.views&quot;</span><span class="p">)</span> -</span> <span class="k">return</span> <span class="n">config</span><span class="o">.</span><span class="n">make_wsgi_app</span><span class="p">()</span> -</pre></div> -<p>Pour définir des resources <span class="caps">CRUD</span>, il faut commencer par définir un schéma, -avec <em>Colander</em>, et ensuite déclarer une&nbsp;resource:</p> -<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">cliquet</span> <span class="kn">import</span> <span class="n">resource</span><span class="p">,</span> <span class="n">schema</span> - -<span class="k">class</span> <span class="nc">BookmarkSchema</span><span class="p">(</span><span class="n">schema</span><span class="o">.</span><span class="n">ResourceSchema</span><span class="p">):</span> - <span class="n">url</span> <span class="o">=</span> <span class="n">schema</span><span class="o">.</span><span class="n">URL</span><span class="p">()</span> - -<span class="hll"><span class="nd">@resource</span><span class="o">.</span><span class="n">register</span><span class="p">()</span> -</span><span class="hll"><span class="k">class</span> <span class="nc">Bookmark</span><span class="p">(</span><span class="n">resource</span><span class="o">.</span><span class="n">BaseResource</span><span class="p">):</span> -</span><span class="hll"> <span class="n">mapping</span> <span class="o">=</span> <span class="n">BookmarkSchema</span><span class="p">()</span> -</span></pre></div> -<p>Désormais, la resource <span class="caps">CRUD</span> est disponible sur <tt class="docutils literal">/v1/bookmarks</tt>, avec toutes -les fonctionnalités de synchronisation, filtrage, tri, pagination, timestamp, etc. -De base les enregistrements sont privés, par&nbsp;utilisateur.</p> -<div class="highlight"><pre><span></span><span class="err">$</span><span class="w"> </span><span class="err">h</span><span class="kc">tt</span><span class="err">p</span><span class="w"> </span><span class="err">GET</span><span class="w"> </span><span class="s2">&quot;http://localhost:8000/v1/bookmarks&quot;</span> -<span class="err">HTTP/</span><span class="mf">1.1</span><span class="w"> </span><span class="mi">200</span><span class="w"> </span><span class="err">OK</span> -<span class="err">...</span> -<span class="p">{</span> -<span class="w"> </span><span class="nt">&quot;data&quot;</span><span class="p">:</span><span class="w"> </span><span class="p">[</span> -<span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="nt">&quot;url&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;http://cliquet.readthedocs.org&quot;</span><span class="p">,</span> -<span class="w"> </span><span class="nt">&quot;id&quot;</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;cc103eb5-0c80-40ec-b6f5-dad12e7d975e&quot;</span><span class="p">,</span> -<span class="w"> </span><span class="nt">&quot;last_modified&quot;</span><span class="p">:</span><span class="w"> </span><span class="mi">1437034418940</span><span class="p">,</span> -<span class="w"> </span><span class="p">}</span> -<span class="w"> </span><span class="p">]</span> -<span class="p">}</span> -</pre></div> -</div> -<div class="section" id="etape-3"> -<h3>Étape&nbsp;3</h3> -<p>Évidemment, il est possible choisir les <span class="caps">URLS</span>, les verbes <span class="caps">HTTP</span> supportés, de modifier -des champs avant l&#8217;enregistrement,&nbsp;etc.</p> -<div class="highlight"><pre><span></span><span class="hll"><span class="nd">@resource</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">collection_path</span><span class="o">=</span><span class="s1">&#39;/user/bookmarks&#39;</span><span class="p">,</span> -</span><span class="hll"> <span class="n">record_path</span><span class="o">=</span><span class="s1">&#39;/user/bookmarks/{{id}}&#39;</span><span class="p">,</span> -</span><span class="hll"> <span class="n">collection_methods</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;GET&#39;</span><span class="p">,))</span> -</span><span class="k">class</span> <span class="nc">Bookmark</span><span class="p">(</span><span class="n">resource</span><span class="o">.</span><span class="n">BaseResource</span><span class="p">):</span> - <span class="n">mapping</span> <span class="o">=</span> <span class="n">BookmarkSchema</span><span class="p">()</span> - -<span class="hll"> <span class="k">def</span> <span class="nf">process_record</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">new</span><span class="p">,</span> <span class="n">old</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> -</span><span class="hll"> <span class="k">if</span> <span class="n">old</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">new</span><span class="p">[</span><span class="s1">&#39;device&#39;</span><span class="p">]</span> <span class="o">!=</span> <span class="n">old</span><span class="p">[</span><span class="s1">&#39;device&#39;</span><span class="p">]:</span> -</span><span class="hll"> <span class="n">device</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">headers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s1">&#39;User-Agent&#39;</span><span class="p">)</span> -</span><span class="hll"> <span class="n">new</span><span class="p">[</span><span class="s1">&#39;device&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="n">device</span> -</span><span class="hll"> <span class="k">return</span> <span class="n">new</span> -</span></pre></div> -<p><a class="reference external" href="http://cliquet.readthedocs.org/en/latest/reference/resource.html">Plus d&#8217;infos dans la documentation dédiée</a>&nbsp;!</p> -<div class="admonition note"> -<p class="first admonition-title">Note</p> -<p class="last">Il est possible de définir des resources sans validation de schema. -<a class="reference external" href="https://github.com/mozilla-services/kinto/blob/master/kinto/views/records.py">Voir le code source de Kinto</a>.</p> -</div> -</div> -<div class="section" id="etape-4-optionelle"> -<h3>Étape 4&nbsp;(optionelle)</h3> -<p>Utiliser les abstractions de <em>Cliquet</em> dans une vue <em>Cornice</em>.</p> -<p>Par exemple, une vue qui utilise le backend de&nbsp;stockage:</p> -<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">cliquet</span> <span class="kn">import</span> <span class="n">Service</span> - -<span class="n">score</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;score&quot;</span><span class="p">,</span> - <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/score/</span><span class="si">{game}</span><span class="s1">&#39;</span><span class="p">,</span> - <span class="n">description</span><span class="o">=</span><span class="s2">&quot;Store game score&quot;</span><span class="p">)</span> - -<span class="nd">@score</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">schema</span><span class="o">=</span><span class="n">ScoreSchema</span><span class="p">)</span> -<span class="k">def</span> <span class="nf">post_score</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="n">collection_id</span> <span class="o">=</span> <span class="s1">&#39;scores-&#39;</span> <span class="o">+</span> <span class="n">request</span><span class="o">.</span><span class="n">match_dict</span><span class="p">[</span><span class="s1">&#39;game&#39;</span><span class="p">]</span> - <span class="n">user_id</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">authenticated_userid</span> - <span class="n">value</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">validated</span> <span class="c1"># c.f. Cornice.</span> - -<span class="hll"> <span class="n">storage</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">registry</span><span class="o">.</span><span class="n">storage</span> -</span><span class="hll"> <span class="n">record</span> <span class="o">=</span> <span class="n">storage</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="n">collection_id</span><span class="p">,</span> <span class="n">user_id</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> -</span> <span class="k">return</span> <span class="n">record</span> -</pre></div> -</div> -</div> -<div class="section" id="vos-retours"> -<h2>Vos&nbsp;retours</h2> -<p>N&#8217;hésitez pas à nous faire part de vos retours ! Cela vous a donné envie -d&#8217;essayer ? Vous connaissez un outil similaire ? -Y-a-t-il des points qui ne sont pas clairs ? Manque de cas d&#8217;utilisation concrets ? -Certains aspects mal pensés ? Trop contraignants ? Trop de magie ? Overkill&nbsp;?</p> -<p>Nous prenons&nbsp;tout.</p> -<div class="section" id="points-faibles"> -<h3>Points&nbsp;faibles</h3> -<p>Nous sommes très fiers de ce que nous avons construit, en relativement peu -de temps. Et comme nous l&#8217;exposions dans l&#8217;article précédent (plus accessible), il y a du potentiel&nbsp;!</p> -<p>Cependant, nous sommes conscients d&#8217;un certain nombre de points -qui peuvent être vus comme des&nbsp;faiblesses.</p> -<ul class="simple"> -<li><strong>La documentation d&#8217;<span class="caps">API</span></strong> : actuellement, nous n&#8217;avons pas de solution pour qu&#8217;un -projet qui utilise <em>Cliquet</em> puisse intégrer facilement toute -<a class="reference external" href="http://cliquet.readthedocs.org/en/latest/api/index.html">la documentation de l&#8217;<span class="caps">API</span></a>&nbsp;obtenue.</li> -<li><strong>La documentation</strong> : il est très difficile d&#8217;organiser la documentation, surtout -quand le public visé est aussi bien débutant qu&#8217;expérimenté. Nous sommes probablement -victimes du «<a class="reference external" href="https://en.wikipedia.org/wiki/Curse_of_knowledge">curse of knowledge</a>».</li> -<li><strong>Le protocole</strong> : on sent bien qu&#8217;on va devoir versionner le protocole. Au -moins pour le désolidariser des versions de <em>Cliquet</em>, si on veut aller au -bout de la philosophie et de&nbsp;l&#8217;éco-système.</li> -<li><strong>Le conservatisme</strong> : Nous aimons la stabilité et la robustesse. Mais surtout -nous ne sommes pas tout seuls et devons nous plier aux contraintes de la mise -en production ! Cependant, nous avons très envie de faire de l&#8217;async avec Python 3&nbsp;!</li> -<li><strong>Publication de versions</strong> : le revers de la médaille de la factorisation. Il -arrive qu&#8217;on préfère faire évoluer le toolkit (e.g. ajouter une option) pour -un point précis d&#8217;un projet. En conséquence, on doit souvent releaser les -projets en&nbsp;cascade.</li> -</ul> -</div> -<div class="section" id="quelques-questions-courantes"> -<h3>Quelques questions&nbsp;courantes</h3> -<blockquote> -Pourquoi Python ?</blockquote> -<p>On prend beaucoup de plaisir à écrire du Python, et le calendrier annoncé -initialement était très serré: pas question de tituber avec une technologie -mal maitrisée&nbsp;!</p> -<p>Et puis, après avoir passé près d&#8217;un an sur un projet Node.js, l&#8217;équipe avait -bien envie de refaire du&nbsp;Python.</p> -<blockquote> -Pourquoi pas Django ?</blockquote> -<p>On y a pensé, surtout parce qu&#8217;il y a plusieurs fans de <em>Django <span class="caps">REST</span> Framework</em> -dans&nbsp;l&#8217;équipe.</p> -<p>On l&#8217;a écarté principalement au profit de la légèreté et la modularité de -<em>Pyramid</em>.</p> -<blockquote> -Pourquoi pas avec un framework asynchrone en Python 3+ ?</blockquote> -<p>Pour l&#8217;instant nos administrateurs système nous imposent des déploiements en -Python 2.7, à notre grand désarroi&nbsp;/o\</p> -<p>Pour <em>Reading List</em>, nous <a class="reference external" href="https://github.com/mozilla-services/readinglist/blob/1.7.0/readinglist/__init__.py#L19-L26">avions activé</a> -<em>gevent</em>.</p> -<p>Puisque l&#8217;approche consiste à implémenter un protocole bien déterminé, nous n&#8217;excluons -pas un jour d&#8217;écrire un <em>Cliquet</em> en <em>aiohttp</em> ou <em>Go</em> si cela s&#8217;avèrerait&nbsp;pertinent.</p> -<blockquote> -Pourquoi pas <span class="caps">JSON</span>-<span class="caps">API</span> ?</blockquote> -<p>Comme nous l&#8217;expliquions au retour des APIdays, -<span class="caps">JSON</span>-<span class="caps">API</span> est une spécification qui rejoint plusieurs de nos&nbsp;intentions.</p> -<p>Quand nous avons commencé le protocole, nous ne connaissions pas <span class="caps">JSON</span>-<span class="caps">API</span>. -Pour l&#8217;instant, comme notre proposition est beaucoup plus minimaliste, le -rapprochement n&#8217;a <a class="reference external" href="https://github.com/mozilla-services/cliquet/issues/254">pas dépassé le stade de la discussion</a>.</p> -<blockquote> -Est-ce que Cliquet est un framework <span class="caps">REST</span> pour Pyramid ?</blockquote> -<p>Non.</p> -<p>Au delà des classes de resources <span class="caps">CRUD</span> de Cliquet, qui implémentent un -protocole bien précis, il faut utiliser Cornice ou Pyramid&nbsp;directement.</p> -<blockquote> -Est-ce que Cliquet est suffisamment générique pour des projets hors Mozilla ?</blockquote> -<p>Premièrement, nous faisons en sorte que tout soit contrôlable depuis la -configuration <tt class="docutils literal">.ini</tt> pour permettre la dés/activation ou substitution des&nbsp;composants.</p> -<p>Si le protocole <span class="caps">HTTP</span>/<span class="caps">JSON</span> des resources <span class="caps">CRUD</span> vous satisfait, -alors Cliquet est probablement le plus court chemin pour construire une -application qui tient la&nbsp;route.</p> -<p>Mais l&#8217;utilisation des resources <span class="caps">CRUD</span> est facultative, donc Cliquet reste pertinent -si les bonnes pratiques en terme de mise en production ou les abstractions fournies -vous paraissent valables&nbsp;!</p> -<p>Cliquet reste un moyen simple d&#8217;aller très vite pour mettre sur pied -une application&nbsp;Pyramid/Cornice.</p> -<blockquote> -Est-ce que les resources <span class="caps">JSON</span> supporte les modèles relationnels complexes ?</blockquote> -<p>La couche de persistence fournie est très simple, et devrait -répondre à la majorité des cas d&#8217;utilisation où les données n&#8217;ont pas de&nbsp;relations.</p> -<p>En revanche, il est tout à fait possible de bénéficier de tous les aspects -du protocole en utilisant une classe <tt class="docutils literal">Collection</tt> maison, qui se chargerait -elle de manipuler les&nbsp;relations.</p> -<p>Le besoin de relations pourrait être un bon prétexte pour implémenter le -protocole avec Django <span class="caps">REST</span> Framework&nbsp;:)</p> -<blockquote> -Est-il possible de faire ci ou ça avec Cliquet ?</blockquote> -<p>Nous aimerions collecter des besoins pour écrire un ensemble de «recettes/tutoriels». Mais -pour ne pas travailler dans le vide, nous aimerions <a class="reference external" href="https://github.com/mozilla-services/cliquet/issues">connaitre vos idées</a> ! -(<em>ex. brancher l&#8217;authentification Github, changer le format du logging <span class="caps">JSON</span>, stocker des -données cartographiques, &#8230;</em>)</p> -<blockquote> -Est-ce que Cliquet peut manipuler des fichiers ?</blockquote> -<p><a class="reference external" href="https://github.com/mozilla-services/cliquet/issues/236">Nous l&#8217;envisageons</a>, -mais pour l&#8217;instant nous attendons que le besoin survienne en interne pour se&nbsp;lancer.</p> -<p>Si c&#8217;est le cas, le protocole utilisé sera <a class="reference external" href="http://remotestorage.io/">Remote Storage</a>, -afin notamment de s&#8217;intégrer dans l&#8217;éco-système&nbsp;grandissant.</p> -<blockquote> -Est-ce que la fonctionnalité X va être implémentée ?</blockquote> -<p><em>Cliquet</em> est déjà bien garni. Plutôt qu&#8217;implémenter la fonctionnalité X, -il y a de grandes chances que nous agissions pour s&#8217;assurer que les abstractions -et les mécanismes d&#8217;extension fournis permettent de l&#8217;implémenter sous forme&nbsp;d&#8217;extension.</p> -</div> -</div> -Service de nuages : Perspectives pour l’été2015-07-07T00:00:00+02:002015-07-07T00:00:00+02:00tag:blog.notmyidea.org,2015-07-07:/service-de-nuages-perspectives-pour-lete-fr.html<p class="first last">Le travail en cours et les fonctionnalités à venir pour les prochains&nbsp;mois.</p> -<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> -<p>Mozilla a pour coutume d&#8217;organiser régulièrement des semaines de travail où tous les employés -sont réunis physiquement. Pour cette dernière édition, nous avons pu retrouver -nos collègues du monde entier à <a class="reference external" href="http://www.openstreetmap.org/node/268148288#map=4/50.12/-122.95">Whistler, en Colombie Britannique au Canada</a>&nbsp;!</p> -<img alt="«All Hands» talk about Lego, by &#64;davidcrob - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-talks.jpg" /> -<p>Ce fût l&#8217;occasion pour notre équipe de se retrouver, et surtout de partager notre -vision et nos idées dans le domaine du stockage, afin de collecter des cas d&#8217;utilisation pour -notre solution <a class="reference external" href="https://kinto.readthedocs.org">Kinto</a>.</p> -<p>Dans cet article, nous passons en revue les pistes que nous avons pour -les prochains&nbsp;mois.</p> -<div class="section" id="ateliers-et-promotion"> -<h2>Ateliers et&nbsp;promotion</h2> -<p>Nicolas a présenté <a class="reference external" href="https://github.com/mozilla-services/kinto.js">Kinto.js</a> dans un atelier dédié, avec comme support de -présentation le <a class="reference external" href="http://kintojs.readthedocs.org/en/latest/tutorial/">tutorial d&#8217;introduction</a>.</p> -<p>L&#8217;application résultante, pourtant toute simple, permet d&#8217;appréhender les -concepts de synchronisation de Kinto. Le tout sans installation prélable, -puisque Rémy a mis en place un <a class="reference external" href="https://kinto.dev.mozaws.net/v1/">serveur de dev effacé tous les jours</a>.</p> -<p>Nous avions mis un point d&#8217;honneur à faire du Vanilla.<span class="caps">JS</span>, déjà pour éviter les -combats de clochers autour des frameworks, mais aussi pour mettre en évidence qu&#8217;avec -<span class="caps">HTML5</span> et <span class="caps">ES6</span>, on n&#8217;était plus aussi démunis qu&#8217;il y a quelques&nbsp;années.</p> -<p>Ce petit atelier nous a permis de nous rendre compte qu&#8217;on avait encore de -grosses lacunes en terme de documentation, surtout en ce qui concerne -l&#8217;éco-système et la vision globale des projets (Kinto, Kinto.js, Cliquet, &#8230;). -Nous allons donc faire de notre mieux pour combler ce&nbsp;manque.</p> -<img alt="Kinto.js workshop - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-workshop.jpg" /> -</div> -<div class="section" id="mozilla-payments"> -<h2>Mozilla&nbsp;Payments</h2> -<p>Comme <a class="reference external" href="http://www.servicedenuages.fr/la-gestion-des-permissions">décrit précédemment</a>, nous avons mis en place un système de permissions pour répondre aux besoins de suivi des paiements et&nbsp;abonnements.</p> -<p>Pour ce projet, Kinto sera utilisé depuis une application Django, via un client&nbsp;Python.</p> -<p>Maintenant que les développements ont été livrés, il faut transformer l&#8217;essai, réussir l&#8217;intégration, l&#8217;hébergement et la montée en puissance. La solution doit être livrée à la fin de&nbsp;l&#8217;année.</p> -<div class="section" id="a-venir"> -<h3>À&nbsp;venir</h3> -<p>Nous aimerions en profiter pour implémenter une fonctionnalité qui nous tient à coeur : la construction de la liste des enregistrements accessibles en lecture sur une collection&nbsp;partagée.</p> -<img alt="Whistler Alta Lake - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-lake.jpg" /> -</div> -</div> -<div class="section" id="firefox-os-et-stockage"> -<h2>Firefox <span class="caps">OS</span> et&nbsp;stockage</h2> -<p>Nous avons eu beaucoup d&#8217;échanges avec l&#8217;équipe de Firefox <span class="caps">OS</span>, avec qui nous avions -déjà eu l&#8217;occasion de collaborer, pour le <a class="reference external" href="https://github.com/mozilla-services/msisdn-gateway">serveur d&#8217;identification BrowserID par <span class="caps">SMS</span></a> et pour <a class="reference external" href="https://github.com/mozilla-services/loop-server">Firefox Hello</a>.</p> -<div class="section" id="in-app-sync"> -<h3>In-App&nbsp;sync</h3> -<p>Kinto, la solution simple promue pour la synchronisation de données dans les applications -Firefox <span class="caps">OS</span> ? La classe ! C&#8217;est ce qu&#8217;on avait en tête depuis longtemps, déjà à -l&#8217;époque avec <a class="reference external" href="http://daybed.readthedocs.org/">Daybed</a>. Voici donc une belle opportunité à saisir&nbsp;!</p> -<p>Il va falloir expliciter les limitations et hypothèses simplificatrices de notre -solution, surtout en termes de gestion de la concurrence. Nous sommes persuadés -que ça colle avec la plupart des besoins, mais il ne faudrait pas décevoir&nbsp;:)</p> -<p>Le fait que <a class="reference external" href="https://github.com/daleharvey">Dale</a>, un des auteurs de <a class="reference external" href="http://pouchdb.com/">PouchDB</a> et <a class="reference external" href="https://github.com/michielbdejong">Michiel de Jong</a>, un des auteurs de <a class="reference external" href="http://remotestorage.io/">Remote Storage</a>, nous aient encouragés sur nos premiers pas nous a bien motivé&nbsp;!</p> -</div> -<div class="section" id="cut-the-rope"> -<h3>Cut the&nbsp;Rope</h3> -<p>Kinto devrait être mis à profit pour synchroniser les paramètres et les scores -du <a class="reference external" href="http://mozilla.cuttherope.net/">jeu</a>. Un premier exercice et une première vitrine sympas&nbsp;!</p> -</div> -<div class="section" id="syncto"> -<h3>« SyncTo&nbsp;»</h3> -<p><a class="reference external" href="https://docs.services.mozilla.com/storage/apis-1.5.html">Firefox Sync</a> est la solution qui permet de synchroniser les données de Firefox (favoris, extensions, historique, complétion des formulaires, mots de passe, &#8230;) entre plusieurs périphériques, de manière&nbsp;chiffrée.</p> -<p>L&#8217;implémentation du client en JavaScript est relativement complexe et date un peu maintenant. -Le code existant n&#8217;est pas vraiment portable dans <em>Firefox <span class="caps">OS</span></em> et les tentatives de réécriture -n&#8217;ont pas&nbsp;abouti.</p> -<p>Nous souhaitons implémenter un pont entre <em>Kinto</em> et <em>Firefox Sync</em>, de manière -à pouvoir utiliser le client <em>Kinto.js</em>, plus simple et plus moderne, pour récupérer -les contenus et les stocker dans IndexedDB. Le delta à implémenter côté serveur est faible car nous nous étions -inspirés du protocole déjà éprouvé de Sync. Côté client, il s&#8217;agira surtout de -câbler l&#8217;authentification BrowserId et la&nbsp;Crypto.</p> -<p>Alexis a sauté sur l&#8217;occasion pour commencer l&#8217;écriture d&#8217;<a class="reference external" href="https://github.com/mozilla-services/syncclient">un client python pour Firefox Sync</a>, qui servira de brique de base pour l&#8217;écriture du&nbsp;service.</p> -</div> -<div class="section" id="cloud-storage"> -<h3>Cloud&nbsp;Storage</h3> -<p>Eden Chuang et Sean Lee ont présenté les avancées sur l&#8217;intégration de services de stockages -distants (<em>DropBox, Baidu Yun</em>) dans <em>Firefox <span class="caps">OS</span></em>. Actuellement, leur preuve de -concept repose sur <a class="reference external" href="https://fr.wikipedia.org/wiki/Filesystem_in_Userspace"><span class="caps">FUSE</span></a>.</p> -<p>Nous avons évidemment en tête d&#8217;introduire la notion de fichiers attachés dans -<em>Kinto</em>, en implémentant la specification -<a class="reference external" href="https://tools.ietf.org/html/draft-dejong-remotestorage-05">*Remote Storage*</a>, -mais pour l&#8217;instant les cas d&#8217;utilisations ne se sont pas encore présentés&nbsp;officiellement.</p> -</div> -<div class="section" id="a-venir-1"> -<h3>À&nbsp;venir</h3> -<p>Nous serons probablement amenés à introduire la gestion de la concurrence dans -le client <span class="caps">JS</span>, en complément de ce qui a été fait sur le serveur, pour permettre -les écritures simultanées et synchronisation en tâche de&nbsp;fond.</p> -<p>Nous sommes par ailleurs perpétuellement preneurs de vos retours — et bien -entendu de vos contributions — tant sur le code <a class="reference external" href="https://github.com/mozilla-services/kinto/">serveur</a> -que <a class="reference external" href="https://github.com/mozilla-services/kinto.js/">client</a>&nbsp;!</p> -<img alt="Firefox OS Cloud Storage Presentation - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-cloud-storage.jpg" /> -</div> -</div> -<div class="section" id="contenus-applicatifs-de-firefox"> -<h2>Contenus applicatifs de&nbsp;Firefox</h2> -<p>Aujourd&#8217;hui Firefox a un cycle de release de six semaines. Un des objectifs -consiste à désolidariser certains contenus applicatifs de ces cycles -relativement longs (ex. <em>règles de securité, dictionnaires, traductions, &#8230;</em>) <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a>.</p> -<p>Il s&#8217;agit de données <span class="caps">JSON</span> et binaire qui doivent être versionnées et synchronisées par -les navigateurs (<em>lecture seule</em>).</p> -<p>Il y a plusieurs outils officiels qui existent pour gérer ça (<em>Balrog</em>, <em>Shavar</em>, &#8230;), -et pour l&#8217;instant, aucun choix n&#8217;a été fait. Mais lors des conversations avec -l&#8217;équipe en charge du projet, ce fût vraiment motivant de voir que même pour -ce genre de besoins internes, <em>Kinto</em> est tout aussi pertinent&nbsp;!</p> -<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>La bonne nouvelle c&#8217;est que toutes les fonctionnalités <em>third-party</em> qui ont -été intégrées récemment vont redevenir des <em>add-ons</em> \o/.</td></tr> -</tbody> -</table> -<img alt="Landscape - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-landscape.jpg" /> -</div> -<div class="section" id="awesome-bar"> -<h2>Awesome&nbsp;bar</h2> -<p>L&#8217;équipe <em>Firefox Labs</em>, le laboratoire qui élève des pandas roux en éprouvette, -serait vraiment intéressé par notre solution, notamment pour abreuver en données -un prototype pour améliorer <em>Awesome bar</em>, qui fusionnerait <span class="caps">URL</span>, historique et&nbsp;recherche.</p> -<p>Nous ne pouvons pas en dire beaucoup plus pour l&#8217;instant, mais les fonctionnalités -de collections d&#8217;enregistrements partagées entre utilisateurs de <em>Kinto</em> -correspondent parfaitement à ce qui est envisagé pour le futur du navigateur&nbsp;:)</p> -<div class="section" id="a-venir-2"> -<h3>À&nbsp;venir</h3> -<p>Nous serons donc probablement amenés, avant de la fin de l&#8217;année, à introduire des -fonctionnalités d&#8217;indexation et de recherche <em>full-text</em> (comprendre <em>ElasticSearch</em>). -Cela rejoint nos plans précédents, puisque c&#8217;est quelque chose que nous avions dans -<em>Daybed</em>, et qui figurait sur notre feuille de route&nbsp;!</p> -<img alt="Firefox Labs Meeting - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-labs.jpg" /> -</div> -</div> -<div class="section" id="browser-html"> -<h2>Browser.html</h2> -<p>L&#8217;équipe <em>Recherche</em> explore les notions de plateforme, et travaille notamment -sur l&#8217;implémentation d&#8217;un navigateur en <span class="caps">JS</span>/<span class="caps">HTML</span> avec <em>React</em>: -<a class="reference external" href="https://github.com/mozilla/browser.html">browser.html</a></p> -<p><em>Kinto</em> correspond parfaitement aux attentes -de l&#8217;équipe pour synchroniser les données associées à un&nbsp;utilisateur.</p> -<p>Il pourrait s&#8217;agir de données de navigation (comme Sync), mais aussi de collections -d&#8217;enregistrements diverses, comme par exemple les préférences du navigateur -ou un équivalent à <em>Alexa.com Top 500</em> pour fournir la complétion d&#8217;<span class="caps">URL</span> sans -interroger le moteur de&nbsp;recherche.</p> -<p>L&#8217;exercice pourrait être poussé jusqu&#8217;à la synchronisation d&#8217;états <em>React</em> -entre périphériques (par exemple pour les&nbsp;onglets).</p> -<div class="section" id="a-venir-3"> -<h3>À&nbsp;venir</h3> -<p>Si <em>browser.html</em> doit stocker des données de navigation, il faudra ajouter -des fonctionnalités de chiffrement sur le client <span class="caps">JS</span>. Ça tombe bien, c&#8217;est un -sujet passionant, et <a class="reference external" href="http://www.w3.org/TR/WebCryptoAPI/">il y a plusieurs standards</a>&nbsp;!</p> -<p>Pour éviter d&#8217;interroger le serveur à intervalle régulier afin de synchroniser les -changements, l&#8217;introduction des <a class="reference external" href="https://w3c.github.io/push-api/">*push notifications*</a> semble assez naturelle. -Il s&#8217;agirait alors de la dernière pierre qui manque à l&#8217;édifice pour obtenir -un «<em>Mobile/Web backend as a service</em>»&nbsp;complet.</p> -<img alt="Roadmap - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-roadmap.jpg" /> -</div> -</div> -<div class="section" id="conclusion"> -<h2>Conclusion</h2> -<p>Nous sommes dans une situation idéale, puisque ce que nous avions imaginé -sur <a class="reference external" href="https://github.com/mozilla-services/kinto/wiki/Roadmap">notre feuille de route</a> correspond à ce qui nous est demandé par les -différentes&nbsp;équipes.</p> -<p>L&#8217;enjeu consiste maintenant à se coordonner avec tout le monde, ne pas décevoir, -tenir la charge, continuer à améliorer et à faire la promotion du produit, se concentrer -sur les prochaines étapes et embarquer quelques contributeurs à nos cotés pour -construire une solution libre, générique, simple et auto-hébergeable pour le stockage -de données sur le Web&nbsp;:)</p> -<img alt="Friday Night Party - CC0" class="align-center" src="https://blog.notmyidea.org/images/whistler/whistler-top-roof.jpg" /> -</div> -Service de nuages : Achievement unlocked2015-06-01T00:00:00+02:002015-06-01T00:00:00+02:00tag:blog.notmyidea.org,2015-06-01:/service-de-nuages-achievement-unlocked-fr.html<p class="first last">Après près de 3 mois intensifs, nous venons de <em>tagguer</em> Cliquet 2.0 -et Kinto 1.0&nbsp;!</p> -<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> -<p>Aujourd&#8217;hui, c&#8217;est jour de fête : nous venons de publier Cliquet <strong>2.0</strong> -<a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a> et Kinto <strong>1.0</strong> <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a>.</p> -<blockquote class="epigraph"> -<p>L&#8217;aboutissement de 3 années de R&amp;D&nbsp;!</p> -<p class="attribution">&mdash;Rémy</p> -</blockquote> -<p><a class="reference external" href="https://kinto.readthedocs.org/en/latest/">Kinto</a> est un service pour -stocker, synchroniser et partager des données arbitraires, attachées à un -compte Firefox (mais le système d&#8217;authentification est <em>pluggable</em>).</p> -<p><a class="reference external" href="https://cliquet.readthedocs.org/en/latest/">Cliquet</a> est une boite à outils pour faciliter l&#8217;implémentation de -micro-services <span class="caps">HTTP</span> tels que les APIs <em><span class="caps">REST</span></em> ayant des besoins de&nbsp;synchronisation.</p> -<p>Vous pouvez lire plus à propos des raisons qui nous ont poussé à proposer cette nouvelle solution -et de notre ambition sur <a class="reference external" href="http://www.servicedenuages.fr/eco-systeme-et-stockage-generique.html">http://www.servicedenuages.fr/eco-systeme-et-stockage-generique.html</a></p> -<p>Nous sommes fiers du travail que nous avons pu réaliser durant ces derniers -mois sur ces deux projets. Bien que la plupart du travail que nous ayons -réalisé pour le serveur de liste de lecture (Reading List) ait pu être utilisé, -beaucoup de parties ont été repensées et nous avons introduit des -fonctionnalités que l&#8217;on attendait depuis longtemps, comme la gestion des&nbsp;permissions.</p> -<p>Bien sur, exactement comme après un ré-aménagement de salon, on ne peut -s&#8217;empêcher de voir toutes les choses qui doivent toujours être améliorées, -notamment sur la documentation et les&nbsp;performances.</p> -<p>On peut déjà entrevoir à quoi l&#8217;écosystème va ressembler, et c&#8217;est prometteur. -Il y a déjà un client JavaScript <a class="footnote-reference" href="#footnote-3" id="footnote-reference-3">[3]</a> dont l&#8217;objectif est de synchroniser les -données locales du navigateur avec une instance de&nbsp;Kinto.</p> -<p>N&#8217;hésitez vraiment pas à nous solliciter pour discuter avec vous si vous avez -des problématiques proches : nous accueillons avec plaisir toutes sortes de -retours, que ce soit à propos du code, de la documentation, de la sécurité de -la solution ou de la manière de communiquer avec le monde extérieur. Si vous -souhaitez nous contacter, vous pouvez laisser un commentaire ici ou nous -contacter sur le canal <a class="reference external" href="irc://irc.mozilla.org/#storage">#storage</a> sur le réseau <span class="caps">IRC</span> de&nbsp;Mozilla.</p> -<p>Et ce n&#8217;est que le début ! Le futur se dessine dans notre feuille de route -<a class="footnote-reference" href="#footnote-4" id="footnote-reference-4">[4]</a>.</p> -<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td><strong>Cliquet</strong> est une boite à outils pour faciliter l&#8217;implémentation de -microservices <span class="caps">HTTP</span> tels que les APIs <em><span class="caps">REST</span></em> ayant des besoins de -synchronisation.</td></tr> -</tbody> -</table> -<table class="docutils footnote" frame="void" id="footnote-2" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td><strong>Kinto</strong> est un service pour stocker, synchroniser et partager des données -arbitraires, attachées à un compte Firefox (mais le système d&#8217;authentification -est <em>pluggable</em>).</td></tr> -</tbody> -</table> -<table class="docutils footnote" frame="void" id="footnote-3" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-3">[3]</a></td><td>Cliquetis, la bibliothèque JavaScript pour consommer l&#8217;<span class="caps">API</span> <span class="caps">HTTP</span> de Kinto — -<a class="reference external" href="https://github.com/mozilla-services/cliquetis">https://github.com/mozilla-services/cliquetis</a></td></tr> -</tbody> -</table> -<table class="docutils footnote" frame="void" id="footnote-4" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-4">[4]</a></td><td>La feuille de route de Kinto: <a class="reference external" href="https://github.com/mozilla-services/kinto/wiki/roadmap">https://github.com/mozilla-services/kinto/wiki/roadmap</a></td></tr> -</tbody> -</table> -Service de nuages : Stocker et interroger les permissions avec Kinto2015-05-26T00:00:00+02:002015-05-26T00:00:00+02:00tag:blog.notmyidea.org,2015-05-26:/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html<p class="first last">Comment faire pour stocker et interroger la base de données au sujet des permissions avec Kinto&nbsp;?</p> -<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> -<p><strong>tl;dr: On a maintenant un super système de permission mais comment faire pour stocker et interroger ces permissions de manière efficace&nbsp;?</strong></p> -<div class="section" id="la-problematique"> -<h2>La&nbsp;problématique</h2> -<p>Maintenant que nous avons défini un modèle de gestion des permissions -sur les objets qui nous satisfait, le problème est de stocker ces -permissions de manière efficace afin de pouvoir autoriser ou interdire -l&#8217;accès à un objet pour la personne qui fait la&nbsp;requête.</p> -<p>Chaque requête sur notre <span class="caps">API</span> va générer une ou plusieurs demandes -d&#8217;accès, il faut donc que la réponse soit très rapide sous peine -d&#8217;impacter la vélocité du&nbsp;service.</p> -</div> -<div class="section" id="obtenir-la-liste-des-principals-d-un-utilisateur"> -<h2>Obtenir la liste des &#8220;principals&#8221; d&#8217;un&nbsp;utilisateur</h2> -<p>Les <em>principals</em> de l&#8217;utilisateur correspondent à son <tt class="docutils literal">user_id</tt> -ainsi qu&#8217;à la liste des identifiants des groupes dans lesquels il a -été&nbsp;ajouté.</p> -<p>Pour éviter de recalculer les <em>principals</em> de l&#8217;utilisateur à chaque -requête, le mieux reste de maintenir une liste des <em>principals</em> par&nbsp;utilisateur.</p> -<p>Ainsi lorsqu&#8217;on ajoute un utilisateur à un groupe, il faut bien penser -à ajouter le groupe à la liste des <em>principals</em> de&nbsp;l&#8217;utilisateur.</p> -<p>Ça se complexifie lorsqu&#8217;on ajoute un groupe à un&nbsp;groupe.</p> -<p>Dans un premier temps interdire l&#8217;ajout d&#8217;un groupe à un groupe est -une limitation qu&#8217;on est prêts à accepter pour simplifier le&nbsp;modèle.</p> -<p>L&#8217;avantage de maintenir la liste des <em>principals</em> d&#8217;un utilisateur -lors de la modification de cette liste c&#8217;est qu&#8217;elle est déjà -construite lors des lectures, qui sont dans notre cas plus fréquentes -que les&nbsp;écritures.</p> -<p>Cela nécessite de donner un identifiant unique aux groupes pour tous -les <em>buckets</em>.</p> -<p>Nous proposons de de les nommer avec leur <span class="caps">URI</span>: -<tt class="docutils literal">/buckets/blog/groups/moderators</tt></p> -</div> -<div class="section" id="obtenir-la-liste-des-principals-d-un-ace"> -<h2>Obtenir la liste des &#8220;principals&#8221; d&#8217;un <span class="caps">ACE</span></h2> -<blockquote> -Rappel, un &#8220;<span class="caps">ACE</span>&#8221; est un <em>Access Control Entry</em>, un des éléments -d&#8217;une <span class="caps">ACL</span> (e.g. <em>modifier un enregistrement</em>).</blockquote> -<p>Avec le <a class="reference external" href="https://blog.notmyidea.org/service-de-nuages-la-gestion-des-permissions-fr.html">système de permissions choisi</a>, les permissions d&#8217;un -objet héritent de celle de l&#8217;objet&nbsp;parent.</p> -<p>Par exemple, avoir le droit d&#8217;écriture sur un <em>bucket</em> permet la -création des permissions et la modification de tous ses&nbsp;records.</p> -<p>Ce qui veut dire que pour obtenir la liste complète des <em>principals</em> -ayant une permission sur un objet, il faut regarder à plusieurs&nbsp;endroits.</p> -<p>Rémy a <a class="reference external" href="https://gist.github.com/Natim/77c8f61c1d42e476cef8#file-permission-py-L9-L52">décrit dans un gist la liste d&#8217;héritage de chaque permission</a>.</p> -<p>Prenons l&#8217;exemple de l&#8217;ajout d&#8217;un record dans une&nbsp;collection.</p> -<p>Le droit <tt class="docutils literal">records:create</tt> est obtenu si l&#8217;on a l&#8217;un des droits&nbsp;suivants:</p> -<ul class="simple"> -<li><tt class="docutils literal">bucket:write</tt></li> -<li><tt class="docutils literal">collection:write</tt></li> -<li><tt class="docutils literal">records:create</tt></li> -</ul> -<p>Notre première idée était de stocker les permissions sur chaque objet -et de maintenir la liste exhaustive des permissions lors d&#8217;une -modification d&#8217;<span class="caps">ACL</span>. Cependant cela nécessitait de construire cette -liste lors de l&#8217;ajout d&#8217;un objet et de mettre à jour tout l&#8217;arbre lors -de sa suppression. (<em>Je vous laisse imaginer le nombre d&#8217;opérations -nécessaires pour ajouter un administrateur sur un *bucket</em> contenant -1000 collections avec 100000 records&nbsp;chacune.*)</p> -<p>La solution que nous avons désormais adoptée consiste à stocker les -<em>principals</em> de chaque <em><span class="caps">ACE</span></em> (<em>qui</em> a le droit de faire telle action -sur l&#8217;objet), et de faire l&#8217;union des <em><span class="caps">ACE</span></em> hérités, afin de les -croiser avec les <em>principals</em> de l&#8217;utilisateur&nbsp;:</p> -<blockquote> -(<span class="caps">ACE</span>(object, permission) ∪ inherited_ACE) ∩ <span class="caps">PRINCIPALS</span>(user)</blockquote> -<p>Par exemple l&#8217;<span class="caps">ACE</span>: <tt class="docutils literal">/buckets/blog/collections/article:records:create</tt> hérite de -l&#8217;<span class="caps">ACE</span> <tt class="docutils literal">/buckets/blog/collections/article:write</tt> et de <tt class="docutils literal">/buckets/blog:write</tt> :</p> -<blockquote> -(<span class="caps">ACE</span>(/buckets/blog/collections/article:records:create) ∪ <span class="caps">ACE</span>(/buckets/blog/collections/article:write) ∪ <span class="caps">ACE</span>(/buckets/blog:write)) ∩ <span class="caps">PRINCIPALS</span>(&#8216;fxa:alexis&#8217;)</blockquote> -</div> -<div class="section" id="recuperer-les-donnees-de-l-utilisateur"> -<h2>Récupérer les données de&nbsp;l&#8217;utilisateur</h2> -<p>La situation se corse lorsqu&#8217;on souhaite limiter la liste des -<em>records</em> d&#8217;une collection à ceux accessibles pour l&#8217;utilisateur, car -on doit faire cette intersection pour tous les <em>records</em>.</p> -<p>Une première solution est de regarder si l&#8217;utilisateur est mentionné -dans les <em><span class="caps">ACL</span>*s du *bucket</em> ou de la <em>collection</em>:</p> -<p>Ensuite, si ce n&#8217;est pas le cas, alors on filtre les <em>records</em> pour -lesquels les <em>principals</em> correspondent à ceux de&nbsp;l&#8217;utilisateur.</p> -<div class="highlight"><pre><span></span><span class="n">principals</span> <span class="o">=</span> <span class="n">get_user_principals</span><span class="p">(</span><span class="n">user_id</span><span class="p">)</span> -<span class="n">can_read_all</span> <span class="o">=</span> <span class="n">has_read_perms</span><span class="p">(</span><span class="n">bucket_id</span><span class="p">,</span> <span class="n">collection_id</span><span class="p">,</span> - <span class="n">principals</span><span class="p">)</span> -<span class="k">if</span> <span class="n">can_read_all</span><span class="p">:</span> - <span class="n">records</span> <span class="o">=</span> <span class="n">get_all_records</span><span class="p">(</span><span class="n">bucket_id</span><span class="p">,</span> <span class="n">collection_id</span><span class="p">,</span> - <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="o">...</span><span class="p">])</span> -<span class="k">else</span><span class="p">:</span> - <span class="n">records</span> <span class="o">=</span> <span class="n">filter_read_records</span><span class="p">(</span><span class="n">bucket_id</span><span class="p">,</span> <span class="n">collection_id</span><span class="p">,</span> - <span class="n">principals</span><span class="o">=</span><span class="n">principals</span><span class="p">,</span> - <span class="n">filters</span><span class="o">=</span><span class="p">[</span><span class="o">...</span><span class="p">])</span> -</pre></div> -<p>Il faudra faire quelque chose de similaire pour la suppression -multiple, lorsqu&#8217;un utilisateur souhaitera supprimer des -enregistrements sur lesquels il a les droits de lecture mais pas&nbsp;d&#8217;écriture.</p> -</div> -<div class="section" id="le-modele-de-donnees"> -<h2>Le modèle de&nbsp;données</h2> -<p>Pour avoir une idée des requêtes dans un backend <span class="caps">SQL</span>, voyons un peu ce -que donnerait le modèle de&nbsp;données.</p> -<div class="section" id="le-format-des-id"> -<h3>Le format des <span class="caps">ID</span></h3> -<p>Utiliser des <span class="caps">URI</span> comme identifiant des objets présente de nombreux -avantages (lisibilité, unicité, cohérence avec les&nbsp;URLs)</p> -<ul class="simple"> -<li>bucket: <tt class="docutils literal">/buckets/blog</tt></li> -<li>groupe: <tt class="docutils literal">/buckets/blog/group/moderators</tt></li> -<li>collection: <tt class="docutils literal">/buckets/blog/collections/articles</tt></li> -<li>record: <tt class="docutils literal"><span class="pre">/buckets/blog/collections/articles/records/02f3f76f-7059-4ae4-888f-2ac9824e9200</span></tt></li> -</ul> -</div> -<div class="section" id="les-tables"> -<h3>Les&nbsp;tables</h3> -<p>Pour le stockage des principals et des&nbsp;permissions:</p> -<div class="highlight"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">user</span><span class="p">(</span><span class="n">id</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[]);</span> -<span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">perms</span><span class="p">(</span><span class="n">ace</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[]);</span> -</pre></div> -<p>La table <em>perms</em> va associer des <em>principals</em> à chaque <em><span class="caps">ACE</span></em>&nbsp;(e.g.&#8220;/buckets/blog:write&#8220;).</p> -<p>Pour le stockage des&nbsp;données:</p> -<div class="highlight"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="k">object</span><span class="p">(</span><span class="n">id</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="w"> </span><span class="n">JSONB</span><span class="p">,</span> -<span class="w"> </span><span class="n">write_principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[],</span><span class="w"> </span><span class="n">read_principals</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">[]);</span> -</pre></div> -<p>La colonne <em>parent_id</em> permet de savoir à qui appartient l&#8217;objet -(e.g. groupe d&#8217;un <em>bucket</em>, collection d&#8217;un <em>bucket</em>, <em>record</em> d&#8217;une -collection,&nbsp;&#8230;).</p> -</div> -<div class="section" id="exemple-d-utilisateur"> -<h3>Exemple&nbsp;d&#8217;utilisateur</h3> -<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="p">)</span> -<span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;fxa:alexis&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">);</span> - -<span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">principals</span><span class="p">)</span> -<span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="s1">&#39;fxa:natim&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{&quot;/buckets/blog/groups/moderators&quot;}&#39;</span><span class="p">);</span> -</pre></div> -</div> -<div class="section" id="exemple-d-objets"> -<h3>Exemple&nbsp;d&#8217;objets</h3> -<div class="section" id="bucket"> -<h4>Bucket</h4> -<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> -<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> -<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;bucket&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="k">NULL</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;blog&quot;}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{&quot;fxa:alexis&quot;}&#39;</span><span class="p">);</span> -</pre></div> -</div> -<div class="section" id="group"> -<h4>Group</h4> -<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> -<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> -<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog/groups/moderators&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;group&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;moderators&quot;, &quot;members&quot;: [&#39;</span><span class="n">fxa</span><span class="p">:</span><span class="n">natim</span><span class="s1">&#39;]}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">);</span> -</pre></div> -<p>Ce groupe peut être gére par <tt class="docutils literal">fxa:alexis</tt> puisqu&#8217;il a la permission -<tt class="docutils literal">write</tt> dans le <em>bucket</em>&nbsp;parent.</p> -</div> -<div class="section" id="collection"> -<h4>Collection</h4> -<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> -<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> -<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/articles&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;collection&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;article&quot;}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{&quot;system.Everyone&quot;}&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{&quot;/buckets/blog/groups/moderators&quot;}&#39;</span><span class="p">);</span> -</pre></div> -<p>Cette collection d&#8217;articles peut être lue par tout le monde, -et gérée par les membres du groupe <tt class="docutils literal">moderators</tt>, ainsi que -<tt class="docutils literal">fxa:alexis</tt>, via le <em>bucket</em>.</p> -</div> -<div class="section" id="records"> -<h4>Records</h4> -<div class="highlight"><pre><span></span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="k">type</span><span class="p">,</span><span class="w"> </span><span class="n">parent_id</span><span class="p">,</span><span class="w"> </span><span class="k">data</span><span class="p">,</span> -<span class="w"> </span><span class="n">read_principals</span><span class="p">,</span><span class="w"> </span><span class="n">write_principals</span><span class="p">)</span> -<span class="k">VALUES</span><span class="w"> </span><span class="p">(</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/articles/records/02f3f76f-7059-4ae4-888f-2ac9824e9200&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;record&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/articles&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{&quot;name&quot;: &quot;02f3f76f-7059-4ae4-888f-2ac9824e9200&quot;,</span> -<span class="s1"> &quot;title&quot;: &quot;Stocker les permissions&quot;, ...}&#39;</span><span class="p">::</span><span class="n">JSONB</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;{}&#39;</span><span class="p">);</span> -</pre></div> -</div> -</div> -<div class="section" id="interroger-les-permissions"> -<h3>Interroger les&nbsp;permissions</h3> -<div class="section" id="obtenir-la-liste-des-principals-d-un-ace-1"> -<h4>Obtenir la liste des &#8220;principals&#8221; d&#8217;un <span class="caps">ACE</span></h4> -<p>Comme vu plus haut, pour vérifier une permission, on fait l&#8217;union des -<em>principals</em> requis par les objets hérités, et on teste leur -intersection avec ceux de&nbsp;l&#8217;utilisateur:</p> -<div class="highlight"><pre><span></span><span class="k">WITH</span><span class="w"> </span><span class="n">required_principals</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span> -<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">unnest</span><span class="p">(</span><span class="n">principals</span><span class="p">)</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="n">p</span> -<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">perms</span> -<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">ace</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="p">(</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog:write&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog:read&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/article:write&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/article:read&#39;</span><span class="p">)</span> -<span class="w"> </span><span class="p">),</span> -<span class="w"> </span><span class="n">user_principals</span><span class="w"> </span><span class="k">AS</span><span class="w"> </span><span class="p">(</span> -<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">unnest</span><span class="p">(</span><span class="n">principals</span><span class="p">)</span> -<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">user</span> -<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;fxa:natim&#39;</span> -<span class="w"> </span><span class="p">)</span> -<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> -<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">user_principals</span><span class="w"> </span><span class="n">a</span> -<span class="w"> </span><span class="k">INNER</span><span class="w"> </span><span class="k">JOIN</span><span class="w"> </span><span class="n">required_principals</span><span class="w"> </span><span class="n">b</span> -<span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="n">p</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">b</span><span class="p">.</span><span class="n">p</span><span class="p">;</span> -</pre></div> -</div> -<div class="section" id="filtrer-les-objets-en-fonction-des-permissions"> -<h4>Filtrer les objets en fonction des&nbsp;permissions</h4> -<p>Pour filtrer les objets, on fait une simple intersection de liste -(<em>merci PostgreSQL</em>):</p> -<div class="highlight"><pre><span></span><span class="k">SELECT</span><span class="w"> </span><span class="k">data</span> -<span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="k">object</span><span class="w"> </span><span class="n">o</span><span class="p">,</span><span class="w"> </span><span class="k">user</span><span class="w"> </span><span class="n">u</span> -<span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">o</span><span class="p">.</span><span class="k">type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;record&#39;</span> -<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">o</span><span class="p">.</span><span class="n">parent_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;/buckets/blog/collections/article&#39;</span> -<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="p">(</span><span class="n">o</span><span class="p">.</span><span class="n">read_principals</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">u</span><span class="p">.</span><span class="n">principals</span><span class="w"> </span><span class="k">OR</span> -<span class="w"> </span><span class="n">o</span><span class="p">.</span><span class="n">write_principals</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">u</span><span class="p">.</span><span class="n">principals</span><span class="p">)</span> -<span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">u</span><span class="p">.</span><span class="n">id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;fxa:natim&#39;</span><span class="p">;</span> -</pre></div> -<p>Les listes s&#8217;indexent bien, notamment grâce aux <a class="reference external" href="http://www.postgresql.org/docs/current/static/indexes-types.html">index <span class="caps">GIN</span></a>.</p> -</div> -</div> -<div class="section" id="avec-redis"> -<h3>Avec&nbsp;Redis</h3> -<p><em>Redis</em> présente plusieurs avantages pour ce genre de -problématiques. Notamment, il gère les <em>set</em> nativement (listes de -valeurs uniques), ainsi que les opérations d&#8217;intersection et&nbsp;d&#8217;union.</p> -<p>Avec <em>Redis</em> on peut écrire l&#8217;obtention des <em>principals</em> pour un <em><span class="caps">ACE</span></em> -comme cela&nbsp;:</p> -<div class="highlight"><pre><span></span>SUNIONSTORE temp_perm:/buckets/blog/collections/articles:write permission:/buckets/blog:write permission:/buckets/blog/collections/articles:write -SINTER temp_perm:/buckets/blog/collections/articles:write principals:fxa:alexis -</pre></div> -<ul class="simple"> -<li><tt class="docutils literal"><span class="caps">SUNIONSTORE</span></tt> permet de créer un set contenant les éléments de -l&#8217;union de tous les set suivants. Dans notre cas on le nomme -<tt class="docutils literal"><span class="pre">temp_perm:/buckets/blog/collections/articles:write</span></tt> et il contient -l&#8217;union des sets d&#8217;ACLs suivants: -- <tt class="docutils literal"><span class="pre">permission:/buckets/blog:write</span></tt> -- <tt class="docutils literal"><span class="pre">permission:/buckets/blog/collections/articles:write</span></tt></li> -<li><tt class="docutils literal"><span class="caps">SINTER</span></tt> retourne l&#8217;intersection de tous les sets passés en paramètres dans notre cas : -- <tt class="docutils literal"><span class="pre">temp_perm:/buckets/blog/collections/articles:write</span></tt> -- <tt class="docutils literal">principals:fxa:alexis</tt></li> -</ul> -<p>Plus d&#8217;informations sur : -- <a class="reference external" href="http://redis.io/commands/sinter">http://redis.io/commands/sinter</a> -- <a class="reference external" href="http://redis.io/commands/sunionstore">http://redis.io/commands/sunionstore</a></p> -<p>Si le set résultant de la commande <tt class="docutils literal"><span class="caps">SINTER</span></tt> n&#8217;est pas vide, alors -l&#8217;utilisateur possède la&nbsp;permission.</p> -<p>On peut ensuite supprimer la clé temporaire <tt class="docutils literal">temp_perm</tt>.</p> -<p>En utilisant <tt class="docutils literal"><span class="caps">MULTI</span></tt> on peut <a class="reference external" href="https://gist.github.com/Natim/77c8f61c1d42e476cef8#file-permission-py-L117-L124">même faire tout cela au sein d&#8217;une -transaction</a> -et garantir ainsi l&#8217;intégrité de la&nbsp;requête.</p> -</div> -</div> -<div class="section" id="conclusion"> -<h2>Conclusion</h2> -<p>La solution a l&#8217;air simple mais nous a demandé beaucoup de réflexion -en passant par plusieurs&nbsp;propositions.</p> -<p>L&#8217;idée finale est d&#8217;avoir&nbsp;:</p> -<ul class="simple"> -<li>Un backend spécifique permettant de stocker les <em>principals</em> des -utilisateurs et des <em><span class="caps">ACE</span></em> (e.g. avec les sets Redis)&nbsp;;</li> -<li>La liste des principals read et write sur la table des&nbsp;objets.</li> -</ul> -<p>C&#8217;est dommage d&#8217;avoir le concept de permissions à deux endroits, mais -cela permet de connaître rapidement la permission d&#8217;un utilisateur sur -un objet et également de pouvoir récupérer tous les objets d&#8217;une -collection pour un utilisateur si celui-ci n&#8217;a pas accès à tous les -records de la collection, ou toutes les collections du&nbsp;bucket.</p> -</div> -Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote> -<p>Flip a bit in the communication between sender and recipient and they -will experience decryption or verification errors. How high are the -chances they will start to exchange the data in the clear rather than -trying to hunt down the man in the&nbsp;middle?</p> -<p>&#8212; <a href="http://secushare.org/PGP">http://secushare.org/<span class="caps">PGP</span></a></p> -</blockquote> -<p>Une fois …</p><blockquote> -<p>Flip a bit in the communication between sender and recipient and they -will experience decryption or verification errors. How high are the -chances they will start to exchange the data in the clear rather than -trying to hunt down the man in the&nbsp;middle?</p> -<p>&#8212; <a href="http://secushare.org/PGP">http://secushare.org/<span class="caps">PGP</span></a></p> -</blockquote> -<p>Une fois passé l&#8217;euphorie du &#8220;il faut utiliser <span class="caps">PGP</span> pour l&#8217;ensemble de -nos communications&#8221;, j&#8217;ai réalisé lors de discussions que <span class="caps">PGP</span> avait -plusieurs problèmes, parmi&nbsp;ceux-ci:</p> -<ul> -<li>Les <em>meta données</em> (y compris le champ &#8220;sujet&#8221; de la conversation) - sont quand même échangées en clair (il est possible de savoir qu&#8217;un - message à été échangé entre telle et telle personne, a telle&nbsp;date);</li> -<li><span class="caps">PGP</span> se base sur un protocole de communication qui est lui non - chiffré, et il est donc facile de soit se tromper, soit dégrader le - mode de conversation vers une méthode non&nbsp;chiffrée;</li> -<li>Il est facile de connaître votre réseau social avec <span class="caps">PGP</span>, puisque - tout le principe est de signer les clés des personnes dont vous - validez&nbsp;l&#8217;identité;</li> -<li>En cas de fuite de votre clé privée, tous les messages que vous avez - chiffrés avec elle sont compromis. On dit que <span class="caps">PGP</span> ne fournit pas de - <em>forward secrecy</em>;</li> -<li>La découverte de la clé de pairs se passe souvent <em>en clair</em>, sans - utiliser une connexion &#8220;sécurisée&#8221; (<span class="caps">HTTPS</span>). Tout le monde peut donc - voir ces échanges et savoir de qui vous cherchez la&nbsp;clé;</li> -<li>Les discussions de groupes sont très difficiles: il faut chiffrer - pour chacun des destinataires (ou que ceux-ci partagent une paire de&nbsp;clés).</li> -</ul> -<p>Je suis en train de creuser à propos les alternatives à <span class="caps">PGP</span>, par exemple -<a href="https://pond.imperialviolet.org/">Pond</a>, qui lui ne construit pas par -dessus un standard déjà établi, et donc n&#8217;hérite pas de ses défauts -(mais pas non plus de son réseau déjà&nbsp;établi).</p> -<p>En attendant, quelques bonnes pratiques sur <span class="caps">PGP</span>&nbsp;;)</p> -<h2 id="bonnes-pratiques">Bonnes&nbsp;pratiques</h2> -<p>Il est en fait assez facile d&#8217;utiliser <span class="caps">PGP</span> de travers. Riseup à fait <a href="https://help.riseup.net/en/security/message-security/openpgp/best-practices">un -excellent -guide</a> -qui explique comment configurer son installation&nbsp;correctement.</p> -<ul> -<li>J&#8217;en ai déjà parlé, mais il faut absolument choisir des phrases de - passes suffisamment longues. Pas facile de les retenir, mais - indispensable. Vous pouvez aussi avoir un document chiffré avec une - clé que vous ne mettez jamais en ligne, qui contiens ces phrases de - passe, au cas ou vous les&nbsp;oubliez.</li> -<li>Générez des clés <span class="caps">RSA</span> de 4096 bits, en utilisant&nbsp;sha512;</li> -<li>Il faut utiliser une date d&#8217;expiration de nos clés suffisamment - proche (2 ans). Il est possible de repousser cette date si - nécessaire, par la&nbsp;suite.</li> -</ul> -<p>Parmi les choses les plus frappantes que j&#8217;ai&nbsp;rencontrées:</p> -<ul> -<li>Utiliser le <em>flag</em> –hidden-recipient avec <span class="caps">PGP</span> pour ne pas dévoiler - qui est le destinataire du&nbsp;message;</li> -<li>Ne pas envoyer les messages de brouillons sur votre serveur, ils le - seraient en clair&nbsp;!;</li> -<li>Utilisez <span class="caps">HPKS</span> pour communiquer avec les serveurs de clés, sinon tout - le trafic est en&nbsp;clair.</li> -</ul> -<p>Le <a href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils -de chiffrement d&#8217;échanges de messages et de <span class="caps">VPN</span> simples à utiliser, -encore quelque chose à&nbsp;regarder.</p> -<p>Enfin bref, y&#8217;a du&nbsp;taf.</p>Simplifier les preuves d’identités2015-05-11T00:00:00+02:002015-05-11T00:00:00+02:00tag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.html -<ul> -<li>headline<br> - Qu&#8217;est-ce que Keybase.io et comment essayent-ils de simplifier la - création de preuves&nbsp;d&#8217;identité.</li> -</ul> -<p>L&#8217;un des problèmes non réellement résolu actuellement quant au -chiffrement des échanges est lié à l&#8217;authenticité des clés. Si quelqu&#8217;un -décide de publier une clé en mon nom, et en …</p> -<ul> -<li>headline<br> - Qu&#8217;est-ce que Keybase.io et comment essayent-ils de simplifier la - création de preuves&nbsp;d&#8217;identité.</li> -</ul> -<p>L&#8217;un des problèmes non réellement résolu actuellement quant au -chiffrement des échanges est lié à l&#8217;authenticité des clés. Si quelqu&#8217;un -décide de publier une clé en mon nom, et en utilisant mon adresse email, -cela lui est assez&nbsp;facile.</p> -<p>Il est donc nécessaire d&#8217;avoir des moyens de prouver que la clé publique -que j&#8217;utilise est réellement la&nbsp;mienne.</p> -<p>Traditionnellement, il est nécessaire de faire signer ma clé publique -par d&#8217;autres personnes, via une rencontre en personne ou des échanges -hors du réseau. C&#8217;est par exemple ce qui est réalisé lors des <a href="https://fr.wikipedia.org/wiki/Key_signing_party">Key -Signing parties</a>.</p> -<p>Une manière simple d&#8217;effectuer ces vérifications serait, en plus de -donner son adresse email, sa signature de clé, ou a minima de donner un -mot clé pour valider que les échanges proviennent bien de la bonne&nbsp;personne.</p> -<p><span class="caps">PGP</span> propose un mécanisme de signature des clés d&#8217;autrui, une fois celles -ci validées, ce qui permet de placer sa confiance dans les signataires -de la&nbsp;clé.</p> -<p><a href="https://keybase.io">Keybase.io</a> est un service qui vise à rendre la -création de ces preuves plus facile, en partant du principe qu&#8217;il est -possible d&#8217;utiliser différents moyens afin de prouver l&#8217;identité des -personnes. Par exemple, leurs comptes Twitter, GitHub ou leurs noms de -domaines. De la même manière qu&#8217;il est possible de signer (valider) les -clés de nos amis, il est possible de les &#8220;tracker&#8221; selon le jargon de&nbsp;keybase.</p> -<p>Donc, en somme, <em>Keybase.io</em> est un annuaire, qui tente de rendre plus -facile la création de preuves.&nbsp;Bien.</p> -<h2 id="quelques-points-dombre">Quelques points&nbsp;d&#8217;ombre</h2> -<p>Il s&#8217;agit d&#8217;une <em>startup</em> américaine, domiciliée dans le Delaware, qui -se trouve être un des paradis fiscaux qui <a href="https://fr.wikipedia.org/wiki/Delaware">est connu pour être un -paradis fiscal au coeur même des -États-Unis</a>. Je ne veux pas -faire de raccourcis trop rapides, bien évidemment, alors <a href="https://github.com/keybase/keybase-issues/issues/1569">j&#8217;ai ouvert un -ticket sur GitHub pour en savoir -plus</a> (après -tout, le fait d&#8217;être un paradis fiscal permet peut-être d&#8217;échapper à -certaines lois sur la requêtes de données). D&#8217;autant plus étonnant, la -startup n&#8217;a pour l&#8217;instant <a href="https://github.com/keybase/keybase-issues/issues/788">pas de <em>business -model</em></a> (ce qui en -un sens est assez rassurant, même si on peut se poser la question de -pourquoi faire une startup dans ces cas&nbsp;là).</p> -<p>Le service (bien qu&#8217;en Alpha), n&#8217;est pas mis à disposition sous licence -libre, ce qui pour l&#8217;instant empêche quiconque de créer son propre -serveur Keybase. <a href="https://github.com/keybase/">Une partie des composants, cependant, le sont (open -source)</a>.</p> -<p>J&#8217;ai du mal à croire en des initiatives qui veulent sauver le monde, -mais dans leur coin, je ne comprends pas pourquoi il n&#8217;y à pas de -documentation sur comment monter son propre serveur, ou comment les -aider à travailler sur la fédération. Mais bon, c&#8217;est pour l&#8217;instant une -initiative encore fraîche, et je lui laisse le bénéfice du&nbsp;doute.</p> -<p>Sur le long terme, une infrastructure comme <em>Keybase.io</em>, devra -évidemment être -<a href="https://github.com/keybase/keybase-issues/issues/162">distribuée</a>.</p> -<blockquote> -<p>We&#8217;ve been talking about a total decentralization, but we have to -solve a couple things, synchronization in particular. Right now -someone can mirror us and a client can trust a mirror just as easily -as the server at keybase.io, but there needs to be a way of announcing -proofs to any server and having them cooperate with each other. We&#8217;d -be so happy to get this&nbsp;right.</p> -<p>&#8212; <a href="http://chris.beams.io/posts/keybase/">Chris Coyne, co-founder of&nbsp;Keybase</a></p> -</blockquote> -<p>Afin de se &#8220;passer&#8221; de leur service centralisé, les preuves générées -(qui sont la force du système qu&#8217;ils mettent en place) pourraient être -exportées sur des serveurs de clés existants. C&#8217;est quelque chose -<a href="https://github.com/keybase/keybase-issues/issues/890">qu&#8217;ils souhaitent réaliser -.</a>.</p> -<p>Bref, une initiative quand même importante et utile, même si elle -soulève des questions qui méritent qu&#8217;on s&#8217;y attarde un&nbsp;brin.</p> -<p>Par ailleurs, <a href="https://leap.se/nicknym">d&#8217;autres projets qui visent des objectifs -similaires</a> existent, via le projet <span class="caps">LEAP</span>, mais -je n&#8217;ai pas encore&nbsp;creusé.</p>Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html -<ul> -<li>headline<br> - Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de - mémoriser des phrases de passes complexes. Comment s&#8217;en sortir&nbsp;?</li> -</ul> -<blockquote> -<p>Au contraire des autres mots de passe, les mots de passe -cryptographiques ont specifiquement besoin d&#8217;être longs et extremement -difficiles à deviner. La raison est qu&#8217;un …</p></blockquote> -<ul> -<li>headline<br> - Communiquer de manière chiffrée n&#8217;est pas aisée, et nécessite de - mémoriser des phrases de passes complexes. Comment s&#8217;en sortir&nbsp;?</li> -</ul> -<blockquote> -<p>Au contraire des autres mots de passe, les mots de passe -cryptographiques ont specifiquement besoin d&#8217;être longs et extremement -difficiles à deviner. La raison est qu&#8217;un ordinateur (ou un cluster de -plusieurs ordinateurs) peut être programmé pour faire des trillions -d&#8217;essais de manière automatique. Si le mot de passe choisi est trop -faible ou construit d&#8217;une manière trop prédictible, cette attaque par -la force pourrait se revéler fructueuse en essayant toutes les&nbsp;possibilités.</p> -<p>&#8212; <a href="https://www.eff.org/wp/defending-privacy-us-border-guide-travelers-carrying-digital-devices">The Electronic Frontier -Foundation</a> -(traduction de mon&nbsp;fait)</p> -</blockquote> -<p>Comprendre les concepts et l&#8217;écosystème qui permettent d&#8217;avoir une vie -numérique chiffrée n&#8217;est pas quelque chose d&#8217;aisé. -<a href="https://emailselfdefense.fsf.org/fr/">Plusieurs</a> -<a href="http://www.controle-tes-donnees.net/outils/GnuPG.html">guides</a> ont été -écrits à ce propos, et pour autant je me rends compte que naïvement il -est possible de mal utiliser les outils&nbsp;existants.</p> -<blockquote> -<p>Utilisez un <em>bon</em> mot de passe pour votre session utilisateur et une -<em>bonne</em> phrase de passe pour proteger votre clé privée. Cette phrase -de passe est la partie la plus fragile de tout le&nbsp;système.</p> -<p>&#8212; La page de manuel de <span class="caps">GPG</span>.</p> -</blockquote> -<p>Une phrase de passe&nbsp;devrait:</p> -<ul> -<li>Être suffisamment longue pour être difficile à&nbsp;deviner;</li> -<li>Ne pas être une citation connue (littérature, livres sacrés&nbsp;etc);</li> -<li>Difficile à deviner même pour vos&nbsp;proches;</li> -<li>Facile à se souvenir et à&nbsp;taper;</li> -<li>être unique et non partagée entre différents sites / applications&nbsp;etc.</li> -</ul> -<p>Une des techniques consiste à utiliser des mots du dictionnaire, -sélectionnés de manière aléatoire, puis&nbsp;modifiés.</p> -<p><img alt="Trough 20 years of effort, we've succesfully trained everyone to use passwords that are hard for humans to remember, but easy for computers to guess" src="https://imgs.xkcd.com/comics/password_strength.png"></p> -<p>Micah Lee <a href="https://github.com/micahflee/passphrases">travaille également sur un -outil</a> qui vise à rendre la -mémorisation des phrases de passe plus aisée, de par leur répétition -avec des pauses de plus en plus&nbsp;longues.</p> -<p>Oui, ce n&#8217;est pas aussi simple que ce qu&#8217;il y parait. Pour ma part, j&#8217;ai -une copie en local de mes clés, dans un fichier chiffré avec une autre -clé que j&#8217;ai généré pour l&#8217;occasion et que je ne partagerait pas. J&#8217;ai -par ailleurs <a href="https://github.com/jamessan/vim-gnupg">configuré</a> mon -éditeur de texte pour pouvoir chiffrer les documents textes par&nbsp;défaut.</p> -<p>J&#8217;ai donc regénéré une nouvelle fois mes clés de travail et -personnelles, en utilisant des phrases de passe plus&nbsp;complexes.</p> -<p>Reste encore la question de la sauvegarde de ces clés privées de manière -chiffrée, que je n&#8217;ai pas encore résolue. Bref, tout cela me semble bien -compliqué pour réussir à l&#8217;expliquer à des novices, qui pour certains ne -sont même pas sur de l&#8217;intérêt de la&nbsp;chose.</p>Service de nuages : La gestion des permissions2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00tag:blog.notmyidea.org,2015-05-01:/service-de-nuages-la-gestion-des-permissions-fr.html<p class="first last">Démystification du vocabulaire des permissions et proposition d&#8217;implémentation pour&nbsp;Kinto</p> -<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> -<p>Dans le cadre de la création d&#8217;un service de stockage de données personnelles -(Kinto), la gestion des permissions est un des gros challenges : qui doit avoir -accès à quoi, et comment le définir&nbsp;?</p> -<p><strong>tl;dr: Quelques retours sur le vocabulaire des systèmes de permission et sur nos idées pour l&#8217;implementation des permissions dans un stockage&nbsp;générique.</strong></p> -<div class="section" id="la-problematique"> -<h2>La&nbsp;problématique</h2> -<p>La problématique est simple : des données sont stockées en ligne, et il -faut un moyen de pouvoir les partager avec d&#8217;autres&nbsp;personnes.</p> -<p>En regardant les cas d&#8217;utilisations, on se rend compte qu&#8217;on a plusieurs types -d&#8217;utilisateurs&nbsp;:</p> -<ul class="simple"> -<li>les utilisateurs &#8220;finaux&#8221; (vous)&nbsp;;</li> -<li>les applications qui interagissent en leurs&nbsp;noms.</li> -</ul> -<p>Tous les intervenants n&#8217;ont donc pas les mêmes droits : certains doivent -pouvoir lire, d&#8217;autres écrire, d&#8217;autres encore créer de nouveaux -enregistrements, et le contrôle doit pouvoir s&#8217;effectuer de manière fine : il -doit être possible de lire un enregistrement mais pas un autre, par&nbsp;exemple.</p> -<p>Nous sommes partis du constat que les solutions disponibles n&#8217;apportaient pas -une réponse satisfaisante à ces&nbsp;besoins.</p> -</div> -<div class="section" id="un-probleme-de-vocabulaire"> -<h2>Un problème de&nbsp;vocabulaire</h2> -<p>Le principal problème rencontré lors des réflexions fût le&nbsp;vocabulaire.</p> -<p>Voici ci-dessous une explication des différents&nbsp;termes.</p> -<div class="section" id="le-concept-de-principal"> -<h3>Le concept de « principal&nbsp;»</h3> -<p>Un <em>principal</em>, en sécurité informatique, est une entité qui peut être -authentifiée par un système informatique. <a class="footnote-reference" href="#footnote-1" id="footnote-reference-1">[1]</a> En Français il s&#8217;agit -du « commettant », l&#8217;acteur qui commet l&#8217;action (oui, le terme est conceptuel&nbsp;!)</p> -<p>Il peut s&#8217;agir aussi bien d&#8217;un individu, d&#8217;un ordinateur, d&#8217;un -service ou d&#8217;un groupe regroupant l&#8217;une de ces entités, ce qui -est plus large que le classique « <em>user id</em>&nbsp;».</p> -<p>Les permissions sont alors associées à ces <em>principals</em>.</p> -<p>Par exemple, un utilisateur est identifié de manière unique lors de la -connexion par le système d&#8217;authentification dont le rôle est de -définir une liste de <em>principals</em> pour l&#8217;utilisateur se&nbsp;connectant.</p> -<table class="docutils footnote" frame="void" id="footnote-1" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-1">[1]</a></td><td>Pour en savoir plus sur les <em>principals</em> : -<a class="reference external" href="https://en.wikipedia.org/wiki/Principal_%28computer_security%29">https://en.wikipedia.org/wiki/Principal_%28computer_security%29</a></td></tr> -</tbody> -</table> -</div> -<div class="section" id="la-difference-entre-role-et-groupe"> -<h3>La différence entre rôle et&nbsp;groupe</h3> -<p>De but en blanc, il n&#8217;est pas évident de définir précisément la -différence entre ces deux concepts qui permettent d&#8217;associer -des permissions à un groupe de <em>principals</em>. <a class="footnote-reference" href="#footnote-2" id="footnote-reference-2">[2]</a></p> -<p>La différence est principalement sémantique. Mais on peut y voir une -différence dans la « direction » de la relation entre les deux&nbsp;concepts.</p> -<ul class="simple"> -<li>Un rôle est une liste de permissions que l&#8217;on associe à un <em>principal</em>.</li> -<li>Un groupe est une liste de <em>principals</em> que l&#8217;on peut associer à une&nbsp;permission.</li> -</ul> -<table class="docutils footnote" frame="void" id="footnote-2" rules="none"> -<colgroup><col class="label" /><col /></colgroup> -<tbody valign="top"> -<tr><td class="label"><a class="fn-backref" href="#footnote-reference-2">[2]</a></td><td>Plus d&#8217;informations : -<a class="reference external" href="http://stackoverflow.com/questions/7770728/group-vs-role-any-real-difference">http://stackoverflow.com/questions/7770728/group-vs-role-any-real-difference</a></td></tr> -</tbody> -</table> -</div> -<div class="section" id="la-difference-entre-permission-acl-ace"> -<h3>La différence entre permission, <span class="caps">ACL</span>, <span class="caps">ACE</span></h3> -<blockquote class="epigraph"> -<p>Une <span class="caps">ACL</span> est une liste d’Access Control Entry (<span class="caps">ACE</span>) ou entrée de contrôle d&#8217;accès -donnant ou supprimant des droits d&#8217;accès à une personne ou un&nbsp;groupe.</p> -<p class="attribution">&mdash;<a class="reference external" href="https://fr.wikipedia.org/wiki/Access_Control_List">https://fr.wikipedia.org/wiki/Access_Control_List</a></p> -</blockquote> -<p>Je dirais même plus, dans notre cas, « à un <em>principal</em> ». Par&nbsp;exemple:</p> -<div class="highlight"><pre><span></span>create_record: alexis,remy,tarek -</pre></div> -<p>Cet <span class="caps">ACE</span> donne la permission <tt class="docutils literal">create</tt> sur l&#8217;objet <tt class="docutils literal">record</tt> aux -utilisateurs Tarek, Rémy et&nbsp;Alexis.</p> -</div> -</div> -<div class="section" id="la-delegation-de-permissions"> -<h2>La délégation de&nbsp;permissions</h2> -<p>Imaginez l&#8217;exemple suivant, où un utilisateur stocke deux types de données en -ligne&nbsp;:</p> -<ul class="simple"> -<li>des contacts&nbsp;;</li> -<li>une liste de tâches à faire qu&#8217;il peut associer à ses&nbsp;contacts.</li> -</ul> -<p>L&#8217;utilisateur a tous les droits sur ses&nbsp;données.</p> -<p>Cependant il utilise deux applications qui doivent elles avoir un accès restreint&nbsp;:</p> -<ul class="simple"> -<li>une application de gestion des contacts à qui il souhaite déléguer -la gestion intégrale de ses contacts : <tt class="docutils literal">contacts:write</tt> ;</li> -<li>une application de gestion des tâches à qui il souhaite déléguer la -gestion des tâches : <tt class="docutils literal">contacts:read tasks:write</tt></li> -</ul> -<p>Il souhaite que son application de contacts ne puisse pas accéder à -ses tâches et que son application de tâches ne puisse pas modifier ses -contacts existants, juste éventuellement en créer de&nbsp;nouveaux.</p> -<p>Il lui faut donc un moyen de déléguer certains de ses droits à un tiers&nbsp;(l&#8217;application).</p> -<p>C&#8217;est précisément le rôle des <a class="reference external" href="http://tools.ietf.org/html/rfc6749#page-23">scopes OAuth2</a>.</p> -<p>Lors de la connexion d&#8217;un utilisateur, une fenêtre lui demande quels -accès il veut donner à l&#8217;application qui va agir en son&nbsp;nom.</p> -<p>Le service aura ensuite accès à ces <em>scopes</em> en regardant le jeton -d&#8217;authentification utilisé. Cette information doit être -considérée comme une entrée utilisateur (c&#8217;est à dire qu&#8217;on ne peut -pas lui faire confiance). Il s&#8217;agit de ce que l&#8217;utilisateur&nbsp;souhaite.</p> -<p>Or, il est également possible que l&#8217;utilisateur n&#8217;ait pas accès aux données -qu&#8217;il demande. Le service doit donc utiliser deux niveaux de permissions : -celles de l&#8217;utilisateur, et celles qui ont été déléguées à&nbsp;l&#8217;application.</p> -</div> -<div class="section" id="espace-de-noms"> -<h2>Espace de&nbsp;noms</h2> -<p>Dans notre implémentation initiale de <em>Kinto</em> (notre service de stockage en -construction), l&#8217;espace de nom était implicite : les données stockées étaient -nécessairement celles de l&#8217;utilisateur&nbsp;connecté.</p> -<p>Les données d&#8217;un utilisateur étaient donc cloisonnées et impossible à&nbsp;partager.</p> -<p>L&#8217;utilisation d&#8217;espaces de noms est une manière simple de gérer le partage des&nbsp;données.</p> -<p>Nous avons choisi de reprendre le modèle de GitHub et de Bitbucket, qui -utilisent les « organisations » comme espaces de&nbsp;noms.</p> -<p>Dans notre cas, il est possible de créer des &#8220;buckets&#8221;, qui correspondent à ces -espaces de noms. Un bucket est un conteneur de collections et de groupes&nbsp;utilisateurs.</p> -<p>Les ACLs sur ces collections peuvent être attribuées à certains groupes du -<em>bucket</em> ainsi qu&#8217;à d&#8217;autres <em>principals</em>&nbsp;directement.</p> -</div> -<div class="section" id="notre-proposition-d-api"> -<h2>Notre proposition d&#8217;<span class="caps">API</span></h2> -<div class="section" id="les-objets-manipules"> -<h3>Les objets&nbsp;manipulés</h3> -<p>Pour mettre en place la gestion des permissions, nous avons identifié les -objets suivants&nbsp;:</p> -<table border="1" class="docutils"> -<colgroup> -<col width="23%" /> -<col width="77%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Objet</th> -<th class="head">Description</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td><strong>bucket</strong></td> -<td>On peut les voir comme des espaces de noms. Ils -permettent d&#8217;avoir différentes collections portant -le même nom mais stockées dans différents <em>buckets</em> de -manière à ce que les données soient distinctes.</td> -</tr> -<tr><td><strong>collection</strong></td> -<td>Une liste d&#8217;enregistrements.</td> -</tr> -<tr><td><strong>record</strong></td> -<td>Un enregistrement d&#8217;une collection.</td> -</tr> -<tr><td><strong>group</strong></td> -<td>Un groupe de commetants (« <em>principals</em> »).</td> -</tr> -</tbody> -</table> -<p>Pour la définition des ACLs, il y a une hiérarchie et les objets « héritent » des -ACLs de leur parents&nbsp;:</p> -<div class="highlight"><pre><span></span> +---------------+ - | Bucket | - +---------------+ - +-----&gt;+ - id +&lt;---+ - | | - permissions | | - | +---------------+ | - | | - | | - | | - | | - | | -+---+-----------+ +------+---------+ -| Collection | | Group | -+---------------+ +----------------+ -| - id | | - id | -| - permissions | | - members | -+------+--------+ | - permissions | - ^ +----------------+ - | - | -+------+---------+ -| Record | -+----------------+ -| - id | -| - data | -| - permissions | -+----------------+ -</pre></div> -</div> -<div class="section" id="les-permissions"> -<h3>Les&nbsp;permissions</h3> -<p>Pour chacun de ces objets nous avons identifié les permissions suivantes&nbsp;:</p> -<table border="1" class="docutils"> -<colgroup> -<col width="23%" /> -<col width="77%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Permission</th> -<th class="head">Description</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td><strong>read</strong></td> -<td>La permission de lire le contenu de -l&#8217;objet et de ses sous-objets.</td> -</tr> -<tr><td><strong>write</strong></td> -<td>La permission de modifier et -d&#8217;administrer un objet et ses sous- -objets. La permission <em>write</em> permet la -lecture, modification et suppression -d&#8217;un objet ainsi que la gestion de ses -permissions.</td> -</tr> -<tr><td><strong>create</strong></td> -<td>La permission de créer le sous-objet -spécifié. Par exemple: -<tt class="docutils literal">collections:create</tt></td> -</tr> -</tbody> -</table> -<p>À chaque permission spécifiée sur un objet est associée une liste de -<em>principals</em>.</p> -<p>Dans le cas de la permission <tt class="docutils literal">create</tt> on est obligé de spécifier -l&#8217;objet enfant en question car un objet peut avoir plusieurs types -d&#8217;enfants. Par exemple : <tt class="docutils literal">collections:create</tt>, <tt class="docutils literal">groups:create</tt>.</p> -<p>Nous n&#8217;avons pour l&#8217;instant pas de permission pour <cite>delete</cite> et <cite>update</cite>, -puisque nous n&#8217;avons pas trouvé de cas d&#8217;utilisation qui les nécessitent. -Quiconque avec le droit d&#8217;écriture peut donc supprimer un&nbsp;enregistrement.</p> -<p>Les permissions d&#8217;un objet sont héritées de son parent. Par exemple, -un enregistrement créé dans une collection accessible à tout le monde -en lecture sera lui aussi accessible à tout le&nbsp;monde.</p> -<p>Par conséquent, les permissions sont cumulées. Autrement dit, il n&#8217;est pas -possible qu&#8217;un objet ait des permissions plus restrictives que son&nbsp;parent.</p> -<p>Voici la liste exhaustive des permissions&nbsp;:</p> -<table border="1" class="docutils"> -<colgroup> -<col width="21%" /> -<col width="32%" /> -<col width="47%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Objet</th> -<th class="head">Permissions associées</th> -<th class="head">Commentaire</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td>Configuration -(.ini)</td> -<td><cite>buckets:create</cite></td> -<td>Les <em>principals</em> ayant le droit -de créer un bucket sont définis -dans la configuration du serveur. -(<em>ex. utilisateurs authentifiés</em>)</td> -</tr> -<tr><td rowspan="4"><tt class="docutils literal">bucket</tt></td> -<td><cite>write</cite></td> -<td>C&#8217;est en quelque sorte le droit -d&#8217;administration du <em>bucket</em>.</td> -</tr> -<tr><td><cite>read</cite></td> -<td>C&#8217;est le droit de lire le contenu -de tous les objets du <em>bucket</em>.</td> -</tr> -<tr><td><cite>collections:create</cite></td> -<td>Permission de créer des -collections dans le <em>bucket</em>.</td> -</tr> -<tr><td><cite>groups:create</cite></td> -<td>Permission de créer des groupes -dans le <em>bucket</em>.</td> -</tr> -<tr><td rowspan="3"><tt class="docutils literal">collection</tt></td> -<td><cite>write</cite></td> -<td>Permission d&#8217;administrer tous les -objets de la collection.</td> -</tr> -<tr><td><cite>read</cite></td> -<td>Permission de consulter tous les -objets de la collection.</td> -</tr> -<tr><td><cite>records:create</cite></td> -<td>Permission de créer des nouveaux -enregistrement dans la collection.</td> -</tr> -<tr><td rowspan="2"><tt class="docutils literal">record</tt></td> -<td><cite>write</cite></td> -<td>Permission de modifier ou de -partager l&#8217;enregistrement.</td> -</tr> -<tr><td><cite>read</cite></td> -<td>Permission de consulter -l&#8217;enregistrement.</td> -</tr> -<tr><td rowspan="2"><tt class="docutils literal">group</tt></td> -<td><cite>write</cite></td> -<td>Permission d&#8217;administrer le -groupe</td> -</tr> -<tr><td><cite>read</cite></td> -<td>Permission de consulter les -membres du groupe.</td> -</tr> -</tbody> -</table> -</div> -<div class="section" id="les-principals"> -<h3>Les « <em>principals</em>&nbsp;»</h3> -<p>Les acteurs se connectant au service de stockage peuvent&nbsp;s&#8217;authentifier.</p> -<p>Ils reçoivent alors une liste de <em>principals</em>&nbsp;:</p> -<ul class="simple"> -<li><tt class="docutils literal">Everyone</tt>: le <em>principal</em> donné à tous les acteurs (authentifiés ou pas)&nbsp;;</li> -<li><tt class="docutils literal">Authenticated</tt>: le <em>principal</em> donné à tous les acteurs authentifiés&nbsp;;</li> -<li>un <em>principal</em> identifiant l&#8217;acteur, par exemple <tt class="docutils literal">fxa:32aa95a474c984d41d395e2d0b614aa2</tt></li> -</ul> -<p>Afin d&#8217;éviter les collisions d&#8217;identifiants, le <em>principal</em> de l&#8217;acteur dépend -de son type d&#8217;authentification (<tt class="docutils literal">system</tt>, <tt class="docutils literal">basic</tt>, <tt class="docutils literal">ipaddr</tt>, <tt class="docutils literal">hawk</tt>, -<tt class="docutils literal">fxa</tt>) et de son identifiant (unique par&nbsp;acteur).</p> -<p>En fonction du <em>bucket</em> sur lequel se passe l&#8217;action, les groupes dont -fait partie l&#8217;utilisateur sont également ajoutés à sa liste de -<tt class="docutils literal">principals</tt>. <tt class="docutils literal">group:moderators</tt> par&nbsp;exemple.</p> -<p>Ainsi, si Bob se connecte avec <em>Firefox Accounts</em> sur le <em>bucket</em> -<tt class="docutils literal">servicedenuages_blog</tt> dans lequel il fait partie du groupe -<tt class="docutils literal">moderators</tt>, il aura la liste de <em>principals</em> suivante : -<tt class="docutils literal">Everyone, Authenticated, fxa:32aa95a474c984d41d395e2d0b614aa2, group:moderators</tt></p> -<p>Il est donc possible d&#8217;assigner une permission à Bob en utilisant l&#8217;un de -ces quatre <em>principals</em>.</p> -<div class="admonition note"> -<p class="first admonition-title">Note</p> -<p class="last">Le <em>principal</em> <tt class="docutils literal">&lt;userid&gt;</tt> dépend du <em>back-end</em> d&#8217;authentification (e.g. -<tt class="docutils literal">github:leplatrem</tt>).</p> -</div> -</div> -<div class="section" id="quelques-exemples"> -<h3>Quelques&nbsp;exemples</h3> -<p><strong>Blog</strong></p> -<table border="1" class="docutils"> -<colgroup> -<col width="35%" /> -<col width="18%" /> -<col width="46%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Objet</th> -<th class="head">Permissions</th> -<th class="head">Principals</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td><tt class="docutils literal">bucket:blog</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;blog</span> owner id&gt;</tt></td> -</tr> -<tr><td rowspan="2"><tt class="docutils literal">collection:articles</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal">group:moderators</tt></td> -</tr> -<tr><td><tt class="docutils literal">read</tt></td> -<td><tt class="docutils literal">Everyone</tt></td> -</tr> -<tr><td><tt class="docutils literal">record:569e28r98889</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;co-author</span> id&gt;</tt></td> -</tr> -</tbody> -</table> -<p><strong>Wiki</strong></p> -<table border="1" class="docutils"> -<colgroup> -<col width="35%" /> -<col width="18%" /> -<col width="46%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Object</th> -<th class="head">Permissions</th> -<th class="head">Principals</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td><tt class="docutils literal">bucket:wiki</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;wiki</span> administrator id&gt;</tt></td> -</tr> -<tr><td rowspan="2"><tt class="docutils literal">collection:articles</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal">Authenticated</tt></td> -</tr> -<tr><td><tt class="docutils literal">read</tt></td> -<td><tt class="docutils literal">Everyone</tt></td> -</tr> -</tbody> -</table> -<p><strong>Sondages</strong></p> -<table border="1" class="docutils"> -<colgroup> -<col width="34%" /> -<col width="31%" /> -<col width="35%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Objet</th> -<th class="head">Permissions</th> -<th class="head">Principals</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td rowspan="2"><tt class="docutils literal">bucket:poll</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;admin</span> id&gt;</tt></td> -</tr> -<tr><td><tt class="docutils literal">collection:create</tt></td> -<td><tt class="docutils literal">Authenticated</tt></td> -</tr> -<tr><td rowspan="2"><tt class="docutils literal"><span class="pre">collection:&lt;poll</span> id&gt;</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;poll</span> author id&gt;</tt></td> -</tr> -<tr><td><tt class="docutils literal">record:create</tt></td> -<td><tt class="docutils literal">Everyone</tt></td> -</tr> -</tbody> -</table> -<p><strong>Cartes&nbsp;colaboratives</strong></p> -<table border="1" class="docutils"> -<colgroup> -<col width="34%" /> -<col width="31%" /> -<col width="35%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Objet</th> -<th class="head">Permissions</th> -<th class="head">Principals</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td rowspan="2"><tt class="docutils literal">bucket:maps</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;admin</span> id&gt;</tt></td> -</tr> -<tr><td><tt class="docutils literal">collection:create</tt></td> -<td><tt class="docutils literal">Authenticated</tt></td> -</tr> -<tr><td rowspan="2"><tt class="docutils literal"><span class="pre">collection:&lt;map</span> id&gt;</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;map</span> author id&gt;</tt></td> -</tr> -<tr><td><tt class="docutils literal">read</tt></td> -<td><tt class="docutils literal">Everyone</tt></td> -</tr> -<tr><td><tt class="docutils literal"><span class="pre">record:&lt;record</span> id&gt;</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;maintainer</span> id&gt;</tt> -(<em>ex. event staff member -maintaining venues</em>)</td> -</tr> -</tbody> -</table> -<p><strong>Plateformes</strong></p> -<p>Bien sûr, il y a plusieurs façons de modéliser les cas d&#8217;utilisation typiques. -Par exemple, on peut imaginer une plateforme de wikis (à la wikia.com), où les -wikis sont privés par défaut et certaines pages peuvent être rendues publiques&nbsp;:</p> -<table border="1" class="docutils"> -<colgroup> -<col width="32%" /> -<col width="30%" /> -<col width="38%" /> -</colgroup> -<thead valign="bottom"> -<tr><th class="head">Objet</th> -<th class="head">Permissions</th> -<th class="head">Principals</th> -</tr> -</thead> -<tbody valign="top"> -<tr><td rowspan="3"><tt class="docutils literal">bucket:freewiki</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;administrator</span> id&gt;</tt></td> -</tr> -<tr><td><tt class="docutils literal">collection:create</tt></td> -<td><tt class="docutils literal">Authenticated</tt></td> -</tr> -<tr><td><tt class="docutils literal">group:create</tt></td> -<td><tt class="docutils literal">Authenticated</tt></td> -</tr> -<tr><td rowspan="2"><tt class="docutils literal"><span class="pre">collection:&lt;wiki</span> id&gt;</tt></td> -<td><tt class="docutils literal">write</tt></td> -<td><tt class="docutils literal"><span class="pre">fxa:&lt;wiki</span> owner id&gt;</tt>, -<tt class="docutils literal"><span class="pre">group:&lt;editors</span> id&gt;</tt></td> -</tr> -<tr><td><tt class="docutils literal">read</tt></td> -<td><tt class="docutils literal"><span class="pre">group:&lt;readers</span> id&gt;</tt></td> -</tr> -<tr><td><tt class="docutils literal"><span class="pre">record:&lt;page</span> id&gt;</tt></td> -<td><tt class="docutils literal">read</tt></td> -<td><tt class="docutils literal">Everyone</tt></td> -</tr> -</tbody> -</table> -</div> -<div class="section" id="l-api-http"> -<h3>L&#8217;<span class="caps">API</span> <span class="caps">HTTP</span></h3> -<p>Lors de la création d&#8217;un objet, l&#8217;utilisateur se voit -attribué la permission <tt class="docutils literal">write</tt> sur l&#8217;objet&nbsp;:</p> -<div class="highlight"><pre><span></span><span class="nf">PUT</span> <span class="nn">/v1/buckets/servicedenuages_blog</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> -<span class="na">Authorization</span><span class="o">:</span> <span class="l">Bearer 0b9c2625dc21ef05f6ad4ddf47c5f203837aa32ca42fced54c2625dc21efac32</span> -<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json</span> - -HTTP/1.1 201 Created -Content-Type: application/json; charset=utf-8 - -{ - &quot;id&quot;: &quot;servicedenuages_blog&quot;, - &quot;permissions&quot;: { - &quot;write&quot;: [&quot;fxa:49d02d55ad10973b7b9d0dc9eba7fdf0&quot;] - } -} -</pre></div> -<p>Il est possible d&#8217;ajouter des permissions à l&#8217;aide de <tt class="docutils literal"><span class="caps">PATCH</span></tt> :</p> -<div class="highlight"><pre><span></span><span class="nf">PATCH</span> <span class="nn">/v1/buckets/servicedenuages_blog/collections/articles</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> -<span class="na">Authorization</span><span class="o">:</span> <span class="l">Bearer 0b9c2625dc21ef05f6ad4ddf47c5f203837aa32ca42fced54c2625dc21efac32</span> -<span class="na">Accept</span><span class="o">:</span> <span class="l">application/json</span> - -{ - &quot;permissions&quot;: { - &quot;read&quot;: [&quot;+system.Everyone&quot;] - } -} - -HTTP/1.1 201 Created -Content-Type: application/json; charset=utf-8 - -{ - &quot;id&quot;: &quot;servicedenuages_blog&quot;, - &quot;permissions&quot;: { - &quot;write&quot;: [&quot;fxa:49d02d55ad10973b7b9d0dc9eba7fdf0&quot;], - &quot;read&quot;: [&quot;system.Everyone&quot;] - } -} -</pre></div> -<p>Pour le <tt class="docutils literal"><span class="caps">PATCH</span></tt> nous utilisons la syntaxe préfixée par un <tt class="docutils literal">+</tt> ou -par un <tt class="docutils literal">-</tt> pour ajouter ou enlever des <em>principals</em> sur un <span class="caps">ACL</span>.</p> -<p>Il est également possible de faire un <tt class="docutils literal"><span class="caps">PUT</span></tt> pour réinitialiser les ACLs, -sachant que le <tt class="docutils literal"><span class="caps">PUT</span></tt> va ajouter l&#8217;utilisateur courant à la -liste automatiquement mais qu&#8217;il pourra se retirer avec un <tt class="docutils literal"><span class="caps">PATCH</span></tt>. -Ajouter l&#8217;utilisateur courant permet d&#8217;éviter les situations où plus -personne n&#8217;a accès aux&nbsp;données.</p> -<div class="admonition note"> -<p class="first admonition-title">Note</p> -<p class="last">La permission <tt class="docutils literal">create</tt> est valable pour <tt class="docutils literal"><span class="caps">POST</span></tt> mais aussi pour <tt class="docutils literal"><span class="caps">PUT</span></tt> -lorsque l&#8217;enregistrement n&#8217;existe&nbsp;pas.</p> -</div> -</div> -<div class="section" id="le-cas-specifique-des-donnees-utilisateurs"> -<h3>Le cas spécifique des données&nbsp;utilisateurs</h3> -<p>Une des fonctionnalités actuelles de <em>Kinto</em> est de pouvoir gérer des -collections d&#8217;enregistrements par&nbsp;utilisateur.</p> -<p>Sous <em>*nix</em> il est possible, pour une -application, de sauvegarder la configuration de l&#8217;utilisateur courant -dans son dossier personnel sans se soucier de l&#8217;emplacement sur -le disque en utilisant <tt class="docutils literal">~/</tt>.</p> -<p>Dans notre cas si une application souhaite sauvegarder les contacts d&#8217;un -utilisateur, elle peut utiliser le raccourci <tt class="docutils literal">~</tt> pour faire référence au -<em>bucket</em> <strong>personnel</strong> de l&#8217;utilisateur : <tt class="docutils literal"><span class="pre">/buckets/~/collections/contacts</span></tt></p> -<p>Cette <span class="caps">URL</span> retournera le code <tt class="docutils literal"><span class="caps">HTTP</span> 307</tt> vers le <em>bucket</em> de l&#8217;utilisateur courant&nbsp;:</p> -<div class="highlight"><pre><span></span><span class="nf">POST</span> <span class="nn">/v1/buckets/~/collections/contacts/records</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span> - -{ - &quot;name&quot;: &quot;Rémy&quot;, - &quot;emails&quot;: [&quot;remy@example.com&quot;], - &quot;phones&quot;: [&quot;+330820800800&quot;] -} - -HTTP/1.1 307 Temporary Redirect -Location: /v1/buckets/fxa:49d02d55ad10973b7b9d0dc9eba7fdf0/collections/contacts/records -</pre></div> -<p>Ainsi il est tout à fait possible à Alice de partager ses contacts -avec Bob. Il lui suffit pour cela de donner la permission <tt class="docutils literal">read</tt> à -Bob sur sa collection et de donner l&#8217;<span class="caps">URL</span> complète -<tt class="docutils literal">/v1/buckets/fxa:49d02d55ad10973b7b9d0dc9eba7fdf0/collections/contacts/records</tt> -à&nbsp;Bob.</p> -</div> -<div class="section" id="la-delegation-des-permissions"> -<h3>La délégation des&nbsp;permissions</h3> -<p>Dans le cas de <em>Kinto</em>, nous avons défini un format pour restreindre les -permissions via les scopes OAuth2: -<tt class="docutils literal"><span class="pre">storage:&lt;bucket_id&gt;:&lt;collection_id&gt;:&lt;permissions_list&gt;</span></tt>.</p> -<p>Ainsi, si on reprend l&#8217;exemple précédent de la liste de tâches, il est possible pour -Bob de créer un token OAuth spécifique avec les <em>scopes</em> suivants : -<tt class="docutils literal">profile storage:todolist:tasks:write <span class="pre">storage:~:contacts:read+records:create</span></tt></p> -<p>Donc, bien que Bob a la permission <tt class="docutils literal">write</tt> sur ses contacts, -l&#8217;application utilisant ce token pourra uniquement lire les contacts -existants et en ajouter de&nbsp;nouveaux.</p> -<p>Une partie de la complexité est donc de réussir à présenter ces <em>scopes</em> de -manière lisible à l&#8217;utilisateur, afin qu&#8217;il choisisse quelles permissions -donner aux applications qui agissent en son&nbsp;nom.</p> -<p>Voilà où nous en sommes de notre réflexion&nbsp;!</p> -<p>Si vous avez des choses à ajouter, des points de désaccord ou autres -réflexions, n&#8217;hésitez pas à nous interrompre pendant qu&#8217;il est encore temps&nbsp;!</p> -</div> -</div> -Eco-système et stockage générique2015-04-30T00:00:00+02:002015-04-30T00:00:00+02:00tag:blog.notmyidea.org,2015-04-30:/eco-systeme-et-stockage-generique.html -<p><strong>tl;dr Nous devons construire un service de suivi de paiements, et nous -hésitons à continuer à nous entêter avec notre propre solution de&nbsp;stockage/synchronisation.</strong></p> -<p>Comme nous l&#8217;écrivions <a href="https://blog.notmyidea.org/service-de-nuages-fr.html">dans l&#8217;article -précédent</a>, nous -souhaitons construire une solution de stockage générique. On refait -<a href="http://daybed.readthedocs.org">Daybed</a> chez Mozilla&nbsp;!</p> -<p>Notre objectif est …</p> -<p><strong>tl;dr Nous devons construire un service de suivi de paiements, et nous -hésitons à continuer à nous entêter avec notre propre solution de&nbsp;stockage/synchronisation.</strong></p> -<p>Comme nous l&#8217;écrivions <a href="https://blog.notmyidea.org/service-de-nuages-fr.html">dans l&#8217;article -précédent</a>, nous -souhaitons construire une solution de stockage générique. On refait -<a href="http://daybed.readthedocs.org">Daybed</a> chez Mozilla&nbsp;!</p> -<p>Notre objectif est simple: permettre aux développeurs d&#8217;application, -internes à Mozilla ou du monde entier, de faire persister et -synchroniser facilement des données associées à un&nbsp;utilisateur.</p> -<div id="storage-specs"> - -Les aspects de l&#8217;architecture qui nous semblent incontournables: - -</div> - -<ul> -<li>La solution doit reposer sur un protocole, et non sur une - implémentation&nbsp;;</li> -<li>L&#8217;auto-hébergement de l&#8217;ensemble doit être simplissime&nbsp;;</li> -<li>L&#8217;authentification doit être <em>pluggable</em>, voire décentralisée - (OAuth2, FxA, Persona)&nbsp;;</li> -<li>Les enregistrements doivent pouvoir être validés par le serveur&nbsp;;</li> -<li>Les données doivent pouvoir être stockées dans n&#8217;importe quel - backend&nbsp;;</li> -<li>Un système de permissions doit permettre de protéger des - collections, ou de partager des enregistrements de manière fine&nbsp;;</li> -<li>La résolution de conflits doit pouvoir avoir lieu sur le serveur&nbsp;;</li> -<li>Le client doit être pensé «*offline-first*»&nbsp;;</li> -<li>Le client doit pouvoir réconcilier les données simplement&nbsp;;</li> -<li>Le client doit pouvoir être utilisé aussi bien dans le navigateur - que côté serveur&nbsp;;</li> -<li>Tous les composants se doivent d´être simples et substituables&nbsp;facilement.</li> -</ul> -<p>La première question qui nous a été posée fût «*Pourquoi vous -n&#8217;utilisez pas PouchDB ou Remote Storage&nbsp;?*»</p> -<h2 id="remote-storage">Remote&nbsp;Storage</h2> -<p>Remote Storage est un standard ouvert pour du stockage par utilisateur. -<a href="http://tools.ietf.org/html/draft-dejong-remotestorage-04">La -specification</a> -se base sur des standards déjà existants et éprouvés: Webfinger, OAuth -2, <span class="caps">CORS</span> et <span class="caps">REST</span>.</p> -<p>L&#8217;<span class="caps">API</span> est simple, des <a href="http://blog.cozycloud.cc/news/2014/08/12/when-unhosted-meets-cozy-cloud/">projets prestigieux -l&#8217;utilisent</a>. -Il y a plusieurs <a href="https://github.com/jcoglan/restore">implémentations</a> -du serveur, et il existe <a href="https://www.npmjs.com/package/remotestorage-server">un squelette -Node</a> pour -construire un serveur sur&nbsp;mesure.</p> -<p><img alt="Remote Storage widget" src="%7Bfilename%7D/images/remotestorage-widget.png"></p> -<p>Le client -<a href="https://github.com/remotestorage/remotestorage.js/">remoteStorage.js</a> -permet d&#8217;intégrer la solution dans les applications Web. Il se charge du -«store local», du cache, de la synchronization, et fournit un widget qui -permet aux utilisateurs des applications de choisir le serveur qui -recevra les données (via&nbsp;Webfinger).</p> -<p><a href="https://github.com/michielbdejong/ludbud">ludbud</a>, la version épurée de -<em>remoteStorage.js</em>, se limite à l&#8217;abstraction du stockage distant. Cela -permettrait à terme, d&#8217;avoir une seule bibliothèque pour stocker dans un -serveur <em>remoteStorage</em>, <em>ownCloud</em> ou chez les méchants comme <em>Google -Drive</em> ou <em>Dropbox</em>.</p> -<p>Au premier abord, la spécification correspond à ce que nous voulons&nbsp;accomplir:</p> -<ul> -<li>La philosophie du protocole est&nbsp;saine;</li> -<li>L&#8217;éco-système est bien&nbsp;fichu;</li> -<li>La vision politique colle: redonner le contrôle des données aux - utilisateurs (voir <a href="http://unhosted.org/">unhosted</a>);</li> -<li>Les choix techniques compatibles avec ce qu&#8217;on a commencé (<span class="caps">CORS</span>, - <span class="caps">REST</span>, OAuth&nbsp;2);</li> -</ul> -<p>En revanche, vis à vis de la manipulation des données, il y a plusieurs -différences avec ce que nous souhaitons&nbsp;faire:</p> -<ul> -<li>L&#8217;<span class="caps">API</span> suit globalement une métaphore «fichiers» (dossier/documents), - plutôt que «données» (collection/enregistrements)&nbsp;;</li> -<li>Il n&#8217;y a pas de validation des enregistrements selon un schéma (même - si <a href="https://remotestorage.io/doc/code/files/baseclient/types-js.html">certaines - implémentations</a> - du protocole le font)&nbsp;;</li> -<li>Il n&#8217;y a pas la possibilité de trier/filtrer les enregistrements - selon des attributs&nbsp;;</li> -<li>Les permissions <a href="https://groups.google.com/forum/#!topic/unhosted/5_NOGq8BPTo">se limitent à - privé/public</a> - (et <a href="https://github.com/remotestorage/spec/issues/58#issue-27249452">l&#8217;auteur envisage plutôt un modèle à la - Git</a>)[1]&nbsp;;</li> -</ul> -<p>En résumé, il semblerait que ce que nous souhaitons faire avec le -stockage d&#8217;enregistrements validés est complémentaire avec <em>Remote -Storage</em>.</p> -<p>Si des besoins de persistence orientés «fichiers» se présentent, a -priori nous aurions tort de réinventer les solutions apportées par cette -spécification. Il y a donc de grandes chances que nous l´intégrions à -terme, et que <em>Remote Storage</em> devienne une facette de notre&nbsp;solution.</p> -<h2 id="pouchdb">PouchDB</h2> -<p><a href="http://pouchdb.com/">PouchDB</a> est une bibliothèque JavaScript qui -permet de manipuler des enregistrements en local et de les synchroniser -vers une base&nbsp;distante.</p> -<div class="highlight"><pre><span></span><code><span class="n">javascript</span> -<span class="k">var</span><span class="w"> </span><span class="n">db</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">new</span><span class="w"> </span><span class="n">PouchDB</span><span class="p">(</span><span class="s1">&#39;dbname&#39;</span><span class="p">);</span> - -<span class="n">db</span><span class="o">.</span><span class="n">put</span><span class="p">({</span> -<span class="w"> </span><span class="n">_id</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;dave@gmail.com&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="n">name</span><span class="p">:</span><span class="w"> </span><span class="s1">&#39;David&#39;</span><span class="p">,</span> -<span class="w"> </span><span class="n">age</span><span class="p">:</span><span class="w"> </span><span class="mi">68</span> -<span class="p">});</span> - -<span class="n">db</span><span class="o">.</span><span class="n">replicate</span><span class="o">.</span><span class="n">to</span><span class="p">(</span><span class="s1">&#39;http://example.com/mydb&#39;</span><span class="p">);</span> -</code></pre></div> - -<p>Le projet a le vent en poupe, bénéficie de nombreux contributeurs, -l&#8217;éco-système est très riche et l&#8217;adoption par des projets <a href="https://github.com/hoodiehq/wip-hoodie-store-on-pouchdb">comme -Hoodie</a> ne fait -que confirmer la pertinence de l&#8217;outil pour les développeurs&nbsp;frontend.</p> -<p><em>PouchDB</em> gère un « store » local, dont la persistence est abstraite et -<a href="http://pouchdb.com/2014/07/25/pouchdb-levels-up.html">repose sur</a> l&#8217;<span class="caps">API</span> -<a href="https://github.com/level/levelup#relationship-to-leveldown">LevelDown</a> -pour persister les données dans <a href="https://github.com/Level/levelup/wiki/Modules#storage-back-ends">n&#8217;importe quel -backend</a>.</p> -<p>Même si <em>PouchDB</em> adresse principalement les besoins des applications -«*offline-first*», il peut être utilisé aussi bien dans le navigateur -que côté serveur, via&nbsp;Node.</p> -<h3 id="synchronisation">Synchronisation</h3> -<p>La synchronisation (ou réplication) des données locales s&#8217;effectue sur -un <a href="http://couchdb.apache.org/">CouchDB</a>&nbsp;distant.</p> -<p>Le projet <a href="https://github.com/pouchdb/pouchdb-server">PouchDB Server</a> -implémente l&#8217;<span class="caps">API</span> de CouchDB en NodeJS. Comme <em>PouchDB</em> est utilisé, on -obtient un service qui se comporte comme un <em>CouchDB</em> mais qui stocke -ses données n&#8217;importe où, dans un <em>Redis</em> ou un <em>PostgreSQL</em> par&nbsp;exemple.</p> -<p>La synchronisation est complète. Autrement dit, tous les enregistrements -qui sont sur le serveur se retrouvent synchronisés dans le client. Il -est possible de filtrer les collections synchronisées, mais cela <a href="http://pouchdb.com/2015/04/05/filtered-replication.html">n&#8217;a -pas pour objectif de sécuriser l&#8217;accès aux -données</a>.</p> -<p>L&#8217;approche recommandée pour cloisonner les données par utilisateur -consiste à créer <a href="https://github.com/nolanlawson/pouchdb-authentication#some-people-can-read-some-docs-some-people-can-write-those-same-docs">une base de données par -utilisateur</a>.</p> -<p>Ce n&#8217;est pas forcément un problème, CouchDB <a href="https://mail-archives.apache.org/mod_mbox/couchdb-user/201401.mbox/%3C52CEB873.7080404@ironicdesign.com%3E">supporte des centaines de -milliers de bases sans -sourciller</a>. -Mais selon les cas d&#8217;utilisation, le cloisement n&#8217;est pas toujours -facile à déterminer (par rôle, par application, par collection,&nbsp;&#8230;).</p> -<h2 id="le-cas-dutilisation-payments">Le cas d&#8217;utilisation « Payments&nbsp;»</h2> -<p><img alt="Put Payments Here -- Before the Internet - CC-NC-SA Katy Silberger -https://www.flickr.com/photos/katysilbs/11163812186" src="%7Bfilename%7D/images/put-payments.jpg"></p> -<p>Dans les prochaines semaines, nous devrons mettre sur pied un prototype -pour tracer l&#8217;historique des paiements et abonnements d&#8217;un&nbsp;utilisateur.</p> -<p>Le besoin est&nbsp;simple:</p> -<ul> -<li>l&#8217;application « Payment » enregistre les paiements et abonnements - d&#8217;un utilisateur pour une application&nbsp;donnée;</li> -<li>l&#8217;application « Donnée » interroge le service pour vérifier qu&#8217;un - utilisateur a payé ou est&nbsp;abonné;</li> -<li>l&#8217;utilisateur interroge le service pour obtenir la liste de tous ses&nbsp;abonnements.</li> -</ul> -<p>Seule l&#8217;application « Payment » a le droit de créer/modifier/supprimer -des enregistrements, les deux autres ne peuvent que consulter en lecture&nbsp;seule.</p> -<p>Une application donnée ne peut pas accéder aux paiements des autres -applications, et un utilisateur ne peut pas accéder aux paiements des -autres&nbsp;utilisateurs.</p> -<h3 id="avec-remotestorage">Avec&nbsp;RemoteStorage</h3> -<p><img alt="Remote Love - CC-BY-NC Julie -https://www.flickr.com/photos/mamajulie2008/2609549461" src="%7Bfilename%7D/images/remote-love.jpg"></p> -<p>Clairement, l&#8217;idée de <em>RemoteStorage</em> est de dissocier l&#8217;application -executée, et les données créées par l&#8217;utilisateur avec&nbsp;celle-ci.</p> -<p>Dans notre cas, c&#8217;est l&#8217;application « Payment » qui manipule des données -concernant un utilisateur. Mais celles-ci ne lui appartiennent pas -directement: certes un utilisateur doit pouvoir les supprimer, surtout -pas en créer ou les&nbsp;modifier!</p> -<p>La notion de permissions limitée à privé/publique ne suffit pas dans ce -cas&nbsp;précis.</p> -<h3 id="avec-pouchdb">Avec&nbsp;PouchDB</h3> -<p>Il va falloir créer une <em>base de données</em> par utilisateur, afin d&#8217;isoler -les enregistrements de façon sécurisée. Seule l&#8217;application « Payment » -aura tous les droits sur les&nbsp;databases.</p> -<p>Mais cela ne suffit&nbsp;pas.</p> -<p>Il ne faut pas qu&#8217;une application puisse voir les paiements des autres -applications, donc il va aussi falloir recloisonner, et créer une <em>base -de données</em> par&nbsp;application.</p> -<p>Quand un utilisateur voudra accéder à l&#8217;ensemble de ses paiements, il -faudra agréger les <em>databases</em> de toutes les applications. Quand -l&#8217;équipe marketing voudra faire des statistiques sur l&#8217;ensemble des -applications, il faudra agrégér des centaines de milliers de -<em>databases</em>.</p> -<p>Ce qui est fort dommage, puisqu&#8217;il est probable que les paiements ou -abonnements d&#8217;un utilisateur pour une application se comptent sur les -doigts d&#8217;une main. Des centaines de milliers de bases contenant moins de -5 enregistrements&nbsp;?</p> -<p>De plus, dans le cas de l&#8217;application « Payment », le serveur est -implémenté en Python. Utiliser un wrapper JavaScript comme le fait -<a href="https://pythonhosted.org/Python-PouchDB/">python-pouchdb</a> cela ne nous -fait pas trop&nbsp;rêver.</p> -<h2 id="un-nouvel-eco-systeme">Un nouvel éco-système&nbsp;?</h2> -<p><img alt="Wagon wheel - CC-BY-NC-SA arbyreed -https://www.flickr.com/photos/19779889@N00/16161808220" src="%7Bfilename%7D/images/wagon-wheel.jpg"></p> -<p>Évidemment, quand on voit la richesse des projets <em>PouchDB</em> et <em>Remote -Storage</em> et la dynamique de ces communautés, il est légitime d&#8217;hésiter -avant de développer une solution&nbsp;alternative.</p> -<p>Quand nous avons créé le serveur <em>Reading List</em>, nous l&#8217;avons construit -avec <a href="http://cliquet.readthedocs.org/">Cliquet</a>, ce fût l&#8217;occasion de -mettre au point <a href="http://cliquet.readthedocs.org/en/latest/api/">un protocole très -simple</a>, fortement -inspiré de <a href="http://en.wikipedia.org/wiki/Firefox_Sync">Firefox Sync</a>, -pour faire de la synchronisation&nbsp;d&#8217;enregistrements.</p> -<p>Et si les clients <em>Reading List</em> ont pu être implémentés en quelques -semaines, que ce soit en JavaScript, Java (Android) et <span class="caps">ASM</span> (Add-on -Firefox), c&#8217;est que le principe «*offline first*» du service est&nbsp;trivial.</p> -<h3 id="les-compromis">Les&nbsp;compromis</h3> -<p>Évidemment, nous n&#8217;avons pas la prétention de concurrencer <em>CouchDB</em>. -Nous faisons plusieurs&nbsp;concessions:</p> -<ul> -<li>De base, les collections d&#8217;enregistrements sont cloisonnées par&nbsp;utilisateur;</li> -<li>Pas d&#8217;historique des&nbsp;révisions;</li> -<li>Pas de diff sur les enregistrements entre&nbsp;révisions;</li> -<li>De base, pas de résolution de conflit&nbsp;automatique;</li> -<li>Pas de synchronisation par flux (<em>streams</em>);</li> -</ul> -<p>Jusqu&#8217;à preuve du contraire, ces compromis excluent la possibilité -d&#8217;implémenter un <a href="https://github.com/pouchdb/pouchdb/blob/master/lib/adapters/http/http.js#L721-L946">adapter -PouchDB</a> -pour la synchronisation avec le protocole <span class="caps">HTTP</span> de <em>Cliquet</em>.</p> -<p>Dommage puisque capitaliser sur l&#8217;expérience client de <em>PouchDB</em> au -niveau synchro client semble être une très bonne&nbsp;idée.</p> -<p>En revanche, nous avons plusieurs fonctionnalités&nbsp;intéressantes:</p> -<ul> -<li>Pas de&nbsp;map-reduce;</li> -<li>Synchronisation partielle et/ou ordonnée et/ou paginée&nbsp;;</li> -<li>Le client choisit, via des headers, d&#8217;écraser la donnée ou de - respecter la version du serveur&nbsp;;</li> -<li>Un seul serveur à déployer pour N applications&nbsp;;</li> -<li>Auto-hébergement simplissime&nbsp;;</li> -<li>Le client peut choisir de ne pas utiliser de « store local » du tout&nbsp;;</li> -<li>Dans le client <span class="caps">JS</span>, la gestion du « store local » sera externalisée - (on pense à <a href="https://github.com/mozilla/localForage">LocalForage</a> ou - <a href="https://github.com/dfahlander/Dexie.js">Dexie.js</a>)&nbsp;;</li> -</ul> -<p>Et, on répond au reste des <a href="#storage-specs">specifications mentionnées au début de -l&#8217;article</a>&nbsp;!</p> -<h3 id="les-arguments-philosophiques">Les arguments&nbsp;philosophiques</h3> -<p>Il est <a href="http://en.wikipedia.org/wiki/Law_of_the_instrument">illusoire de penser qu&#8217;on peut tout faire avec un seul -outil</a>.</p> -<p>Nous avons d&#8217;autres cas d&#8217;utilisations dans les cartons qui semblent -correspondre au scope de <em>PouchDB</em> (<em>pas de notion de permissions ou de -partage, environnement JavaScript, &#8230;</em>). Nous saurons en tirer profit -quand cela s&#8217;avèrera pertinent&nbsp;!</p> -<p>L&#8217;éco-système que nous voulons construire tentera de couvrir les cas -d&#8217;utilisation qui sont mal adressés par <em>PouchDB</em>. Il se&nbsp;voudra:</p> -<ul> -<li>Basé sur notre protocole très simple&nbsp;;</li> -<li>Minimaliste et multi-usages (<em>comme la fameuse <span class="caps">2CV</span></em>)&nbsp;;</li> -<li>Naïf (<em>pas de rocket science</em>)&nbsp;;</li> -<li>Sans magie (<em>explicite et facile à réimplémenter from scratch</em>)&nbsp;;</li> -</ul> -<p><a href="http://cliquet.readthedocs.org/en/latest/rationale.html">La philosophie et les fonctionnalités du toolkit python -Cliquet</a> seront -bien entendu à l&#8217;honneur&nbsp;:)</p> -<p>Quant à <em>Remote Storage</em>, dès que le besoin se présentera, nous serons -très fier de rejoindre l&#8217;initiative, mais pour l&#8217;instant cela nous -paraît risqué de démarrer en tordant la&nbsp;solution.</p> -<h3 id="les-arguments-pratiques">Les arguments&nbsp;pratiques</h3> -<p>Avant d&#8217;accepter de déployer une solution à base de <em>CouchDB</em>, les <em>ops</em> -de Mozilla vont nous demander de leur prouver par A+B que ce n&#8217;est pas -faisable avec les stacks qui sont déjà rodées en interne (i.e. MySQL, -Redis,&nbsp;PostgreSQL).</p> -<p>De plus, on doit s&#8217;engager sur une pérennité d&#8217;au moins 5 ans pour les -données. Avec <em>Cliquet</em>, en utilisant le backend PostgreSQL, les données -sont persistées à plat dans un <a href="https://github.com/mozilla-services/cliquet/blob/40aa33/cliquet/storage/postgresql/schema.sql#L14-L28">schéma PostgreSQL tout -bête</a>. -Ce qui ne sera pas le cas d&#8217;un adapteur LevelDown qui va manipuler des -notions de révisions éclatées dans un schéma&nbsp;clé-valeur.</p> -<p>Si nous basons le service sur <em>Cliquet</em>, comme c&#8217;est le cas avec -<a href="http://kinto.readthedocs.org">Kinto</a>, tout le travail d&#8217;automatisation -de la mise en production (<em>monitoring, builds <span class="caps">RPM</span>, Puppet&#8230;</em>) que nous -avons fait pour <em>Reading List</em> est complètement&nbsp;réutilisable.</p> -<p>De même, si on repart avec une stack complètement différente, nous -allons devoir recommencer tout le travail de rodage, de profiling et -d&#8217;optimisation effectué au premier&nbsp;trimestre.</p> -<h2 id="les-prochaines-etapes">Les prochaines&nbsp;étapes</h2> -<p>Et il est encore temps de changer de stratégie :) Nous aimerions avoir -un maximum de retours ! C&#8217;est toujours une décision difficile à -prendre&#8230; <code>&lt;/appel à troll&gt;</code></p> -<ul> -<li>Tordre un éco-système existant vs. constuire sur mesure&nbsp;;</li> -<li>Maîtriser l&#8217;ensemble vs. s&#8217;intégrer&nbsp;;</li> -<li>Contribuer vs. refaire&nbsp;;</li> -<li>Guider vs.&nbsp;suivre.</li> -</ul> -<p>Nous avons vraiment l&#8217;intention de rejoindre l&#8217;initiative -<a href="https://nobackend.org/">no-backend</a>, et ce premier pas n&#8217;exclue pas que -nous convergions à terme ! Peut-être que nous allons finir par rendre -notre service compatible avec <em>Remote Storage</em>, et peut-être que -<em>PouchDB</em> deviendra plus agnostique quand au protocole de&nbsp;synchronisation&#8230;</p> -<p><img alt="XKCD — Standards -https://xkcd.com/927/" src="%7Bfilename%7D/images/standards.png"></p> -<p>Utiliser ce nouvel écosystème pour le projet « Payments » va nous -permettre de mettre au point un système de permissions (<em>probablement -basé sur les scopes OAuth</em>) qui correspond au besoin exprimé. Et nous -avons bien l&#8217;intention de puiser dans <a href="http://blog.daybed.io/daybed-revival.html">notre expérience avec Daybed sur -le sujet</a>.</p> -<p>Nous extrairons aussi le code des clients implémentés pour <em>Reading -List</em> afin de faire un client JavaScript&nbsp;minimaliste.</p> -<p>En partant dans notre coin, nous prenons plusieurs&nbsp;risques:</p> -<ul> -<li>réinventer une roue dont nous n&#8217;avons pas connaissance&nbsp;;</li> -<li>échouer à faire de l&#8217;éco-système <em>Cliquet</em> un projet communautaire&nbsp;;</li> -<li>échouer à positionner <em>Cliquet</em> dans la niche des cas non couverts - par PouchDB&nbsp;:)</li> -</ul> -<p>Comme <a href="http://pouchdb.com/2015/04/05/filtered-replication.html">le dit Giovanni -Ornaghi</a>:</p> -<blockquote> -<p>Rolling out your set of webservices, push notifications, or background -services might give you more control, but at the same time it will -force you to engineer, write, test, and maintain a whole new&nbsp;ecosystem.</p> -</blockquote> -<p>C&#8217;est justement l&#8217;éco-système dont est responsable l&#8217;équipe <em>Mozilla -Cloud Services</em>!</p> -<ol> -<li>Il existe le <a href="https://sharesome.5apps.com/">projet Sharesome</a> qui - permet de partager publiquement des ressources de son <em>remote - Storage</em>.</li> -</ol>Service de nuages !2015-04-01T00:00:00+02:002015-04-01T00:00:00+02:00tag:blog.notmyidea.org,2015-04-01:/service-de-nuages-fr.html<p class="first last">Retour sur le premier trimestre 2015: Readinglist, Kinto,&nbsp;Cliquet.</p> -<p><em>Cet article est repris depuis le blog « Service de Nuages » de mon équipe à&nbsp;Mozilla</em></p> -<p>Pas mal de changements depuis le début de l&#8217;année pour l&#8217;équipe -«cloud-services»&nbsp;francophone!</p> -<p>Tout d&#8217;abord, nouvelle importante, l&#8217;équipe s&#8217;étoffe avec des profils assez -complémentaires: <a class="reference external" href="https://nicolas.perriault.net/">n1k0</a> et <a class="reference external" href="http://mathieu-leplatre.info">Mathieu</a> sont venus prêter main forte à <a class="reference external" href="http://ziade.org/">Tarek</a>, <a class="reference external" href="http://natim.ionyse.com">Rémy</a> et <a class="reference external" href="http://notmyidea.org">Alexis</a>.</p> -<p>Le début de l&#8217;année a vu le lancement de <a class="reference external" href="https://www.mozilla.org/en-US/firefox/hello/">Firefox Hello</a> ce qui nous a permis de passer -à l&#8217;échelle <a class="reference external" href="https://github.com/mozilla-services/loop-server">le serveur</a>, -écrit en Node.js®, pour&nbsp;l&#8217;occasion.</p> -<div class="section" id="un-serveur-de-listes-de-lecture"> -<h2>Un serveur de listes de&nbsp;lecture</h2> -<p>En parallèle, un projet de <a class="reference external" href="https://readinglist.readthedocs.org">synchronisation de liste de lecture</a> (<em>Reading List</em>) a vu le jour. L&#8217;idée -étant de pouvoir marquer des pages &#8220;à lire pour plus tard&#8221; et de continuer la -lecture sur n&#8217;importe quel périphérique synchronisé (Firefox pour Android ou -Firefox Desktop). Un équivalent libre à <a class="reference external" href="http://getpocket.com">Pocket</a> en quelque sorte, qu&#8217;il est -possible d&#8217;héberger&nbsp;soit-même.</p> -<img alt="Capture d'écran de Firefox nightly avec readinglist." src="https://blog.notmyidea.org/images/readinglist-screenshot.png" /> -<p>Pour le construire, nous aurions pu réutiliser <a class="reference external" href="https://github.com/mozilla-services/server-syncstorage">Firefox Sync</a>, après tout -c&#8217;est un service de synchronisation de données très robuste, construit avec <a class="reference external" href="http://cornice.readthedocs.org/">Cornice</a>. -Mais seulement, <em>Sync</em> n&#8217;a pas été pensé pour garantir la pérennité des données, -et la marche était trop haute pour changer ça en&nbsp;profondeur.</p> -<p>Nous aurions pu aussi nous contenter de faire une énième application qui expose -une <span class="caps">API</span> et persiste des données dans une base de&nbsp;données.</p> -<p>Mais cette nouvelle petite équipe n&#8217;est pas là par hasard&nbsp;:)</p> -</div> -<div class="section" id="la-daybed-team"> -<h2>La «Daybed&nbsp;Team»</h2> -<p>On partage une vision: un service générique de stockage de données ! Peut-être -que ça vous rappelle <a class="reference external" href="https://daybed.io">un certain projet nommé Daybed</a> ? -Pour les applications clientes, JavaScript, mobiles ou autres, l&#8217;utilisation de -ce service doit être un jeu d&#8217;enfant ! L&#8217;application gère ses données -localement (aka offline-first), et synchronise à la&nbsp;demande.</p> -<p>Ici, le cœur du serveur <em>Reading List</em> est justement une <span class="caps">API</span> &#8220;<span class="caps">CRUD</span>&#8221; (Create, -Retrieve, Update, Delete), qui gère de la synchronisation et de -l&#8217;authentification. Nous avons donc pris le parti de faire une <span class="caps">API</span> &#8220;simple&#8221;, -avec le moins de spécificités possible, qui poserait les bases d&#8217;un service -générique. Notamment parce qu&#8217;il y a d&#8217;autres projets dans la même trempe qui vont&nbsp;suivre.</p> -<p>Pas mal d&#8217;expérience ayant été accumulée au sein de l&#8217;équipe, avec d&#8217;une part la -création de <em>Firefox Sync</em>, et d&#8217;autre part avec <em>Daybed</em>, notre side-project, nous -tentons de ne pas reproduire les mêmes erreurs, tout en gardant les concepts -qui ont fait leurs&nbsp;preuves.</p> -<p>Par exemple, nous avons conservé le mécanisme de collections d&#8217;enregistrements -et de <em>timestamp</em> de <em>Sync</em>. Comme ces problématiques sont récurrentes, voire -incontournables, nous avons décidé de reprendre le protocole de synchronisation, -de l&#8217;étendre légèrement et surtout de le dissocier du projet de listes de&nbsp;lecture.</p> -</div> -<div class="section" id="le-mecanisme-qui-force-a-aller-de-l-avant"> -<h2>Le mécanisme qui force à aller de&nbsp;l&#8217;avant</h2> -<p>Comme première pierre à l&#8217;édifice, nous avons donné naissance au projet -<a class="reference external" href="https://cliquet.readthedocs.org">Cliquet</a>, dont l&#8217;idée principale est de -fournir une implémentation de ce protocole en python, tout en factorisant -l&#8217;ensemble de nos bonnes pratiques (pour la prod&nbsp;notamment).</p> -<img alt="Logo du projet Cliquet" class="align-right" src="https://blog.notmyidea.org/images/cliquet/cliquet-logo.png" /> -<p>L&#8217;avantage d&#8217;avoir un protocole plutôt qu&#8217;un monolithe, c&#8217;est que si vous -préférez Asyncio, io.js ou Go, on vous encouragera à publier votre -implémentation alternative&nbsp;!</p> -<p>Avec <em>Cliquet</em>, le code du serveur liste de lecture consiste principalement -à définir un schéma pour les enregistrements, puis à forcer des valeurs de -champs sur certains appels. Cela réduit ce projet à quelques dizaines de lignes -de&nbsp;code.</p> -<p>Quant au futur service de stockage générique, <a class="reference external" href="http://kinto.readthedocs.org">le projet</a> en est encore à ses balbutiements mais c&#8217;est -bel et bien en route ! Il permet déjà d&#8217;être branché comme backend de stockage -dans une application <em>Cliquet</em>, et ça <a class="reference external" href="https://github.com/mozilla-services/kinto/blob/0.2.1/kinto/views/collection.py">implémenté en 20 lignes de code</a>!</p> -<p>Ah, et cette fois, nous ne construirons les fonctionnalités qu&#8217;à partir des -besoins concrets qui surviennent. Ça paraît tout bête, mais sur <em>Daybed</em> on -l&#8217;a pas vu venir&nbsp;:)</p> -<p>Dans les prochains articles, nous avons prévu de décrire les bonnes pratiques -rassemblées dans le protocole (ou <em>Cliquet</em>), certains points techniques précis -et de vous présenter notre vision via des exemples et&nbsp;tutoriaux.</p> -<p>À bientôt, donc&nbsp;!</p> -</div> -What’s Hawk and how to use it?2014-07-31T00:00:00+02:002014-07-31T00:00:00+02:00tag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.html -<p>At Mozilla, we recently had to implement <a href="https://github.com/hueniverse/hawk">the Hawk authentication -scheme</a> for a number of projects, -and we came up creating two libraries to ease integration into pyramid -and node.js&nbsp;apps.</p> -<p>But maybe you don&#8217;t know&nbsp;Hawk.</p> -<p>Hawk is a relatively new technology, crafted by one of the …</p> -<p>At Mozilla, we recently had to implement <a href="https://github.com/hueniverse/hawk">the Hawk authentication -scheme</a> for a number of projects, -and we came up creating two libraries to ease integration into pyramid -and node.js&nbsp;apps.</p> -<p>But maybe you don&#8217;t know&nbsp;Hawk.</p> -<p>Hawk is a relatively new technology, crafted by one of the original -<a href="https://en.wikipedia.org/wiki/OAuth">OAuth</a> specification authors, that -intends to replace the 2-legged OAuth authentication scheme using a -simpler&nbsp;approach.</p> -<p>It is an authentication scheme for <span class="caps">HTTP</span>, built around <a href="https://en.wikipedia.org/wiki/Hmac"><span class="caps">HMAC</span> -digests</a> of requests and&nbsp;responses.</p> -<p>Every authenticated client request has an Authorization header -containing a <span class="caps">MAC</span> (Message Authentication Code) and some additional -metadata, then each server response to authenticated requests contains a -Server-Authorization header that authenticates the response, so the -client is sure it comes from the right&nbsp;server.</p> -<h2 id="exchange-of-the-hawk-id-and-hawk-key">Exchange of the hawk id and hawk&nbsp;key</h2> -<p>To sign the requests, a client needs to retrieve a token id and a token -key from the&nbsp;server.</p> -<p>Hawk itself does not define how these credentials should be exchanged -between the server and the client. The excellent team behind <a href="http://accounts.firefox.com">Firefox -Accounts</a> put together a scheme to do that, -which acts like the&nbsp;following:</p> -<div class="note"> - -<div class="admonition-title"> - -Note - -</div> - -All this derivation crazyness might seem a bit complicated, but don&#8217;t -worry, we put together some libraries that takes care of that for you -automatically. - -If you are not interested into these details, you can directly jump to -the next section to see how to use the libraries. - -</div> - -<p>When your server application needs to send you the credentials, it will -return it inside a specific Hawk-Session-Token header. This token can be -derived to split this string in two values (hawk id and hawk key) that -you will use to sign your next&nbsp;requests.</p> -<p>In order to get the hawk credentials, you&#8217;ll need&nbsp;to:</p> -<p>First, do an <a href="http://en.wikipedia.org/wiki/HKDF"><span class="caps">HKDF</span> derivation</a> on the -given session token. You&#8217;ll need to use the following&nbsp;parameters:</p> -<div class="highlight"><pre><span></span><code>key_material = HKDF(hawk_session, &quot;&quot;, &#39;identity.mozilla.com/picl/v1/sessionToken&#39;, 32*2) -</code></pre></div> - -<div class="note"> - -<div class="admonition-title"> - -Note - -</div> - -The `identity.mozilla.com/picl/v1/sessionToken` is a reference to this -way of deriving the credentials, not an actual <span class="caps">URL</span>. - -</div> - -<p>Then, the key material you&#8217;ll get out of the <span class="caps">HKDF</span> need to be separated -into two parts, the first 32 hex caracters are the hawk id, and the next -32 ones are the hawk&nbsp;key.</p> -<p>Credentials:</p> -<div class="highlight"><pre><span></span><code>javascript -credentials = { - &#39;id&#39;: keyMaterial[0:32], - &#39;key&#39;: keyMaterial[32:64], - &#39;algorithm&#39;: &#39;sha256&#39; -} -</code></pre></div> - -<h2 id="httpie">Httpie</h2> -<p>To showcase APIs in the documentation, I like to use -<a href="https://github.com/jakubroztocil/httpie">httpie</a>, a curl-replacement -with a nicer <span class="caps">API</span>, built around <a href="http://python-requests.org">the python requests -library</a>.</p> -<p>Luckily, HTTPie allows you to plug different authentication schemes for -it, so <a href="https://github.com/mozilla-services/requests-hawk">I wrote a -wrapper</a> around -<a href="https://github.com/kumar303/mohawk">mohawk</a> to add hawk support to the -requests&nbsp;lib.</p> -<p>Doing hawk requests in your terminal is now as simple&nbsp;as:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>requests-hawk<span class="w"> </span>httpie -$<span class="w"> </span>http<span class="w"> </span>GET<span class="w"> </span>localhost:5000/registration<span class="w"> </span>--auth-type<span class="o">=</span>hawk<span class="w"> </span>--auth<span class="o">=</span><span class="s1">&#39;id:key&#39;</span> -</code></pre></div> - -<p>In addition, it will help you to craft requests using the requests&nbsp;library:</p> -<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">requests</span> -<span class="kn">from</span> <span class="nn">requests_hawk</span> <span class="kn">import</span> <span class="n">HawkAuth</span> - -<span class="n">hawk_auth</span> <span class="o">=</span> <span class="n">HawkAuth</span><span class="p">(</span> - <span class="n">credentials</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="nb">id</span><span class="p">,</span> <span class="s1">&#39;key&#39;</span><span class="p">:</span> <span class="n">key</span><span class="p">,</span> <span class="s1">&#39;algorithm&#39;</span><span class="p">:</span> <span class="s1">&#39;sha256&#39;</span><span class="p">})</span> - -<span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&quot;/url&quot;</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="n">hawk_auth</span><span class="p">)</span> -</code></pre></div> - -<p>Alternatively, if you don&#8217;t have the token id and key, you can pass the -hawk session token I talked about earlier and the lib will take care of -the derivation for&nbsp;you:</p> -<div class="highlight"><pre><span></span><code><span class="n">hawk_auth</span> <span class="o">=</span> <span class="n">HawkAuth</span><span class="p">(</span> - <span class="n">hawk_session</span><span class="o">=</span><span class="n">resp</span><span class="o">.</span><span class="n">headers</span><span class="p">[</span><span class="s1">&#39;hawk-session-token&#39;</span><span class="p">],</span> - <span class="n">server_url</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">server_url</span> -<span class="p">)</span> -<span class="n">requests</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="s2">&quot;/url&quot;</span><span class="p">,</span> <span class="n">auth</span><span class="o">=</span><span class="n">hawk_auth</span><span class="p">)</span> -</code></pre></div> - -<h2 id="integrate-with-python-pyramid-apps">Integrate with python pyramid&nbsp;apps</h2> -<p>If you&#8217;re writing pyramid applications, you&#8217;ll be happy to learn that -<a href="https://www.rfk.id.au/blog/">Ryan Kelly</a> put together a library that -makes Hawk work as an Authentication provider for them. I&#8217;m chocked how -simple it is to use&nbsp;it.</p> -<p>Here is a demo of how we implemented it for&nbsp;Daybed:</p> -<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">pyramid_hawkauth</span> <span class="kn">import</span> <span class="n">HawkAuthenticationPolicy</span> - -<span class="n">policy</span> <span class="o">=</span> <span class="n">HawkAuthenticationPolicy</span><span class="p">(</span><span class="n">decode_hawk_id</span><span class="o">=</span><span class="n">get_hawk_id</span><span class="p">)</span> -<span class="n">config</span><span class="o">.</span><span class="n">set_authentication_policy</span><span class="p">(</span><span class="n">authn_policy</span><span class="p">)</span> -</code></pre></div> - -<p>The get_hawk_id function is a function that takes a request and a -tokenid and returns a tuple of (token_id,&nbsp;token_key).</p> -<p>How you want to store the tokens and retrieve them is up to you. The -default implementation (e.g. if you don&#8217;t pass a decode_hawk_id -function) decodes the key from the token itself, using a master secret -on the server (so you don&#8217;t need to store&nbsp;anything).</p> -<h2 id="integrate-with-nodejs-express-apps">Integrate with node.js Express&nbsp;apps</h2> -<p>We had to implement Hawk authentication for two node.js projects and -finally came up factorizing everything in a library for express, named -<a href="https://github.com/mozilla-services/express-hawkauth">express-hawkauth</a>.</p> -<p>In order to plug it in your application, you&#8217;ll need to use it as a&nbsp;middleware:</p> -<div class="highlight"><pre><span></span><code><span class="n">javascript</span> -<span class="k">var</span><span class="w"> </span><span class="n">express</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">require</span><span class="p">(</span><span class="s2">&quot;express&quot;</span><span class="p">);</span> -<span class="k">var</span><span class="w"> </span><span class="n">hawk</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">require</span><span class="p">(</span><span class="s2">&quot;express-hawkauth&quot;</span><span class="p">);</span> -<span class="n">app</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">express</span><span class="p">();</span> - -<span class="k">var</span><span class="w"> </span><span class="n">hawkMiddleware</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hawk</span><span class="o">.</span><span class="n">getMiddleware</span><span class="p">({</span> -<span class="w"> </span><span class="n">hawkOptions</span><span class="p">:</span><span class="w"> </span><span class="p">{},</span> -<span class="w"> </span><span class="n">getSession</span><span class="p">:</span><span class="w"> </span><span class="n">function</span><span class="p">(</span><span class="n">tokenId</span><span class="p">,</span><span class="w"> </span><span class="n">cb</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">function</span><span class="w"> </span><span class="n">which</span><span class="w"> </span><span class="k">pass</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">cb</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">key</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">algorithm</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">given</span><span class="w"> </span><span class="n">token</span><span class="w"> </span><span class="n">id</span><span class="o">.</span><span class="w"> </span><span class="n">First</span><span class="w"> </span><span class="n">argument</span><span class="w"> </span><span class="n">of</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">callback</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">potential</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">error</span><span class="o">.</span> -<span class="w"> </span><span class="n">cb</span><span class="p">(</span><span class="nb nb-Type">null</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="n">key</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;key&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">algorithm</span><span class="p">:</span><span class="w"> </span><span class="s2">&quot;sha256&quot;</span><span class="p">});</span> -<span class="w"> </span><span class="p">},</span> -<span class="w"> </span><span class="n">createSession</span><span class="p">:</span><span class="w"> </span><span class="n">function</span><span class="p">(</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">key</span><span class="p">,</span><span class="w"> </span><span class="n">cb</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">function</span><span class="w"> </span><span class="n">which</span><span class="w"> </span><span class="n">stores</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">session</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">given</span><span class="w"> </span><span class="n">id</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">key</span><span class="o">.</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">Argument</span><span class="w"> </span><span class="n">returned</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">potential</span><span class="w"> </span><span class="n">error</span><span class="o">.</span> -<span class="w"> </span><span class="n">cb</span><span class="p">(</span><span class="nb nb-Type">null</span><span class="p">);</span> -<span class="w"> </span><span class="p">},</span> -<span class="w"> </span><span class="n">setUser</span><span class="p">:</span><span class="w"> </span><span class="n">function</span><span class="p">(</span><span class="n">req</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">tokenId</span><span class="p">,</span><span class="w"> </span><span class="n">cb</span><span class="p">)</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">A</span><span class="w"> </span><span class="n">function</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">uses</span><span class="w"> </span><span class="n">req</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">hawkId</span><span class="w"> </span><span class="n">when</span><span class="w"> </span><span class="n">they</span><span class="s1">&#39;re known so</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">that</span><span class="w"> </span><span class="n">it</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">tweak</span><span class="w"> </span><span class="n">it</span><span class="o">.</span><span class="w"> </span><span class="n">For</span><span class="w"> </span><span class="n">instance</span><span class="p">,</span><span class="w"> </span><span class="n">you</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">store</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">tokenId</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">the</span> -<span class="w"> </span><span class="o">//</span><span class="w"> </span><span class="n">user</span><span class="o">.</span> -<span class="w"> </span><span class="n">req</span><span class="o">.</span><span class="n">user</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tokenId</span><span class="p">;</span> -<span class="w"> </span><span class="p">}</span> -<span class="p">});</span> - -<span class="n">app</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;/hawk-enabled-endpoint&quot;</span><span class="p">,</span><span class="w"> </span><span class="n">hawkMiddleware</span><span class="p">);</span> -</code></pre></div> - -<p>If you pass the createSession parameter, all non-authenticated requests -will create a new hawk session and return it with the response, in the -Hawk-Session-Token&nbsp;header.</p> -<p>If you want to only check a valid hawk session exists (without creating -a new one), just create a middleware which doesn&#8217;t have any -createSession parameter&nbsp;defined.</p> -<h2 id="some-reference-implementations">Some reference&nbsp;implementations</h2> -<p>As a reference, here is how we&#8217;re using the libraries I&#8217;m talking about, -in case that helps you to integrate with your&nbsp;projects.</p> -<ul> -<li>The Mozilla Loop server <a href="https://github.com/mozilla-services/loop-server/blob/master/loop/index.js#L70-L133">uses hawk as authentication once you&#8217;re - logged in with a valid BrowserID - assertion</a>; - request, to keep a session between client and&nbsp;server;</li> -<li><a href="https://github.com/spiral-project/daybed/commit/f178b4e43015fa077430798dcd3d0886c7611caf">I recently added hawk support on the Daybed - project</a> - (that&#8217;s a pyramid / cornice)&nbsp;app.</li> -<li>It&#8217;s also interesting to note that Kumar put together <a href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for - the django rest&nbsp;framework</a></li> -</ul>Implementing CORS in Cornice2013-02-04T00:00:00+01:002013-02-04T00:00:00+01:00tag:blog.notmyidea.org,2013-02-04:/implementing-cors-in-cornice.html -<div class="note"> - -<div class="admonition-title"> - -Note - -</div> - -I&#8217;m cross-posting [on the mozilla services -weblog](https://blog.mozilla.org/services/). Since this is the first -time we&#8217;re doing that, I though it could be useful to point you there. -Check it out and expect more technical articles there in the future. - -</div> - -<p>For security reasons, it …</p> -<div class="note"> - -<div class="admonition-title"> - -Note - -</div> - -I&#8217;m cross-posting [on the mozilla services -weblog](https://blog.mozilla.org/services/). Since this is the first -time we&#8217;re doing that, I though it could be useful to point you there. -Check it out and expect more technical articles there in the future. - -</div> - -<p>For security reasons, it&#8217;s not possible to do cross-domain requests. In -other words, if you have a page served from the domain lolnet.org, it -will not be possible for it to get data from&nbsp;notmyidea.org.</p> -<p>Well, it&#8217;s possible, using tricks and techniques like -<a href="http://en.wikipedia.org/wiki/JSONP"><span class="caps">JSONP</span></a>, but that doesn&#8217;t work all -the time (see <a href="#how-this-is-different-from-jsonp">the section below</a>). I -remember myself doing some simple proxies on my domain server to be able -to query other&#8217;s <span class="caps">API</span>.</p> -<p>Thankfully, there is a nicer way to do this, namely, &#8220;Cross Origin -Resource-Sharing&#8221;, or <a href="http://www.w3.org/TR/cors/"><span class="caps">CORS</span></a>.</p> -<h2 id="you-want-an-icecream-go-ask-your-dad-first">You want an icecream? Go ask your dad&nbsp;first.</h2> -<p>If you want to use <span class="caps">CORS</span>, you need the <span class="caps">API</span> you&#8217;re querying to support it; -on the server&nbsp;side.</p> -<p>The <span class="caps">HTTP</span> server need to answer to the <span class="caps">OPTIONS</span> verb, and with the -appropriate response&nbsp;headers.</p> -<p><span class="caps">OPTIONS</span> is sent as what the authors of the spec call a &#8220;preflight -request&#8221;; just before doing a request to the <span class="caps">API</span>, the <em>User-Agent</em> (the -browser most of the time) asks the permission to the resource, with an -<span class="caps">OPTIONS</span>&nbsp;call.</p> -<p>The server answers, and tell what is available and what&nbsp;isn&#8217;t:</p> -<p><img alt="The CORS flow (from the HTML5 CORS tutorial)" src="/images/cors_flow.png"></p> -<ul> -<li> -<p>1a. The User-Agent, rather than doing the call directly, asks the - server, the <span class="caps">API</span>, the permission to do the request. It does so with - the following&nbsp;headers:</p> -<ul> -<li><strong>Access-Control-Request-Headers</strong>, contains the headers the - User-Agent want to&nbsp;access.</li> -<li><strong>Access-Control-Request-Method</strong> contains the method the - User-Agent want to&nbsp;access.</li> -</ul> -</li> -<li> -<p>1b. The <span class="caps">API</span> answers what is&nbsp;authorized:</p> -<ul> -<li><strong>Access-Control-Allow-Origin</strong> the origin that&#8217;s accepted. Can - be * or the domain&nbsp;name.</li> -<li><strong>Access-Control-Allow-Methods</strong> a <em>list</em> of allowed methods. - This can be cached. Note than the request asks permission for - one method and the server should return a list of accepted&nbsp;methods.</li> -<li><strong>Access-Allow-Headers</strong> a list of allowed headers, for all of - the methods, since this can be cached as&nbsp;well.</li> -</ul> -</li> -<li> -<ol> -<li>The User-Agent can do the &#8220;normal&#8221;&nbsp;request.</li> -</ol> -</li> -</ul> -<p>So, if you want to access the /icecream resource, and do a <span class="caps">PUT</span> there, -you&#8217;ll have the following&nbsp;flow:</p> -<div class="highlight"><pre><span></span><code>&gt; OPTIONS /icecream -&gt; Access-Control-Request-Methods = PUT -&gt; Origin: notmyidea.org -&lt; Access-Control-Allow-Origin = notmyidea.org -&lt; Access-Control-Allow-Methods = PUT,GET,DELETE -200 OK -</code></pre></div> - -<p>You can see that we have an Origin Header in the request, as well as a -Access-Control-Request-Methods. We&#8217;re here asking if we have the right, -as notmyidea.org, to do a <span class="caps">PUT</span> request on&nbsp;/icecream.</p> -<p>And the server tells us that we can do that, as well as <span class="caps">GET</span> and <span class="caps">DELETE</span>.</p> -<p>I&#8217;ll not cover all the details of the <span class="caps">CORS</span> specification here, but bear -in mind than with <span class="caps">CORS</span>, you can control what are the authorized methods, -headers, origins, and if the client is allowed to send authentication -information or&nbsp;not.</p> -<h2 id="a-word-about-security">A word about&nbsp;security</h2> -<p><span class="caps">CORS</span> is not an answer for every cross-domain call you want to do, -because you need to control the service you want to call. For instance, -if you want to build a feed reader and access the feeds on different -domains, you can be pretty much sure that the servers will not implement -<span class="caps">CORS</span>, so you&#8217;ll need to write a proxy yourself, to provide&nbsp;this.</p> -<p>Secondly, if misunderstood, <span class="caps">CORS</span> can be insecure, and cause problems. -Because the rules apply when a client wants to do a request to a server, -you need to be extra careful about who you&#8217;re&nbsp;authorizing.</p> -<p>An incorrectly secured <span class="caps">CORS</span> server can be accessed by a malicious client -very easily, bypassing network security. For instance, if you host a -server on an intranet that is only available from behind a <span class="caps">VPN</span> but -accepts every cross-origin call. A bad guy can inject javascript into -the browser of a user who has access to your protected server and make -calls to your service, which is probably not what you&nbsp;want.</p> -<h2 id="how-this-is-different-from-jsonp">How this is different from <span class="caps">JSONP</span>?</h2> -<p>You may know the <a href="http://en.wikipedia.org/wiki/JSONP"><span class="caps">JSONP</span></a> protocol. -<span class="caps">JSONP</span> allows cross origin, but for a particular use case, and does have -some drawbacks (for instance, it&#8217;s not possible to do DELETEs or PUTs -with <span class="caps">JSONP</span>).</p> -<p><span class="caps">JSONP</span> exploits the fact that it is possible to get information from -another domain when you are asking for javascript code, using the -\&lt;script&gt;&nbsp;element.</p> -<blockquote> -<p>Exploiting the open policy for \&lt;script&gt; elements, some pages use -them to retrieve JavaScript code that operates on dynamically -generated <span class="caps">JSON</span>-formatted data from other origins. This usage pattern -is known as <span class="caps">JSONP</span>. Requests for <span class="caps">JSONP</span> retrieve not <span class="caps">JSON</span>, but arbitrary -JavaScript code. They are evaluated by the JavaScript interpreter, not -parsed by a <span class="caps">JSON</span>&nbsp;parser.</p> -</blockquote> -<h2 id="using-cors-in-cornice">Using <span class="caps">CORS</span> in&nbsp;Cornice</h2> -<p>Okay, things are hopefully clearer about <span class="caps">CORS</span>, let&#8217;s see how we -implemented it on the&nbsp;server-side.</p> -<p>Cornice is a toolkit that lets you define resources in python and takes -care of the heavy lifting for you, so I wanted it to take care of the -<span class="caps">CORS</span> support as&nbsp;well.</p> -<p>In Cornice, you define a service like&nbsp;this:</p> -<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">cornice</span> <span class="kn">import</span> <span class="n">Service</span> - -<span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;foobar&quot;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s2">&quot;/foobar&quot;</span><span class="p">)</span> - -<span class="c1"># and then you do something with it</span> -<span class="nd">@foobar</span><span class="o">.</span><span class="n">get</span><span class="p">()</span> -<span class="k">def</span> <span class="nf">get_foobar</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="c1"># do something with the request.</span> -</code></pre></div> - -<p>To add <span class="caps">CORS</span> support to this resource, you can go this way, with the -cors_origins&nbsp;parameter:</p> -<div class="highlight"><pre><span></span><code><span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;foobar&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/foobar&#39;</span><span class="p">,</span> <span class="n">cors_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> -</code></pre></div> - -<p>Ta-da! You have enabled <span class="caps">CORS</span> for your service. <strong>Be aware that you&#8217;re -authorizing anyone to query your server, that may not be what you&nbsp;want.</strong></p> -<p>Of course, you can specify a list of origins you trust, and you don&#8217;t -need to stick with *, which means &#8220;authorize&nbsp;everyone&#8221;.</p> -<h3 id="headers">Headers</h3> -<p>You can define the headers you want to expose for the&nbsp;service:</p> -<div class="highlight"><pre><span></span><code><span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;foobar&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/foobar&#39;</span><span class="p">,</span> <span class="n">cors_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> - -<span class="nd">@foobar</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">cors_headers</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;X-My-Header&#39;</span><span class="p">,</span> <span class="s1">&#39;Content-Type&#39;</span><span class="p">))</span> -<span class="k">def</span> <span class="nf">get_foobars_please</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="k">return</span> <span class="s2">&quot;some foobar for you&quot;</span> -</code></pre></div> - -<p>I&#8217;ve done some testing and it wasn&#8217;t working on Chrome because I wasn&#8217;t -handling the headers the right way (The missing one was Content-Type, -that Chrome was asking for). With my first version of the -implementation, I needed the service implementers to explicitely list -all the headers that should be exposed. While this improves security, it -can be frustrating while&nbsp;developing.</p> -<p>So I introduced an expose_all_headers flag, which is set to True by -default, if the service supports <span class="caps">CORS</span>.</p> -<h3 id="cookies-credentials">Cookies /&nbsp;Credentials</h3> -<p>By default, the requests you do to your <span class="caps">API</span> endpoint don&#8217;t include the -credential information for security reasons. If you really want to do -that, you need to enable it using the cors_credentials parameter. You -can activate this one on a per-service basis or on a per-method&nbsp;basis.</p> -<h3 id="caching">Caching</h3> -<p>When you do a preflight request, the information returned by the server -can be cached by the User-Agent so that it&#8217;s not redone before each -actual&nbsp;call.</p> -<p>The caching period is defined by the server, using the -Access-Control-Max-Age header. You can configure this timing using the -cors_max_age&nbsp;parameter.</p> -<h3 id="simplifying-the-api">Simplifying the <span class="caps">API</span></h3> -<p>We have cors_headers, cors_enabled, cors_origins, cors_credentials, -cors_max_age, cors_expose_all_headers … a fair number of -parameters. If you want to have a specific <span class="caps">CORS</span>-policy for your -services, that can be a bit tedious to pass these to your services all -the&nbsp;time.</p> -<p>I introduced another way to pass the <span class="caps">CORS</span> policy, so you can do -something like&nbsp;that:</p> -<div class="highlight"><pre><span></span><code><span class="n">policy</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="n">enabled</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> - <span class="n">headers</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;X-My-Header&#39;</span><span class="p">,</span> <span class="s1">&#39;Content-Type&#39;</span><span class="p">),</span> - <span class="n">origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*.notmyidea.org&#39;</span><span class="p">),</span> - <span class="n">credentials</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> - <span class="n">max_age</span><span class="o">=</span><span class="mi">42</span><span class="p">)</span> - -<span class="n">foobar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;foobar&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/foobar&#39;</span><span class="p">,</span> <span class="n">cors_policy</span><span class="o">=</span><span class="n">policy</span><span class="p">)</span> -</code></pre></div> - -<h2 id="comparison-with-other-implementations">Comparison with other&nbsp;implementations</h2> -<p>I was curious to have a look at other implementations of <span class="caps">CORS</span>, in django -for instance, and I found <a href="https://gist.github.com/426829.js">a gist about -it</a>.</p> -<p>Basically, this adds a middleware that adds the &#8220;rights&#8221; headers to the -answer, depending on the&nbsp;request.</p> -<p>While this approach works, it&#8217;s not implementing the specification -completely. You need to add support for all the resources at&nbsp;once.</p> -<p>We can think about a nice way to implement this specifying a definition -of what&#8217;s supposed to be exposed via <span class="caps">CORS</span> and what shouldn&#8217;t directly in -your settings. In my opinion, <span class="caps">CORS</span> support should be handled at the -service definition level, except for the list of authorized hosts. -Otherwise, you don&#8217;t know exactly what&#8217;s going on when you look at the -definition of the&nbsp;service.</p> -<h2 id="resources">Resources</h2> -<p>There are a number of good resources that can be useful to you if you -want to either understand how <span class="caps">CORS</span> works, or if you want to implement it&nbsp;yourself.</p> -<ul> -<li><a href="http://enable-cors.org/">http://enable-cors.org/</a> is useful to get started when you don&#8217;t - know anything about <span class="caps">CORS</span>.</li> -<li>There is a <span class="caps">W3C</span> wiki page containing information that may be useful - about clients, common pitfalls etc: - <a href="http://www.w3.org/wiki/CORS_Enabled">http://www.w3.org/wiki/CORS_Enabled</a></li> -<li><em><span class="caps">HTML5</span> rocks</em> has a tutorial explaining how to implement <span class="caps">CORS</span>, with - <a href="http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server">a nice section about the - server-side</a>.</li> -<li>Be sure to have a look at the <a href="http://caniuse.com/#search=cors">clients support-matrix for this - feature</a>.</li> -<li>About security, <a href="https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity">check out this&nbsp;page</a></li> -<li>If you want to have a look at the implementation code, check <a href="https://github.com/mozilla-services/cornice/pull/98/files">on&nbsp;github</a></li> -</ul> -<p>Of course, the <span class="caps">W3C</span> specification is the best resource to rely on. This -specification isn&#8217;t hard to read, so you may want to go through it. -Especially the <a href="http://www.w3.org/TR/cors/#resource-processing-model">&#8220;resource processing model&#8221;&nbsp;section</a></p>Status board2012-12-29T00:00:00+01:002012-12-29T00:00:00+01:00tag:blog.notmyidea.org,2012-12-29:/status-board.html -<p>À force de démarrer des services web pour un oui et pour un non, de -proposer à des copains d&#8217;héberger leurs sites, de faire pareil pour -quelques assos etc, je me suis retrouvé avec, comme dirait l&#8217;autre, <em>une -bonne platrée</em> de sites et de services à gérer sur …</p> -<p>À force de démarrer des services web pour un oui et pour un non, de -proposer à des copains d&#8217;héberger leurs sites, de faire pareil pour -quelques assos etc, je me suis retrouvé avec, comme dirait l&#8217;autre, <em>une -bonne platrée</em> de sites et de services à gérer sur lolnet.org, mon&nbsp;serveur.</p> -<p>Jusqu&#8217;à très récemment, rien de tout ça n&#8217;était sauvegardé, et non plus -monitoré. Après quelques recherches, je suis tombé sur -<a href="http://www.stashboard.org/">stashboard</a>, un &#8220;status board&#8221; qu&#8217;il est -bien fait. Le seul problème, c&#8217;est écrit pour se lancer sur <span class="caps">GAE</span>, <em>Google -App Engine</em>. Heureusement, c&#8217;est open-source, et ça a été forké pour -donner naissance à -<a href="https://github.com/bfirsh/whiskerboard">whiskerboard</a> (la planche -moustachue, pour les non&nbsp;anglophones).</p> -<p><img alt="Capture d'écran du site." src="/images/status_board.png"></p> -<h2 id="verifier-le-statut-des-services">Vérifier le statut des&nbsp;services</h2> -<p>Donc, c&#8217;est chouette, c&#8217;est facile à installer, tout ça, mais… mais ça ne fait en fait pas ce que je veux: ça ne fait que m&#8217;afficher le statut des services, mais ça ne vérifie pas que tout est bien&nbsp;&#8220;up&#8221;.</p> -<p>Bon, un peu embêtant pour moi, parce que c&#8217;est vraiment ça que je voulais. Pas grave, je sais un peu coder, autant que ça serve. J&#8217;ai ajouté quelques fonctionnalités au soft, qui sont disponibles sur mon fork, sur github:: <a href="https://github.com/almet/whiskerboard">https://github.com/almet/whiskerboard</a>&nbsp;.</p> -<p>Entres autres, il est désormais possible de lancer -<a href="http://celeryproject.org/">celery</a> en tache de fond et de vérifier périodiquement que les services sont toujours bien vivants, en utilisant une tache&nbsp;spécifique.</p> -<p>C&#8217;était un bonheur de développer ça (on a fait ça à deux, avec guillaume, avec un mumble + tmux en pair prog, en une petite soirée, ça&nbsp;dépote).</p> -<p>Les modifications sont assez simples, vous pouvez aller jeter un œil aux changements ici: -<a href="https://github.com/almet/whiskerboard/compare/b539337416...master">https://github.com/almet/whiskerboard/compare/b539337416&#8230;master</a></p> -<p>En&nbsp;gros:</p> -<ul> -<li>ajout d&#8217;une connection_string aux services (de la forme&nbsp;protocol://host:port)</li> -<li>ajout d&#8217;une commande check_status qui s&#8217;occupe d&#8217;itérer sur les - services et de lancer des taches celery qui vont bien, en fonction - du&nbsp;protocole</li> -<li>ajout des taches en&nbsp;question</li> -</ul> -<h2 id="deploiement">Déploiement</h2> -<p>Le plus long a été de le déployer en fin de compte, parce que je ne -voulais pas déployer mon service de supervision sur mon serveur,&nbsp;forcément.</p> -<p>Après un essai (plutôt rapide en fait) sur <a href="http://heroku.com">heroku</a>, -je me suis rendu compte qu&#8217;il me fallait payer pas loin de 35$ par mois -pour avoir un process celeryd qui tourne, donc j&#8217;ai un peu cherché -ailleurs, pour finalement déployer la chose chez -<a href="https://www.alwaysdata.com/">alwaysdata</a></p> -<p>Après quelques péripéties, j&#8217;ai réussi à faire tourner le tout, ça à été -un peu la bataille au départ pour installer virtualenv (j&#8217;ai du faire -des changements dans mon <span class="caps">PATH</span> pour que ça puisse marcher), voici mon&nbsp;`.bash_profile`:</p> -<div class="highlight"><pre><span></span><code><span class="k">export</span><span class="w"> </span><span class="n">PYTHONPATH</span><span class="o">=~/</span><span class="n">modules</span><span class="o">/</span> -<span class="k">export</span><span class="w"> </span><span class="n">PATH</span><span class="o">=$</span><span class="n">HOME</span><span class="o">/</span><span class="n">modules</span><span class="o">/</span><span class="n">bin</span><span class="p">:</span><span class="o">$</span><span class="n">HOME</span><span class="o">/</span><span class="n">modules</span><span class="o">/</span><span class="p">:</span><span class="o">$</span><span class="n">PATH</span> -</code></pre></div> - -<p>Et après y&#8217;a plus qu&#8217;à installer avec&nbsp;`easy_install`:</p> -<div class="highlight"><pre><span></span><code>easy_install --install-dir ~/modules -U pip -easy_install --install-dir ~/modules -U virtualenv -</code></pre></div> - -<p>Et à créer le&nbsp;virtualenv:</p> -<div class="highlight"><pre><span></span><code>virtualenv venv -venv/bin/pip install -r requirements.txt -</code></pre></div> - -<p>Dernière étape, la création d&#8217;un fichier application.wsgi qui s&#8217;occupe -de rendre l&#8217;application disponible, avec le bon&nbsp;venv:</p> -<h2 id="ssl-et-requests"><span class="caps">SSL</span> et&nbsp;Requests</h2> -<p>Quelques tours de manivelle plus loin, j&#8217;ai un celeryd qui tourne et qui -consomme les taches qui lui sont envoyées (pour des questions de -simplicité, j&#8217;ai utilisé le backend django de celery, donc pas besoin -d&#8217;<span class="caps">AMQP</span>, par&nbsp;exemple).</p> -<p>Problème, les ressources que je vérifie en <span class="caps">SSL</span> (<span class="caps">HTTPS</span>) me jettent. Je -sais pas exactement pourquoi à l&#8217;heure qu&#8217;il est, mais il semble que -lorsque je fais une requête avec -<a href="http://docs.python-requests.org/en/latest/">Requests</a> je me récupère -des <em>Connection Refused</em>. Peut être une sombre histoire de proxy ? En -attendant, les appels avec <span class="caps">CURL</span> fonctionnent, donc j&#8217;ai fait <a href="https://github.com/ametaireau/whiskerboard/blob/master/board/tasks.py#L17">un -fallback vers <span class="caps">CURL</span> lorsque les autres méthodes -échouent</a>. -Pas super propre, mais ça&nbsp;fonctionne.</p> -<p><strong><span class="caps">EDIT</span></strong> Finalement, il se trouve que mon serveur était mal configuré. -J&#8217;utilisais haproxy + stunnel, et la négiciation <span class="caps">SSL</span> se passait mal. Une -fois <span class="caps">SSL</span> et <span class="caps">TLS</span> activés, et SSLv2 désactivé, tout fonctionne&nbsp;mieux.</p> -<h2 id="et-voila">Et&nbsp;voilà</h2> -<p>Finalement, j&#8217;ai mon joli status-board qui tourne à merveille sur -<a href="http://status.lolnet.org">http://status.lolnet.org</a>&nbsp;:-)</p>Astuces SSH2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/astuces-ssh.html -<h2 id="tunelling">Tunelling</h2> -<p>Parce que je m&#8217;en rapelle jamais (tête de&nbsp;linote):</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>-f<span class="w"> </span>hote<span class="w"> </span>-L<span class="w"> </span>local:lolnet.org:destination<span class="w"> </span>-N -</code></pre></div> - -<h2 id="sshconfig">.ssh/config</h2> -<p>(merci <a href="http://majerti.fr">gaston</a>&nbsp;!)</p> -<p>La directive suivante dans .ssh/config permet de sauter d&#8217;hôte en hôte -séparés par des &#8220;+&#8221;&nbsp;:</p> -<div class="highlight"><pre><span></span><code>Host *+* - ProxyCommand ssh $(echo %h | sed -&#39;s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l …</code></pre></div> -<h2 id="tunelling">Tunelling</h2> -<p>Parce que je m&#8217;en rapelle jamais (tête de&nbsp;linote):</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>-f<span class="w"> </span>hote<span class="w"> </span>-L<span class="w"> </span>local:lolnet.org:destination<span class="w"> </span>-N -</code></pre></div> - -<h2 id="sshconfig">.ssh/config</h2> -<p>(merci <a href="http://majerti.fr">gaston</a>&nbsp;!)</p> -<p>La directive suivante dans .ssh/config permet de sauter d&#8217;hôte en hôte -séparés par des &#8220;+&#8221;&nbsp;:</p> -<div class="highlight"><pre><span></span><code>Host *+* - ProxyCommand ssh $(echo %h | sed -&#39;s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /&#39;) -PATH=.:\$PATH nc -w1 $(echo %h | sed &#39;s/^.*+//;/:/!s/$/ %p/;s/:/ /&#39;) -</code></pre></div> - -<p>On peut donc spécifier des &#8220;sauts&#8221; ssh du&nbsp;style:</p> -<div class="highlight"><pre><span></span><code><span class="n">ssh</span><span class="w"> </span><span class="n">root</span><span class="mf">@91.25.25.25</span><span class="o">+</span><span class="mf">192.168.1.1</span> -</code></pre></div> - -<p>Ensuite on peut essayer de&nbsp;rajouter:</p> -<div class="highlight"><pre><span></span><code>Host &lt;label_pour_mon_serveur_privé&gt; - user &lt;monuser(root)&gt; - IdentityFile &lt;chemin vers ma clé ssh pour le serveur publique&gt; - hostname ip_serveur_publique+ip_serveur_privé -</code></pre></div>Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.html -<p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut -de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de -regarder du coté de gnome 3, à&nbsp;nouveau.</p> -<p>Et finalement, j&#8217;ai trouvé quelques extensions qui sont vraiment utiles, -que je …</p> -<p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut -de ubuntu, j&#8217;ai eu envie de changements, et j&#8217;ai donc essayé un peu de -regarder du coté de gnome 3, à&nbsp;nouveau.</p> -<p>Et finalement, j&#8217;ai trouvé quelques extensions qui sont vraiment utiles, -que je liste&nbsp;ici.</p> -<ul> -<li><a href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial - Menu</a> - vire les boutons et textes en rapport avec le web social. J&#8217;en avais - pas besoin puisque je suis connecté à mon instant messenger dans un - terminal, en utilisant&nbsp;weechat.</li> -<li><a href="https://extensions.gnome.org/extension/97/coverflow-alt-tab/">Coverflow - Alt-Tab</a> - change le switcher d&#8217;applications par defaut. Je le trouve bien plus - pratique que celui par defaut puisqu&#8217;il me permet de voir &#8220;en grand&#8221; - quelle est la fenêtre que je vais&nbsp;afficher.</li> -<li><a href="https://extensions.gnome.org/extension/55/media-player-indicator/">Media player - indicator</a> - me permet de voir en temps réel ce qui se passe dans mon lecteur - audio. Ça semble ne pas être grand chose, mais ça me manquait. Ça - s&#8217;intègre niquel avec Spotify, et ça c&#8217;est&nbsp;chouette.</li> -<li><a href="https://extensions.gnome.org/extension/149/search-firefox-bookmarks-provider/">Rechercher dans les bookmarks - firefox</a> - permet de… à votre avis&nbsp;?</li> -</ul> -<p>Un peu moins utile mais sait on&nbsp;jamais:</p> -<ul> -<li>“<a href="https://extensions.gnome.org/extension/130/advanced-settings-in-usermenu/">Advanced Settings in - UserMenu</a>” - permet d&#8217;avoir un raccourci vers les paramètres avancés dans le menu - utilisateur (en haut à&nbsp;droite)</li> -<li>Une <a href="https://extensions.gnome.org/extension/409/gtg-integration/">intégration à Getting things - Gnome</a> - (un truc de <span class="caps">GTD</span>). Je suis en train d&#8217;expérimenter avec cet outil, - donc je ne sais pas encore si ça va rester, mais pourquoi&nbsp;pas.</li> -</ul> -<p>Vous pouvez aller faire un tour sur <a href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> pour -en trouver d&#8217;autres à votre&nbsp;gout.</p>Cheese & code - Wrap-up2012-10-22T00:00:00+02:002012-10-22T00:00:00+02:00tag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.html -<p>This week-end I hosted a <em>cheese <span class="amp">&amp;</span> code</em> session in the country-side of -Angers,&nbsp;France.</p> -<p>We were a bunch of python hackers and it rained a lot, wich forced us to -stay inside and to code.&nbsp;Bad.</p> -<p>We were not enough to get rid of all the cheese and the awesome …</p> -<p>This week-end I hosted a <em>cheese <span class="amp">&amp;</span> code</em> session in the country-side of -Angers,&nbsp;France.</p> -<p>We were a bunch of python hackers and it rained a lot, wich forced us to -stay inside and to code.&nbsp;Bad.</p> -<p>We were not enough to get rid of all the cheese and the awesome meals, -but well, we finally managed it pretty&nbsp;well.</p> -<p>Here is a summary of what we worked&nbsp;on:</p> -<h2 id="daybed">Daybed</h2> -<p>Daybed started some time ago, and intend to be a replacement to google -forms, in term of features, but backed as a <span class="caps">REST</span> web service, in python, -and open&nbsp;source.</p> -<p>In case you wonder, daybed is effectively the name of a couch. We chose -this name because of the similarities (in the sound) with <strong>db</strong>, and -because we&#8217;re using <strong>CouchDB</strong> as a&nbsp;backend.</p> -<p><img alt="Daybed is a big couch!" src="/images/daybed.jpg"></p> -<p>We mainly hacked on daybed and are pretty close to the release of the -first version, meaning that we have something&nbsp;working.</p> -<p><a href="http://github.com/spiral-project/daybed">The code</a> is available on -github, and we also wrote <a href="http://daybed.rtfd.org">a small -documentation</a> for&nbsp;it.</p> -<p>Mainly, we did a lot of cleanup, rewrote a bunch of tests so that it -would be easier to continue to work on the project, and implemented some -minor features. I&#8217;m pretty confidend that we now have really good basis -for this&nbsp;project.</p> -<p>Also, we will have a nice todolist application, with the backend <strong>and</strong> -the frontend, in javascript / html / css, you&#8217;ll know more when it&#8217;ll be -ready&nbsp;:-)</p> -<p>Once we have something good enough, we&#8217;ll release the first version and -I&#8217;ll host it somewhere so that people can play with&nbsp;it.</p> -<h2 id="cornice">Cornice</h2> -<p>Daybed is built on top of <a href="http://cornice.rtfd.org">Cornice</a>, a -framework to ease the creation of&nbsp;web-services.</p> -<p>At Pycon France, we had the opportunity to attend a good presentation -about <a href="https://github.com/SPORE/specifications"><span class="caps">SPORE</span></a>. <span class="caps">SPORE</span> is a way -to describe your <span class="caps">REST</span> web services, as <span class="caps">WSDL</span> is for <span class="caps">WS</span>-* services. This -allows to ease the creation of generic <span class="caps">SPORE</span> clients, which are able to -consume any <span class="caps">REST</span> <span class="caps">API</span> with a <span class="caps">SPORE</span>&nbsp;endpoint.</p> -<p>Here is how you can let cornice describe your web service for&nbsp;you</p> -<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">cornice.ext.spore</span> <span class="kn">import</span> <span class="n">generate_spore_description</span> -<span class="kn">from</span> <span class="nn">cornice.service</span> <span class="kn">import</span> <span class="n">Service</span><span class="p">,</span> <span class="n">get_services</span> - -<span class="n">spore</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="s1">&#39;spore&#39;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s1">&#39;/spore&#39;</span><span class="p">,</span> <span class="n">renderer</span><span class="o">=</span><span class="s1">&#39;jsonp&#39;</span><span class="p">)</span> -<span class="nd">@spore</span><span class="o">.</span><span class="n">get</span> -<span class="k">def</span> <span class="nf">get_spore</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="n">services</span> <span class="o">=</span> <span class="n">get_services</span><span class="p">()</span> - <span class="k">return</span> <span class="n">generate_spore_description</span><span class="p">(</span><span class="n">services</span><span class="p">,</span> <span class="s1">&#39;Service name&#39;</span><span class="p">,</span> - <span class="n">request</span><span class="o">.</span><span class="n">application_url</span><span class="p">,</span> <span class="s1">&#39;1.0&#39;</span><span class="p">)</span> -</code></pre></div> - -<p>And you&#8217;ll get a definition of your service, in <span class="caps">SPORE</span>, available at&nbsp;/spore.</p> -<p>Of course, you can use it to do other things, like generating the file -locally and exporting it wherever it makes sense to you,&nbsp;etc.</p> -<p>I released today <a href="http://crate.io/packages/cornice/">Cornice 0.11</a>, -which adds into other things the support for <span class="caps">SPORE</span>, plus some other -fixes we found on our&nbsp;way.</p> -<h2 id="respire">Respire</h2> -<p>Once you have the description of the service, you can do generic clients -consuming&nbsp;them!</p> -<p>We first wanted to contribute to <a href="https://github.com/bl0b/spyre">spyre</a> -but it was written in a way that wasn&#8217;t supporting to <span class="caps">POST</span> data, and -they were using their own stack to handle <span class="caps">HTTP</span>. A lot of code that -already exists in other&nbsp;libraries.</p> -<p>While waiting the train with <a href="http://natim.ionyse.com/">Rémy</a>, we hacked -something together, named &#8220;Respire&#8221;, a thin layer on top of the awesome -<a href="http://python-requests.org">Requests</a>&nbsp;library.</p> -<p>We have a first version, feel free to have a look at it and provide -enhancements if you feel like it. We&#8217;re still hacking on it so it may -break (for the better), but that had been working pretty well for us so&nbsp;far.</p> -<p>You can <a href="http://github.com/spiral-project/respire">find the project on -github</a>, but here is how to -use it, really quickly (these examples are how to interact with&nbsp;daybed)</p> -<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">respire</span> <span class="kn">import</span> <span class="n">client_from_url</span> - -<span class="o">&gt;&gt;&gt;</span> <span class="c1"># create the client from the SPORE definition</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span> <span class="o">=</span> <span class="n">client_from_url</span><span class="p">(</span><span class="s1">&#39;http://localhost:8000/spore&#39;</span><span class="p">)</span> - -<span class="o">&gt;&gt;&gt;</span> <span class="c1"># in daybed, create a new definition</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">todo_def</span> <span class="o">=</span> <span class="p">{</span> -<span class="o">...</span> <span class="s2">&quot;title&quot;</span><span class="p">:</span> <span class="s2">&quot;todo&quot;</span><span class="p">,</span> -<span class="o">...</span> <span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;A list of my stuff to do&quot;</span><span class="p">,</span> -<span class="o">...</span> <span class="s2">&quot;fields&quot;</span><span class="p">:</span> <span class="p">[</span> -<span class="o">...</span> <span class="p">{</span> -<span class="o">...</span> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;item&quot;</span><span class="p">,</span> -<span class="o">...</span> <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;string&quot;</span><span class="p">,</span> -<span class="o">...</span> <span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;The item&quot;</span> -<span class="o">...</span> <span class="p">},</span> -<span class="o">...</span> <span class="p">{</span> -<span class="o">...</span> <span class="s2">&quot;name&quot;</span><span class="p">:</span> <span class="s2">&quot;status&quot;</span><span class="p">,</span> -<span class="o">...</span> <span class="s2">&quot;type&quot;</span><span class="p">:</span> <span class="s2">&quot;enum&quot;</span><span class="p">,</span> -<span class="o">...</span> <span class="s2">&quot;choices&quot;</span><span class="p">:</span> <span class="p">[</span> -<span class="o">...</span> <span class="s2">&quot;done&quot;</span><span class="p">,</span> -<span class="o">...</span> <span class="s2">&quot;todo&quot;</span> -<span class="o">...</span> <span class="p">],</span> -<span class="o">...</span> <span class="s2">&quot;description&quot;</span><span class="p">:</span> <span class="s2">&quot;is it done or not&quot;</span> -<span class="o">...</span> <span class="p">}</span> -<span class="o">...</span> <span class="p">]}</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span><span class="o">.</span><span class="n">put_definition</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">todo_def</span><span class="p">)</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span><span class="o">.</span><span class="n">post_data</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="nb">dict</span><span class="p">(</span><span class="n">item</span><span class="o">=</span><span class="s1">&#39;make it work&#39;</span><span class="p">,</span> <span class="n">status</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">))</span> -<span class="p">{</span><span class="sa">u</span><span class="s1">&#39;id&#39;</span><span class="p">:</span> <span class="sa">u</span><span class="s1">&#39;9f2c90c0529a442cfdc03c191b022cf7&#39;</span><span class="p">}</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">cl</span><span class="o">.</span><span class="n">get_data</span><span class="p">(</span><span class="n">model_name</span><span class="o">=</span><span class="s1">&#39;todo&#39;</span><span class="p">)</span> -</code></pre></div> - -<p>Finally, we were out of cheese so everyone headed back to their -respective houses and&nbsp;cities.</p> -<p>Until next&nbsp;time?</p>Circus sprint at PyconFR2012-09-17T00:00:00+02:002012-09-17T00:00:00+02:00tag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.html -<p>Last Thursday to Sunday, <a href="http://pycon.fr">Pycon France</a> took place, in -Paris. It was the opportunity to meet a lot of people and to talk about -python awesomness in&nbsp;general.</p> -<p>We had three tracks this year, plus sprints the two first days. We -sprinted on <a href="http://circus.io">Circus</a>, the process and socket manager -we …</p> -<p>Last Thursday to Sunday, <a href="http://pycon.fr">Pycon France</a> took place, in -Paris. It was the opportunity to meet a lot of people and to talk about -python awesomness in&nbsp;general.</p> -<p>We had three tracks this year, plus sprints the two first days. We -sprinted on <a href="http://circus.io">Circus</a>, the process and socket manager -we&#8217;re using at Mozilla for some of our&nbsp;setups.</p> -<p>The project gathered some interest, and we ended up with 5 persons -working on it. Of course, we spent some time explaining what is Circus, -how it had been built, a lot of time talking about use-cases and -possible improvements, but we also managed to add new&nbsp;features.</p> -<p>Having people wanting to sprint on our projects is exciting because -that&#8217;s when making things in the open unleashes its full potential. You -can&#8217;t imagine how happy I was to have some friends come and work on this -with us&nbsp;:)</p> -<p>Here is a wrap-up of the&nbsp;sprint:</p> -<h2 id="autocompletion-on-the-command-line">Autocompletion on the&nbsp;command-line</h2> -<p><a href="http://natim.ionyse.com">Remy Hubscher</a> worked on the command-line -autocompletion. Now we have a fancy command-line interface which is able -to aucomplete if you&#8217;re using bash. It seems that not that much work is -needed to make it happen on zsh as well&nbsp;:)</p> -<p><a href="https://github.com/mozilla-services/circus/blob/master/extras/circusctl_bash_completion">Have a look at the&nbsp;feature</a></p> -<p>On the same topic, we now have a cool shell for Circus. If you start the -circusctl command without any option, you&#8217;ll end-up with a cool shell. -Thanks <a href="https://github.com/jojax">Jonathan Dorival</a> for the work on -this! You can have a look at <a href="https://github.com/mozilla-services/circus/pull/268">the pull -request</a>.</p> -<h2 id="future-changes-to-the-web-ui">Future changes to the web&nbsp;ui</h2> -<p><a href="https://twitter.com/rachbelaid">Rachid Belaid</a> had a deep look at the -source code and is much more familiarized to it now than before. We -discussed the possibility to change the implementation of the web ui, -and I&#8217;m glad of this. Currently, it&#8217;s done with bottle.py and we want to -switch to&nbsp;pyramid.</p> -<p>He fixed some issues that were in the tracker, so we now can have the -age of watchers in the webui, for&nbsp;instance.</p> -<h2 id="bug-and-doc-fixing">Bug and doc&nbsp;fixing</h2> -<p>While reading the source code, we found some inconsistencies and fixed -them, with <a href="http://mathieu.agopian.info/">Mathieu Agopian</a>. We also -tried to improve the documentation at different&nbsp;levels.</p> -<p>Documentation still needs a lot of love, and I&#8217;m planning to spend some -time on this shortly. I&#8217;ve gathered a bunch of feedback on&nbsp;this</p> -<h2 id="circus-clustering-capabilities">Circus clustering&nbsp;capabilities</h2> -<p>One feature I wanted to work on during this sprint was the clustering -abilities of Circus. Nick Pellegrino made an internship on this topic at -Mozilla so we spent some time to review his pull&nbsp;requests.</p> -<p>A lot of code was written for this so we discussed a bunch of things -regarding all of this. It took us more time than expected (and I still -need to spend more time on this to provide appropriate feedback), but it -allowed us to have a starting-point about what this clustering thing -could&nbsp;be.</p> -<p>Remy wrote <a href="http://tech.novapost.fr/circus-clustering-management-en.html">a good summary about our -brainstorming</a> -so I&#8217;ll not do it again here, but feel free to contact us if you have -ideas on this, they&#8217;re very&nbsp;welcome!</p> -<h2 id="project-management">Project&nbsp;management</h2> -<p>We&#8217;ve had some inquiries telling us that&#8217;s not as easy as it should to -get started with the Circus project. Some of the reasons are that we -don&#8217;t have any release schedule, and that the documentation is hairy -enough to lost people, at some point&nbsp;:)</p> -<p>That&#8217;s something we&#8217;ll try to fix soon&nbsp;:)</p> -<p>PyconFR was a very enjoyable event. I&#8217;m looking forward to meet the -community again and discuss how Circus can evolve in ways that are -interesting to&nbsp;everyone.</p> -<p>Tarek and me are going to <a href="http://python.ie/pycon/2012/">Pycon ireland</a>, -feel free to reach us if you&#8217;re going there, we&#8217;ll be happy to meet and -enjoy&nbsp;beers!</p>Refactoring Cornice2012-05-01T00:00:00+02:002012-05-01T00:00:00+02:00tag:blog.notmyidea.org,2012-05-01:/refactoring-cornice.html -<p>After working for a while with <a href="http://cornice.readthedocs.com">Cornice</a> -to define our APIs at <a href="http://docs.services.mozilla.com">Services</a>, it -turned out that the current implementation wasn&#8217;t flexible enough to -allow us to do what we wanted to&nbsp;do.</p> -<p>Cornice started as a toolkit on top of the -<a href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> -routing system, allowing to register services …</p> -<p>After working for a while with <a href="http://cornice.readthedocs.com">Cornice</a> -to define our APIs at <a href="http://docs.services.mozilla.com">Services</a>, it -turned out that the current implementation wasn&#8217;t flexible enough to -allow us to do what we wanted to&nbsp;do.</p> -<p>Cornice started as a toolkit on top of the -<a href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> -routing system, allowing to register services in a simpler way. Then we -added some niceties such as the ability to automatically generate the -services documentation or returning the correct <span class="caps">HTTP</span> headers <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">as defined -by the <span class="caps">HTTP</span> -specification</a> -without the need from the developer to deal with them nor to know&nbsp;them.</p> -<p>If you&#8217;re not familiar with Cornice, here is how you define a simple -service with&nbsp;it:</p> -<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">cornice.service</span> <span class="kn">import</span> <span class="n">Service</span> -<span class="n">bar</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">path</span><span class="o">=</span><span class="s2">&quot;/bar&quot;</span><span class="p">)</span> - -<span class="nd">@bar</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validators</span><span class="o">=</span><span class="n">validators</span><span class="p">,</span> <span class="n">accept</span><span class="o">=</span><span class="s1">&#39;application/json&#39;</span><span class="p">)</span> -<span class="k">def</span> <span class="nf">get_drink</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="c1"># do something with the request (with moderation).</span> -</code></pre></div> - -<p>This external <span class="caps">API</span> is quite cool, as it allows to do a bunch of things -quite easily. For instance, we&#8217;ve written our -<a href="https://github.com/mozilla-services/tokenserver">token-server</a> code on -top of this in a&nbsp;blast.</p> -<h2 id="the-burden">The&nbsp;burden</h2> -<p>The problem with this was that we were mixing internally the service -description logic with the route registration one. The way we were doing -this was via an extensive use of decorators&nbsp;internally.</p> -<p>The <span class="caps">API</span> of the cornice.service.Service class was as following -(simplified so you can get the gist of&nbsp;it).</p> -<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">Service</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> - - <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">service_kwargs</span><span class="p">):</span> - <span class="c1"># some information, such as the colander schemas (for validation),</span> - <span class="c1"># the defined methods that had been registered for this service and</span> - <span class="c1"># some other things were registered as instance variables.</span> - <span class="bp">self</span><span class="o">.</span><span class="n">schemas</span> <span class="o">=</span> <span class="n">service_kwargs</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">schema</span><span class="s1">&#39;, None)</span> - <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span> <span class="o">=</span> <span class="p">[]</span> - <span class="bp">self</span><span class="o">.</span><span class="n">definitions</span> <span class="o">=</span> <span class="p">[]</span> - - <span class="k">def</span> <span class="nf">api</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">view_kwargs</span><span class="p">):</span> -<span class="w"> </span><span class="sd">&quot;&quot;&quot;This method is a decorator that is being used by some alias</span> -<span class="sd"> methods.</span> -<span class="sd"> &quot;&quot;&quot;</span> - <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="n">view</span><span class="p">):</span> - <span class="c1"># all the logic goes here. And when I mean all the logic, I</span> - <span class="c1"># mean it.</span> - <span class="c1"># 1. we are registering a callback to the pyramid routing</span> - <span class="c1"># system so it gets called whenever the module using the</span> - <span class="c1"># decorator is used.</span> - <span class="c1"># 2. we are transforming the passed arguments so they conform</span> - <span class="c1"># to what is expected by the pyramid routing system.</span> - <span class="c1"># 3. We are storing some of the passed arguments into the</span> - <span class="c1"># object so we can retrieve them later on.</span> - <span class="c1"># 4. Also, we are transforming the passed view before</span> - <span class="c1"># registering it in the pyramid routing system so that it</span> - <span class="c1"># can do what Cornice wants it to do (checking some rules,</span> - <span class="c1"># applying validators and filters etc.</span> - <span class="k">return</span> <span class="n">wrapper</span> - - <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> -<span class="w"> </span><span class="sd">&quot;&quot;&quot;A shortcut of the api decorator&quot;&quot;&quot;</span> - <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">api</span><span class="p">(</span><span class="n">request_method</span><span class="o">=</span><span class="s2">&quot;GET&quot;</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> -</code></pre></div> - -<p>I encourage you to go read <a href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/service.py#L44">the entire -file</a>. -on github so you can get a better opinion on how all of this was&nbsp;done.</p> -<p>A bunch of things are&nbsp;wrong:</p> -<ul> -<li>first, we are not separating the description logic from the - registration one. This causes problems when we need to access the - parameters passed to the service, because the parameters you get are - not exactly the ones you passed but the ones that the pyramid - routing system is expecting. For instance, if you want to get the - view get_drink, you will instead get a decorator which contains - this&nbsp;view.</li> -<li>second, we are using decorators as APIs we expose. Even if - decorators are good as shortcuts, they shouldn&#8217;t be the default way - to deal with an <span class="caps">API</span>. A good example of this is <a href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/resource.py#L56">how the resource - module consumes this - <span class="caps">API</span></a>. - This is quite hard to&nbsp;follow.</li> -<li>Third, in the api method, a bunch of things are done regarding - inheritance of parameters that are passed to the service or to its - decorator methods. This leaves you with a really hard to follow path - when it comes to add new parameters to your <span class="caps">API</span>.</li> -</ul> -<h2 id="how-do-we-improve-this">How do we improve&nbsp;this?</h2> -<p>Python is great because it allows you to refactor things in an easy way. -What I did isn&#8217;t breaking our APIs, but make things way simpler to -hack-on. One example is that it allowed me to add features that we -wanted to bring to Cornice really quickly (a matter of minutes), without -touching the <span class="caps">API</span> that&nbsp;much.</p> -<p>Here is the gist of the new&nbsp;architecture:</p> -<div class="highlight"><pre><span></span><code><span class="k">class</span> <span class="nc">Service</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> - <span class="c1"># we define class-level variables that will be the default values for</span> - <span class="c1"># this service. This makes things more extensible than it was before.</span> - <span class="n">renderer</span> <span class="o">=</span> <span class="s1">&#39;simplejson&#39;</span> - <span class="n">default_validators</span> <span class="o">=</span> <span class="n">DEFAULT_VALIDATORS</span> - <span class="n">default_filters</span> <span class="o">=</span> <span class="n">DEFAULT_FILTERS</span> - - <span class="c1"># we also have some class-level parameters that are useful to know</span> - <span class="c1"># which parameters are supposed to be lists (and so converted as such)</span> - <span class="c1"># or which are mandatory.</span> - <span class="n">mandatory_arguments</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;renderer&#39;</span><span class="p">,)</span> - <span class="n">list_arguments</span> <span class="o">=</span> <span class="p">(</span><span class="s1">&#39;validators&#39;</span><span class="p">,</span> <span class="s1">&#39;filters&#39;</span><span class="p">)</span> - - <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="n">description</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span> <span class="o">**</span><span class="n">kw</span><span class="p">):</span> - <span class="c1"># setup name, path and description as instance variables</span> - <span class="bp">self</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">name</span> - <span class="bp">self</span><span class="o">.</span><span class="n">path</span> <span class="o">=</span> <span class="n">path</span> - <span class="bp">self</span><span class="o">.</span><span class="n">description</span> <span class="o">=</span> <span class="n">description</span> - - <span class="c1"># convert the arguments passed to something we want to store</span> - <span class="c1"># and then store them as attributes of the instance (because they</span> - <span class="c1"># were passed to the constructor</span> - <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_arguments</span><span class="p">(</span><span class="n">kw</span><span class="p">)</span> - <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">arguments</span><span class="o">.</span><span class="n">items</span><span class="p">():</span> - <span class="nb">setattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span> - - <span class="c1"># we keep having the defined_methods tuple and the list of</span> - <span class="c1"># definitions that are done for this service</span> - <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span> <span class="o">=</span> <span class="p">[]</span> - <span class="bp">self</span><span class="o">.</span><span class="n">definitions</span> <span class="o">=</span> <span class="p">[]</span> - - <span class="k">def</span> <span class="nf">get_arguments</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conf</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span> -<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a dict of arguments. It does all the conversions for</span> -<span class="sd"> you, and uses the information that were defined at the instance</span> -<span class="sd"> level as fallbacks.</span> -<span class="sd"> &quot;&quot;&quot;</span> - - <span class="k">def</span> <span class="nf">add_view</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> -<span class="w"> </span><span class="sd">&quot;&quot;&quot;Add a view to this service.&quot;&quot;&quot;</span> - <span class="c1"># this is really simple and looks a lot like this</span> - <span class="n">method</span> <span class="o">=</span> <span class="n">method</span><span class="o">.</span><span class="n">upper</span><span class="p">()</span> - <span class="bp">self</span><span class="o">.</span><span class="n">definitions</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">method</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="n">args</span><span class="p">))</span> - <span class="k">if</span> <span class="n">method</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span><span class="p">:</span> - <span class="bp">self</span><span class="o">.</span><span class="n">defined_methods</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">method</span><span class="p">)</span> - - <span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">method</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> -<span class="w"> </span><span class="sd">&quot;&quot;&quot;This is only another interface to the add_view method, exposing a</span> -<span class="sd"> decorator interface&quot;&quot;&quot;</span> - <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="n">view</span><span class="p">):</span> - <span class="bp">self</span><span class="o">.</span><span class="n">add_view</span><span class="p">(</span><span class="n">method</span><span class="p">,</span> <span class="n">view</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> - <span class="k">return</span> <span class="n">view</span> - <span class="k">return</span> <span class="n">wrapper</span> -</code></pre></div> - -<p>So, the service is now only storing the information that&#8217;s passed to it -and nothing more. No more route registration logic goes here. Instead, I -added this as another feature, even in a different module. The function -is named register_service_views and has the following&nbsp;signature:</p> -<div class="highlight"><pre><span></span><code><span class="n">register_service_views</span><span class="p">(</span><span class="n">config</span><span class="p">,</span> <span class="n">service</span><span class="p">)</span> -</code></pre></div> - -<p>To sum up, here are the changes I&nbsp;made:</p> -<ol> -<li>Service description is now separated from the route&nbsp;registration.</li> -<li>cornice.service.Service now provides a hook_view method, which is - not a decorator. decorators are still present but they are optional - (you don&#8217;t need to use them if you don&#8217;t want&nbsp;to).</li> -<li>Everything has been decoupled as much as possible, meaning that you - really can use the Service class as a container of information about - the services you are describing. This is especially useful when - generating&nbsp;documentation.</li> -</ol> -<p>As a result, it is now possible to use Cornice with other frameworks. It -means that you can stick with the service description but plug any other -framework on top of it. cornice.services.Service is now only a -description tool. To register routes, one would need to read the -information contained into this service and inject the right parameters -into their preferred routing&nbsp;system.</p> -<p>However, no integration with other frameworks is done at the moment even -if the design allows&nbsp;it.</p> -<p>The same way, the sphinx description layer is now only a consumer of -this service description tool: it looks at what&#8217;s described and build-up -the documentation from&nbsp;it.</p> -<p>The resulting branch is not merged yet. Still, you can <a href="https://github.com/mozilla-services/cornice/tree/refactor-the-world">have a look at -it</a>.</p> -<p>Any suggestions are of course welcome&nbsp;:-)</p>Djangocong 20122012-04-16T00:00:00+02:002012-04-16T00:00:00+02:00tag:blog.notmyidea.org,2012-04-16:/djangocong-2012.html -<p>Ce week-end, c&#8217;était <a href="http://rencontres.django-fr.org">djangocong</a>, une -conférence autour de <a href="http://djangoproject.org">django</a>, de -<a href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à -Carnon-plage, à quelques kilomètres de Montpellier la&nbsp;belle.</p> -<p>J&#8217;ai vraiment apprécié les trois jours passés avec cette bande de geeks. -Je m&#8217;attendais à des <em>nerds</em>, j …</p> -<p>Ce week-end, c&#8217;était <a href="http://rencontres.django-fr.org">djangocong</a>, une -conférence autour de <a href="http://djangoproject.org">django</a>, de -<a href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à -Carnon-plage, à quelques kilomètres de Montpellier la&nbsp;belle.</p> -<p>J&#8217;ai vraiment apprécié les trois jours passés avec cette bande de geeks. -Je m&#8217;attendais à des <em>nerds</em>, j&#8217;y ai trouvé une qualité d&#8217;écoute, des -personnes qui partagent des valeurs qui leur sont chères, mais qui ne -limitent pas leurs discussions à du technique. Eeeh ouais, encore un -préjugé qui tombe, tiens&nbsp;:)</p> -<p>En tant que <em>hackers</em>, on a le moyen de créer des outils qui sont utiles -à tous, et qui peuvent être utiles pour favoriser la collaboration et la -mise en commun des données. J&#8217;ai eu l&#8217;occasion de discuter de projets -tournant autour de l&#8217;entraide, que ça soit pour mettre en lien des -associations d&#8217;économie sociale et solidaire (<span class="caps">ESS</span>) ou simplement pour -que les populations <em>non tech</em> <a href="http://blog.notmyidea.org/quels-usages-pour-linformatique-fr.html">puissent utiliser toute la puissance de -l&#8217;outil qu&#8217;est le -web</a>.</p> -<p>Au niveau du format des conférences, je ne savais pas trop à quoi -m&#8217;attendre, au vu des échos de l&#8217;an dernier, mais c&#8217;était adapté: des -mini-confs de 12mn le samedi matin + début d&#8217;aprem, en mode no-wifi pour -récupérer une qualité d&#8217;écoute. Et contrairement à mes attentes, ce -n&#8217;est pas trop court. Pas mal de retours d&#8217;expérience pour le coup, et -une matinée pas vraiment techniques, mais ça pose le décor et permet de -savoir qui fait&nbsp;quoi.</p> -<p>Parmi l&#8217;ensemble des conférences du matin, je retiens principalement -celle de Mathieu Leplatre, &#8220;des cartes d&#8217;un autre monde&#8221;, qui m&#8217;a -réellement bluffée quand à la facilité de créer des cartes avec -<a href="http://mapbox.com/tilemill/">TileMill</a>, et qui me pousse à reconsidérer -le fait que &#8220;la carto, c&#8217;est compliqué&#8221;. <a href="https://www.youtube.com/watch?v=7NPQo54NbJ8">La vidéo est (déja !) -disponible en ligne</a>, je -vous invite à la regarder (c&#8217;est une 15aine de minutes) pour vous faire -un avis&nbsp;;)</p> -<p>Une fois les conf passées, ça reste très intéressant, voire plus: il -reste un jour et demi pour discuter avec les autres présents. On a pu se -retrouver avec Mathieu pour discuter de &#8220;notre&#8221; projet <a href="http://blog.notmyidea.org/carto-forms-fr.html">&#8220;carto -forms&#8221;</a>, qui à finalement -pu se redéfinir un peu plus et donner naissance à un -<a href="https://github.com/spiral-project/daybed/blob/master/README.rst"><span class="caps">README</span></a>. -On en à profité pour lui choisir un nouveau nom: &#8220;daybed&#8221;, en référence -à&nbsp;couchdb.</p> -<p>Ça devrait se transformer en code d&#8217;ici peu. La curiosité aidant, on a -pu discuter du projet avec d&#8217;autres personnes et affiner les attentes de -chacun pour finalement arriver à quelque chose d&#8217;assez&nbsp;sympathique.</p> -<p>J&#8217;ai aussi pu me rendre compte que pas mal de monde utilise -<a href="http://pelican.notmyidea.org">pelican</a>, le bout de code que j&#8217;ai codé -pour générer ce blog, et avoir des retours utiles ! Probablement des -réflexions à venir sur comment éviter qu&#8217;un projet open-source ne -devienne chronophage, et sur comment réussir à garder une qualité dans -le code source tout en ne froissant pas les&nbsp;contributeurs.</p> -<p>Bien évidemment, c&#8217;était aussi l&#8217;occaz de rencontrer des gens qu&#8217;on ne -voir que sur les inter-nets, et de discuter un brin de tout ce qui fait -que notre monde est chouette et moins&nbsp;chouette.</p> -<p>Entres autres faits notoires, JMad a perdu au baby-foot face à Exirel, -même en m&#8217;ayant à ses cotés pour le déconcentrer (et je suis un joueur -d&#8217;un autre monde - en d&#8217;autres termes, je suis nul), David`bgk ne s&#8217;est -pas levé pour aller courir le dimanche matin (il avait dit 5 heures!), -Les suisses ont essayé de me convertir à coup d&#8217;abricotine, j&#8217;ai perdu -au skulls-n-roses en quelques tours et on a allumé un feu chez Stéphane -le dimanche soir (oui oui, à montpellier, mi avril, je vous le dis -qu&#8217;ils mentent avec leur soit disant&nbsp;soleil).</p> -<p>Et c&#8217;est sans parler de <a href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la -brasucade</a>&nbsp;…</p> -<p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une -présentation&nbsp;!)</p>Génération de formulaires, geolocalisés ?2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/generation-de-formulaires-geolocalises.html -<p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> -<p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même -chose, à quelques détails près: une page web avec un formulaire qui -permettrait de soumettre des informations géographiques, lié à une carte -et des manières de filtrer&nbsp;l&#8217;information …</p> -<p>On a un plan. Un &#8220;truc de&nbsp;ouf&#8221;.</p> -<p>À plusieurs reprises, des amis m&#8217;ont demandé de leur coder la même -chose, à quelques détails près: une page web avec un formulaire qui -permettrait de soumettre des informations géographiques, lié à une carte -et des manières de filtrer&nbsp;l&#8217;information.</p> -<p>L&#8217;idée fait son bout de chemin, et je commence à penser qu&#8217;on peut même -avoir quelque chose de vraiment flexible et utile. J&#8217;ai nommé le projet -<em>carto-forms</em> pour l&#8217;instant (mais c&#8217;est uniquement un nom de&nbsp;code).</p> -<p>Pour résumer: et si on avait un moyen de construire des formulaires, un -peu comme Google forms, mais avec des informations géographiques en&nbsp;plus?</p> -<p>Si vous ne connaissez pas Google forms, il s&#8217;agit d&#8217;une interface simple -d&#8217;utilisation pour générer des formulaires et récupérer des informations -depuis ces&nbsp;derniers.</p> -<p>Google forms est un super outil mais à mon avis manque deux choses -importantes: premièrement, il s&#8217;agit d&#8217;un outil propriétaire (oui, on -peut aussi dire privateur) et il n&#8217;est donc pas possible de le hacker un -peu pour le faire devenir ce qu&#8217;on souhaite, ni l&#8217;installer sur notre -propre serveur. Deuxièmement, il ne sait pas vraiment fonctionner avec -des informations géographiques, et il n&#8217;y à pas d&#8217;autre moyen de filtrer -les informations que l&#8217;utilisation de leur système de feuilles de&nbsp;calcul.</p> -<p>Après avoir réfléchi un petit peu à ça, j&#8217;ai contacté -<a href="http://blog.mathieu-leplatre.info/">Mathieu</a> et les anciens collègues -de chez <a href="http://makina-corpus.com">Makina Corpus</a>, puisque les projets -libres à base de carto sont à même de les&nbsp;intéresser.</p> -<p>Imaginez le cas&nbsp;suivant:</p> -<ol> -<li>Dans une &#8220;mapping party&#8221;, on choisit un sujet particulier à - cartographier et on design un formulaire (liste des champs (tags) a - remplir + description + le type d&#8217;information)&nbsp;;</li> -<li>Sur place, les utilisateurs remplissent les champs du formulaire - avec ce qu&#8217;ils voient. Les champs géolocalisés peuvent être remplis - automatiquement avec la géolocalisation du téléphone&nbsp;;</li> -<li>À la fin de la journée, il est possible de voir une carte des - contributions, avec le formulaire choisi&nbsp;;</li> -<li>Un script peut importer les résultats et les publier vers&nbsp;OpenStreetMap.</li> -</ol> -<h2 id="quelques-cas-dutilisation">Quelques cas&nbsp;d&#8217;utilisation</h2> -<p>J&#8217;arrive à imaginer différents cas d&#8217;utilisation pour cet outil. Le -premier est celui que j&#8217;ai approximativement décrit plus haut: la -génération de cartes de manière collaborative, avec des filtres à -facettes. Voici un flux d&#8217;utilisation&nbsp;général:</p> -<ul> -<li> -<p>Un &#8220;administrateur&#8221; se rend sur le site web et crée un nouveau - formulaire pour l&#8217;ensemble des évènements alternatifs. Il crée les - champs&nbsp;suivants:</p> -<ul> -<li>Nom: le champ qui contient le nom de&nbsp;l&#8217;évènement.</li> -<li>Catégorie: la catégorie de l&#8217;évènement (marche, concert, - manifestation…). Il peut s&#8217;agir d&#8217;un champ à multiples&nbsp;occurrences.</li> -<li>Le lieu de l&#8217;évènement. Celui-ci peut être donné soit par une - adresse soit en sélectionnant un point sur une&nbsp;carte.</li> -<li>Date: la date de l&#8217;évènement (un &#8220;date picker&#8221; peut permettre - cela&nbsp;facilement)</li> -</ul> -<p>Chaque champ dans le formulaire a des informations sémantiques -associées (oui/non, multiple sélection, date, heure, champ géocodé, -sélection carto,&nbsp;etc.)</p> -</li> -<li> -<p>Une fois terminé, le formulaire est généré et une <span class="caps">URL</span> permet d&#8217;y - accéder. (par exemple <a href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>).</p> -</li> -<li> -<p>Une <span class="caps">API</span> <span class="caps">REST</span> permet à d&#8217;autres applications d&#8217;accéder aux - informations et d&#8217;en ajouter / modifier de&nbsp;nouvelles.</p> -</li> -<li> -<p>Il est maintenant possible de donner l&#8217;<span class="caps">URL</span> à qui voudra en faire bon - usage. N&#8217;importe qui peut ajouter des informations. On peut - également imaginer une manière de modérer les modifications si - besoin&nbsp;est.</p> -</li> -<li> -<p>Bien sur, la dernière phase est la plus intéressante: il est - possible de filtrer les informations par lieu, catégorie ou date, le - tout soit via une <span class="caps">API</span> <span class="caps">REST</span>, soit via une jolie carte et quelques - contrôles bien placés, dans le&nbsp;navigateur.</p> -</li> -</ul> -<p>Vous avez dû remarquer que le processus de création d&#8217;un formulaire est -volontairement très simple. L&#8217;idée est que n&#8217;importe qui puisse créer -des cartes facilement, en quelques clics. Si une <span class="caps">API</span> bien pensée suit, -on peut imaginer faire de la validation coté serveur et même faire des -applications pour téléphone assez&nbsp;simplement.</p> -<p>Pour aller un peu plus loin, si on arrive à penser un format de -description pour le formulaire, il sera possible de construire les -formulaires de manière automatisée sur différentes plateformes et -également sur des clients&nbsp;génériques.</p> -<p>On imagine pas mal d&#8217;exemples pour ce projet: des points de recyclage, -les endroits accessibles (pour fauteuils roulants etc.), identification -des arbres, bons coins à champignons, recensement des espèces en voie de -disparition (l&#8217;aigle de Bonelli est actuellement suivi en utilisant une -feuille de calcul partagée !), suivi des espèces dangereuses (le frelon -asiatique par exemple), cartographier les points d&#8217;affichage -publicitaires, participation citoyenne (graffitis, nids de poule, voir -<a href="http://fixmystreet.ca">http://fixmystreet.ca</a>), geocaching, trajectoires (randonnées, -coureurs,&nbsp;cyclistes)…</p> -<p>Voici quelques exemples où ce projet pourrait être utile (la liste n&#8217;est -pas&nbsp;exhaustive):</p> -<h3 id="un-backend-sig-simple-a-utiliser">Un backend <span class="caps">SIG</span> simple à&nbsp;utiliser</h3> -<p>Disons que vous êtes développeur mobile. Vous ne voulez pas vous -encombrer avec PostGIS ou écrire du code spécifique pour récupérer et -insérer des données <span class="caps">SIG</span>! Vous avez besoin de <em>Carto-Forms</em>! Une <span class="caps">API</span> -simple vous aide à penser vos modèles et vos formulaires, et cette même -<span class="caps">API</span> vous permet d&#8217;insérer et de récupérer des données. Vous pouvez vous -concentrer sur votre application et non pas sur la manière dont les -données géographiques sont stockées et&nbsp;gérées.</p> -<p>En d&#8217;autres termes, vous faites une distinction entre le stockage des -informations et leur&nbsp;affichage.</p> -<p>Si vous êtes un développeur django, plomino, drupal etc. vous pouvez -développer un module pour &#8220;plugger&#8221; vos modèles et votre interface -utilisateur avec celle de <em>Carto-Forms</em>. De cette manière, il est -possible d&#8217;exposer les formulaires aux utilisateurs de vos backoffices. -De la même manière, il est possible d&#8217;écrire des widgets qui consomment -des données et les affichent (en utilisant par exemple une bibliothèque -javascript de&nbsp;webmapping).</p> -<h3 id="un-outil-de-visualisation">Un outil de&nbsp;visualisation</h3> -<p>Puisque les données peuvent être proposées de manière automatisée en -utilisant l&#8217;<span class="caps">API</span>, vous pouvez utiliser la page de résultat de Carto-forms -comme un outil de&nbsp;visualisation.</p> -<p>Il est possible d&#8217;explorer mon jeu de données en utilisant des filtres -sur chacun des champs. La recherche à facettes peut être une idée pour -faciliter ce filtrage. Une carte affiche le résultat. Vous avez -l&#8217;impressoin d&#8217;être en face d&#8217;un système d&#8217;aide à la décision&nbsp;!</p> -<p>Évidemment, il est possible de télécharger les données brutes (geojson, -xml). Idéalement, le mieux serait d&#8217;obtenir ces données filtrées -directement depuis une <span class="caps">API</span> Web, et un lien permet de partager la page -avec l&#8217;état des filtres et le niveau de zoom / la localisation de la&nbsp;carte.</p> -<h3 id="un-service-generique-pour-gerer-les-formulaires">Un service générique pour gérer les&nbsp;formulaires</h3> -<p>Si vous souhaitez générer un fichier de configuration (ou ce que vous -voulez, messages emails, …) vous aurez besoin d&#8217;un formulaire et d&#8217;un -template pour injecter les données proposées par les utilisateurs et -récupérer un&nbsp;résultat.</p> -<p>Un service de gestion des formulaires pourrait être utile pour créer des -formulaires de manière automatique et récupérer les données &#8220;nettoyées&#8221; -et&nbsp;&#8220;validées&#8221;.</p> -<p>On peut imaginer par exemple l&#8217;utilisation d&#8217;un système de templates -externe reposant sur <em>carto-forms</em>. Celui-ci &#8220;parserait&#8221; le contenu des -templates et pourrait le lier aux informations ajoutées par les -utilisateurs via un&nbsp;formulaire.</p> -<p>Pour ce cas particulier, il n&#8217;y a pas besoin d&#8217;informations -géographiques (<span class="caps">SIG</span>). Il s&#8217;agit quasiment du service proposé -actuellement par Google&nbsp;forms.</p> -<h2 id="ca-nexiste-pas-deja-tout-ca">Ça n&#8217;existe pas déjà tout ça&nbsp;?</h2> -<p>Bien sur, il y a Google forms, qui vous permet de faire ce genre de -choses, mais comme je l&#8217;ai précisé plus haut, il ne s&#8217;agit pas -exactement de la même&nbsp;chose.</p> -<p>Nous avons découvert <a href="https://webform.com">https://webform.com</a> qui permet de créer des -formulaires avec un système de drag&#8217;n&#8217;drop. J&#8217;adorerais reproduire -quelque chose de similaire pour l&#8217;interface utilisateur. Par contre ce -projet ne gère pas les appels via <span class="caps">API</span> et les informations de -géolocalisation&nbsp;…</p> -<p>L&#8217;idée de <a href="http://thoth.io">http://thoth.io</a> est également assez sympathique: une api -très simple pour stocker et récupérer des données. En plus de ça, -<em>carto-forms</em> proposerait de la validation de données et proposerait un -support des points <span class="caps">SIG</span> (point, ligne,&nbsp;polygone).</p> -<p><a href="http://mapbox.com">http://mapbox.com</a> fait également un superbe travail autour de la -cartographie, mais ne prends pas en compte le coté auto-génération de&nbsp;formulaires…</p> -<h2 id="on-est-parti">On est parti&nbsp;?!</h2> -<p>Comme vous avez pu vous en rendre compte, il ne s&#8217;agit pas d&#8217;un problème -outrageusement complexe. On a pas mal discuté avec Mathieu, à propos de -ce qu&#8217;on souhaite faire et du comment. Il se trouve qu&#8217;on peut sûrement -s&#8217;en sortir avec une solution élégante sans trop de problèmes. Mathieu -est habitué à travailler autour des projets de <span class="caps">SIG</span> (ce qui est parfait -parce que ce n&#8217;est pas mon cas) et connaît son sujet. Une bonne -opportunité&nbsp;d&#8217;apprendre!</p> -<p>On sera tous les deux à <a href="http://rencontres.django-fr.org">Djangocong</a> le -14 et 15 Avril, et on prévoit une session de <em>tempête de cerveau</em> et un -sprint sur ce projet. Si vous êtes dans le coin et que vous souhaitez -discuter ou nous filer un coup de patte, n&#8217;hésitez&nbsp;pas!</p> -<p>On ne sait pas encore si on utilisera django ou quelque chose d&#8217;autre. -On a pensé un peu à CouchDB, son système de couchapps et geocouch, mais -rien n&#8217;est encore gravé dans le marbre ! N&#8217;hésitez pas à proposer vos -solutions ou&nbsp;suggestions.</p> -<p>Voici le document etherpad sur lequel on a travaillé jusqu&#8217;à maintenant: -<a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. N&#8217;hésitez pas à l&#8217;éditer et à ajouter -vos commentaires, c&#8217;est son&nbsp;objectif!</p> -<p>Merci à <a href="http://sneakernet.fr/">Arnaud</a> pour la relecture et la -correction de quelques typos dans le texte&nbsp;:)</p>Thoughts about a form generation service, GIS enabled2012-04-02T00:00:00+02:002012-04-02T00:00:00+02:00tag:blog.notmyidea.org,2012-04-02:/thoughts-about-a-form-generation-service-gis-enabled.html -<p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> -<p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> -<p>A bunch of friends asked me twice for quite the same thing: a webpage -with a form, tied to a map generation with some information filtering. -They didn&#8217;t explicitly ask that but that&#8217;s the …</p> -<p><em>Written by Alexis Métaireau <span class="amp">&amp;</span> Mathieu&nbsp;Leplatre</em></p> -<p>We have a plan. A &#8220;fucking good&#8221;&nbsp;one.</p> -<p>A bunch of friends asked me twice for quite the same thing: a webpage -with a form, tied to a map generation with some information filtering. -They didn&#8217;t explicitly ask that but that&#8217;s the gist of&nbsp;it.</p> -<p>This idea has been stuck in my head since then and I even think that we -can come out with something a little bit more flexible and useful. I&#8217;ve -named it <em>carto-forms</em> for now, but that&#8217;s only the&nbsp;&#8220;codename&#8221;.</p> -<p>To put it shortly: what if we had a way to build forms, ala Google -forms, but with geographic information in&nbsp;them?</p> -<p>If you don&#8217;t know Google forms, it means having an user-friendly way to -build forms and to use them to gather information from different&nbsp;users.</p> -<p>In my opinion, Google forms is missing two important things: first, it&#8217;s -not open-source, so it&#8217;s not possible to hack it or even to run it on -your own server. Second, it doesn&#8217;t really know how to deal with -geographic data, and there is no way to filter the information more than -in a&nbsp;spreadsheet.</p> -<p>I knew that <a href="http://blog.mathieu-leplatre.info/">Mathieu</a> and some folks -at <a href="http://makina-corpus.com">Makina Corpus</a> would be interested in -this, so I started a discussion with him on <span class="caps">IRC</span> and we refined the -details of the project and its&nbsp;objectives.</p> -<p>Imagine the&nbsp;following:</p> -<ol> -<li>For a mapping party, we choose a specific topic to map and design - the form (list of fields (i.e. tags) to be filled + description + - type of the information)&nbsp;;</li> -<li>In situ, users fill the form fields with what they see. Geo fields - can be pre-populated using device geolocation&nbsp;;</li> -<li>At the end of the day, we can see a map with all user contributions - seized through this particular form&nbsp;;</li> -<li>If relevant, a script could eventually import the resulting dataset - and publish/merge with&nbsp;OpenStreetMap.</li> -</ol> -<h2 id="some-use-cases">Some use&nbsp;cases</h2> -<p>I can see some use cases for this. The first one is a collaborative map, -with facet filtering. Let&#8217;s draw a potential user&nbsp;flow:</p> -<ul> -<li> -<p>An &#8220;administrator&#8221; goes to the website and creates a form to list - all the alternative-related events. He creates the following&nbsp;fields:</p> -<ul> -<li>Name: a plain text field containing the name of the&nbsp;event.</li> -<li>Category: the category of the event. Can be a finite&nbsp;list.</li> -<li>Location: The location of the event. It could be provided by - selecting a point on a map or by typing an&nbsp;address.</li> -<li>Date: the date of the event (a datepicker could do the&nbsp;trick)</li> -</ul> -<p>Each field in the form has semantic information associated with it -(yes/no, multiple selection, date-time, geocoding carto, carto -selection&nbsp;etc)</p> -</li> -<li> -<p>Once finished, the form is generated and the user gets an url (say - <a href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>) for&nbsp;it.</p> -</li> -<li> -<p><span class="caps">REST</span> APIs allow third parties to get the form description and to - push/edit/get information from&nbsp;there.</p> -</li> -<li> -<p>He can communicate the address in any way he wants to his community - so they can go to the page and add information to&nbsp;it.</p> -</li> -<li> -<p>Then, it is possible to filter the results per location / date or - category. This can be done via <span class="caps">API</span> calls (useful for third parties) - or via a nice interface in the&nbsp;browser.</p> -</li> -</ul> -<p>So, as you may have noticed, this would allow us to create interactive -maps really easily. It&#8217;s almost just a matter of some clicks to the -users. If we also come up with a nice Web <span class="caps">API</span> for this, we could do -server-side validation and build even phone applications&nbsp;easily.</p> -<p>To push the cursor a bit further, if we can come with a cool description -format for the forms, we could even build the forms dynamically on -different platforms, with generic&nbsp;clients.</p> -<p>As mentioned before, the idea of a simple tool to support collaborative -mapping fullfils a recurring necessity&nbsp;!</p> -<p>We envision a lot of example uses for this : recycling spots, accessible -spots (wheelchairs, etc.), trees identification, mushrooms picking -areas, tracking of endangered species (e.g. Bonelli&#8217;s Eagle is currently -tracked by sharing a spreadsheet), spotting of dangerous species (e.g. -asian predatory wasps), map advertisement boards (most cities do not -track them!), citizen reporting (e.g. graffiti, potholes, garbage, -lightning like <a href="http://fixmystreet.ca">http://fixmystreet.ca</a>), geocaching, trajectories (e.g -hiking, runners,&nbsp;cyclists)&#8230;</p> -<p>Here are some other examples of where <em>carto-forms</em> could be&nbsp;useful:</p> -<h3 id="simple-gis-storage-backend">Simple <span class="caps">GIS</span> storage&nbsp;backend</h3> -<p>Let&#8217;s say you are a mobile developer, you don&#8217;t want to bother with -PostGIS nor write a custom and insecure code to insert and retrieve your -<span class="caps">GIS</span> data! You need carto-forms! A simple <span class="caps">API</span> helps you design your -models/forms and the same <span class="caps">API</span> allows you to <span class="caps">CRUD</span> and query your data. -Thus, you only need to focus on your application, not on how <span class="caps">GIS</span> data -will be&nbsp;handled.</p> -<p>We make a distinction between storage and&nbsp;widgets.</p> -<p>Besides, if you are a django / drupal / plomino&#8230; maintainer : you can -develop a module to &#8220;plug&#8221; your models (content types) and <span class="caps">UI</span> to -carto-forms! Carto forms are then exposed to your backoffice users (ex: -drupal admin <span class="caps">UI</span>, django adminsite), and likewise you can write your own -<span class="caps">HTML</span> widgets that consume datasets in frontend views (facets in -<span class="caps">JSON</span>/<span class="caps">XML</span>, and map data in&nbsp;GeoJSON).</p> -<h3 id="visualization-tool">Visualization&nbsp;tool</h3> -<p>Since data submission can be done programmatically using the <span class="caps">API</span>, you -could use Carto-forms results page as a visualization&nbsp;tool.</p> -<p>You can explore your dataset content using filters related to each form -field. Facets filtering is a great advantage, and a map shows the -resulting features set. You feel like you&#8217;re in front of a decision -support&nbsp;system!</p> -<p>Of course, filtered raw data can be downloaded (GeoJSON, <span class="caps">XML</span>) and a -permalink allows to share the page with the state of the filters and the -zoom/location of the&nbsp;map.</p> -<h3 id="generic-forms-service">Generic forms&nbsp;service</h3> -<p>If you want to generate a configuration file (or whatever, email -messages, &#8230;), you will need a form and a template to inlay user -submitted values and get the&nbsp;result.</p> -<p>A form service would be really useful to create forms programmatically -and retrieve cleaned and validated input&nbsp;values.</p> -<p>You could run a dedicated template service based on <em>carto-forms</em>! -Parsing a template content, this external service could create a form -dynamically and bind them together. The output of the form service -(fields =&gt; values) would be bound to the input of a template engine -(variables =&gt; final&nbsp;result).</p> -<p>Note that for this use-case, there is no specific need of <span class="caps">GIS</span> data nor -storage of records for further&nbsp;retrieval.</p> -<h2 id="whats-out-in-the-wild-already">What&#8217;s out in the wild&nbsp;already?</h2> -<p>Of course, there is Google forms, which allows you to do these kind of -things, but it&#8217;s closed and not exactly what we are describing&nbsp;here.</p> -<p>We&#8217;ve discovered the interesting <a href="https://webform.com/">https://webform.com/</a> which allows one -to create forms with a nice drag-n-drop flow. I would love to reproduce -something similar for the user experience. However, the project doesn&#8217;t -handle APIs and geolocation&nbsp;information.</p> -<p>The idea of <a href="http://thoth.io">http://thoth.io</a> is very attractive : an extremely simple -web <span class="caps">API</span> to store and retrieve data. In addition, <em>carto-forms</em> would do -datatype validation and have basic <span class="caps">GIS</span> fields (point, line,&nbsp;polygon).</p> -<p><a href="http://mapbox.com">http://mapbox.com</a> also did an awesome work on cartography, but didn&#8217;t -take into account the form aspect we&#8217;re leveraging&nbsp;here.</p> -<h2 id="so-lets-get-it-real">So… Let&#8217;s get it&nbsp;real!</h2> -<p>As you may have understood, this isn&#8217;t a really complicated problem. We -have been sometimes chatting about that with Mathieu about what we would -need and how we could achieve&nbsp;this.</p> -<p>We can probably come with an elegant solution without too much pain. -Mathieu is used to work with <span class="caps">GIS</span> systems (which is really cool because -I&#8217;m not at all) and knows his subject, so that&#8217;s an opportunity to learn&nbsp;;-)</p> -<p>We will be at <a href="http://rencontres.django-fr.org">Djangocong</a> on April 14 -and 15 and will probably have a brainstorming session and a sprint on -this, so if you are around and want to help us, or just to discuss, feel -free to&nbsp;join!</p> -<p>We don&#8217;t know yet if we will be using django for this or something else. -We have been thinking about couchdb, couchapps and geocouch but nothing -is written in stone yet. Comments and proposals are&nbsp;welcome!</p> -<p>Here is the etherpad document we worked on so far: -<a href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don&#8217;t hesitate to add your thoughts -and edit it, that&#8217;s what it&#8217;s made&nbsp;for!</p> -<p>Thanks to <a href="http://sneakernet.fr/">Arnaud</a> and -<a href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo&nbsp;fixing.</p>Introducing Cornice2011-12-07T00:00:00+01:002011-12-07T00:00:00+01:00tag:blog.notmyidea.org,2011-12-07:/introducing-cornice.html -<p>Wow, already my third working day at Mozilla. Since Monday, I&#8217;ve been -working with <a href="http://ziade.org">Tarek Ziadé</a>, on a pyramid <span class="caps">REST</span>-ish -toolkit named <a href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> -<p>Its goal is to take care for you of what you&#8217;re usually missing so you -can focus on what&#8217;s important. Cornice provides you …</p> -<p>Wow, already my third working day at Mozilla. Since Monday, I&#8217;ve been -working with <a href="http://ziade.org">Tarek Ziadé</a>, on a pyramid <span class="caps">REST</span>-ish -toolkit named <a href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> -<p>Its goal is to take care for you of what you&#8217;re usually missing so you -can focus on what&#8217;s important. Cornice provides you facilities for -validation of any&nbsp;kind.</p> -<p>The goal is to simplify your work, but we don&#8217;t want to reinvent the -wheel, so it is easily pluggable with validations frameworks, such as -<a href="http://docs.pylonsproject.org/projects/colander/en/latest/">Colander</a>.</p> -<h2 id="handling-errors-and-validation">Handling errors and&nbsp;validation</h2> -<p>Here is how it&nbsp;works:</p> -<div class="highlight"><pre><span></span><code><span class="n">service</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;service&quot;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s2">&quot;/service&quot;</span><span class="p">)</span> - - -<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="k">if</span> <span class="ow">not</span> <span class="s1">&#39;awesome&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span> - <span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">&#39;query&#39;</span><span class="p">,</span> <span class="s1">&#39;awesome&#39;</span><span class="p">,</span> - <span class="s1">&#39;the awesome parameter is required&#39;</span><span class="p">)</span> - - -<span class="nd">@service</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span> -<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;test&quot;</span><span class="p">:</span> <span class="s2">&quot;yay!&quot;</span><span class="p">}</span> -</code></pre></div> - -<p>All the errors collected during the validation process, or after, are -collected before returning the request. If any, a error 400 is fired up, -with the list of problems encountered returned as a nice json list -response (we plan to support multiple formats in the&nbsp;future)</p> -<p>As you might have seen, request.errors.add takes three parameters: -<strong>location</strong>, <strong>name</strong> and <strong>description</strong>.</p> -<p><strong>location</strong> is where the error is located in the request. It can either -be &#8220;body&#8221;, &#8220;query&#8221;, &#8220;headers&#8221; or &#8220;path&#8221;. <strong>name</strong> is the name of the -variable causing problem, if any, and <strong>description</strong> contains a more -detailed&nbsp;message.</p> -<p>Let&#8217;s run this simple service and send some queries to&nbsp;it:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>-v<span class="w"> </span>http://127.0.0.1:5000/service -&gt;<span class="w"> </span>GET<span class="w"> </span>/service<span class="w"> </span>HTTP/1.1 -&gt;<span class="w"> </span>Host:<span class="w"> </span><span class="m">127</span>.0.0.1:5000 -&gt;<span class="w"> </span>Accept:<span class="w"> </span>*/* -&gt; -*<span class="w"> </span>HTTP<span class="w"> </span><span class="m">1</span>.0,<span class="w"> </span>assume<span class="w"> </span>close<span class="w"> </span>after<span class="w"> </span>body -&lt;<span class="w"> </span>HTTP/1.0<span class="w"> </span><span class="m">400</span><span class="w"> </span>Bad<span class="w"> </span>Request -&lt;<span class="w"> </span>Content-Type:<span class="w"> </span>application/json<span class="p">;</span><span class="w"> </span><span class="nv">charset</span><span class="o">=</span>UTF-8 -<span class="o">[{</span><span class="s2">&quot;location&quot;</span>:<span class="w"> </span><span class="s2">&quot;query&quot;</span>,<span class="w"> </span><span class="s2">&quot;name&quot;</span>:<span class="w"> </span><span class="s2">&quot;awesome&quot;</span>,<span class="w"> </span><span class="s2">&quot;description&quot;</span>:<span class="w"> </span><span class="s2">&quot;You lack awesomeness!&quot;</span><span class="o">}</span> -</code></pre></div> - -<p>I&#8217;ve removed the extra clutter from the curl&#8217;s output, but you got the -general&nbsp;idea.</p> -<p>The content returned is in <span class="caps">JSON</span>, and I know exactly what I have to do: -add an &#8220;awesome&#8221; parameter in my query. Let&#8217;s do it&nbsp;again:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>http://127.0.0.1:5000/service?awesome<span class="o">=</span>yeah -<span class="o">{</span><span class="s2">&quot;test&quot;</span>:<span class="w"> </span><span class="s2">&quot;yay!&quot;</span><span class="o">}</span> -</code></pre></div> - -<p>Validators can also convert parts of the request and store the converted -value in request.validated. It is a standard dict automatically attached -to the&nbsp;requests.</p> -<p>For instance, in our validator, we can chose to validate the parameter -passed and use it in the body of the&nbsp;webservice:</p> -<div class="highlight"><pre><span></span><code><span class="n">service</span> <span class="o">=</span> <span class="n">Service</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s2">&quot;service&quot;</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="s2">&quot;/service&quot;</span><span class="p">)</span> - - -<span class="k">def</span> <span class="nf">is_awesome</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="k">if</span> <span class="ow">not</span> <span class="s1">&#39;awesome&#39;</span> <span class="ow">in</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">:</span> - <span class="n">request</span><span class="o">.</span><span class="n">errors</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s1">&#39;query&#39;</span><span class="p">,</span> <span class="s1">&#39;awesome&#39;</span><span class="p">,</span> - <span class="s1">&#39;the awesome parameter is required&#39;</span><span class="p">)</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s1">&#39;awesome&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;awesome &#39;</span> <span class="o">+</span> <span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="p">[</span><span class="s1">&#39;awesome&#39;</span><span class="p">]</span> - - -<span class="nd">@service</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">)</span> -<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;test&quot;</span><span class="p">:</span> <span class="n">request</span><span class="o">.</span><span class="n">validated</span><span class="p">[</span><span class="s1">&#39;awesome&#39;</span><span class="p">]}</span> -</code></pre></div> - -<p>The output would look like&nbsp;this:</p> -<div class="highlight"><pre><span></span><code>curl http://127.0.0.1:5000/service?awesome=yeah -{&quot;test&quot;: &quot;awesome yeah&quot;} -</code></pre></div> - -<h2 id="dealing-with-accept-headers">Dealing with &#8220;Accept&#8221;&nbsp;headers</h2> -<p>The <span class="caps">HTTP</span> spec defines a <strong>Accept</strong> header the client can send so the -response is encoded the right way. A resource, available at an <span class="caps">URL</span>, can -be available in different formats. This is especially true for web&nbsp;services.</p> -<p>Cornice can help you dealing with this. The services you define can tell -which Content-Type values they can deal with and this will be checked -against the <strong>Accept</strong> headers sent by the&nbsp;client.</p> -<p>Let&#8217;s refine a bit our previous example, by specifying which -content-types are supported, using the accept&nbsp;parameter:</p> -<div class="highlight"><pre><span></span><code><span class="nd">@service</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">validator</span><span class="o">=</span><span class="n">is_awesome</span><span class="p">,</span> <span class="n">accept</span><span class="o">=</span><span class="p">(</span><span class="s2">&quot;application/json&quot;</span><span class="p">,</span> <span class="s2">&quot;text/json&quot;</span><span class="p">))</span> -<span class="k">def</span> <span class="nf">get1</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> - <span class="k">return</span> <span class="p">{</span><span class="s2">&quot;test&quot;</span><span class="p">:</span> <span class="s2">&quot;yay!&quot;</span><span class="p">}</span> -</code></pre></div> - -<p>Now, if you specifically ask for <span class="caps">XML</span>, Cornice will throw a 406 with the -list of accepted Content-Type&nbsp;values:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>curl<span class="w"> </span>-vH<span class="w"> </span><span class="s2">&quot;Accept: application/xml&quot;</span><span class="w"> </span>http://127.0.0.1:5000/service -&gt;<span class="w"> </span>GET<span class="w"> </span>/service<span class="w"> </span>HTTP/1.1 -&gt;<span class="w"> </span>Host:<span class="w"> </span><span class="m">127</span>.0.0.1:5000 -&gt;<span class="w"> </span>Accept:<span class="w"> </span>application/xml -&gt; -&lt;<span class="w"> </span>HTTP/1.0<span class="w"> </span><span class="m">406</span><span class="w"> </span>Not<span class="w"> </span>Acceptable -&lt;<span class="w"> </span>Content-Type:<span class="w"> </span>application/json<span class="p">;</span><span class="w"> </span><span class="nv">charset</span><span class="o">=</span>UTF-8 -&lt;<span class="w"> </span>Content-Length:<span class="w"> </span><span class="m">33</span> -&lt; -<span class="o">[</span><span class="s2">&quot;application/json&quot;</span>,<span class="w"> </span><span class="s2">&quot;text/json&quot;</span><span class="o">]</span> -</code></pre></div> - -<h2 id="building-your-documentation-automatically">Building your documentation&nbsp;automatically</h2> -<p>writing documentation for web services can be painful, especially when -your services evolve. Cornice provides a sphinx directive to -automatically document your <span class="caps">API</span> in your&nbsp;docs.</p> -<div class="highlight"><pre><span></span><code><span class="nx">rst</span> -<span class="p">..</span><span class="w"> </span><span class="nx">services</span><span class="o">::</span> -<span class="w"> </span><span class="p">:</span><span class="kn">package</span><span class="p">:</span><span class="w"> </span><span class="nx">coolapp</span> -<span class="w"> </span><span class="p">:</span><span class="nx">service</span><span class="p">:</span><span class="w"> </span><span class="nx">quote</span> -</code></pre></div> - -<p>Here is an example of what a generated page looks like: -<a href="http://packages.python.org/cornice/exampledoc.html">http://packages.python.org/cornice/exampledoc.html</a></p> -<h2 id="yay-how-can-i-get-it">Yay! How can I get&nbsp;it?</h2> -<p>We just cut a 0.4 release, so it&#8217;s available at -<a href="http://pypi.python.org/pypi/cornice">http://pypi.python.org/pypi/cornice</a> You can install it easily using -pip, for&nbsp;instance:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>cornice -</code></pre></div> - -<p>You can also have a look at the documentation at -<a href="http://packages.python.org/cornice/">http://packages.python.org/cornice/</a></p> -<h2 id="whats-next">What&#8217;s&nbsp;next?</h2> -<p>We try to make our best to find how Cornice can help you build better -web services. Cool features we want for the future include the automatic -publication of a static definition of the services, so it can be used by -clients to discover services in a nice&nbsp;way.</p> -<p>Of course, we are open to all your ideas and patches! If you feel -haskish and want to see the sources, <a href="https://github.com/mozilla-services/cornice">go grab them on -github</a> , commit and send -us a pull&nbsp;request!</p>How are you handling your shared expenses?2011-10-15T00:00:00+02:002011-10-15T00:00:00+02:00tag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.html -<p><strong><span class="caps">TL</span>;<span class="caps">DR</span>:</strong> We&#8217;re kick-starting a new application to manage your shared -expenses. Have a look at <a href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a></p> -<p>As a student, I lived in a lot of different locations, and the majority -of them had something in common: I lived with others. It usually was a -great …</p> -<p><strong><span class="caps">TL</span>;<span class="caps">DR</span>:</strong> We&#8217;re kick-starting a new application to manage your shared -expenses. Have a look at <a href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a></p> -<p>As a student, I lived in a lot of different locations, and the majority -of them had something in common: I lived with others. It usually was a -great experience (and I think I will continue to live with others). Most -of the time, we had to spend some time each month to compute who had to -pay what to the&nbsp;others.</p> -<p>I wanted to create a pet project using flask, so I wrote a little (\~150 -lines) flask application to handle this. It worked out pretty well for -my housemates and me, and as we had to move into different locations, -one of them asked me if he could continue to use it for the year to&nbsp;come.</p> -<p>I said yes and gave it some more thoughts: We probably aren&#8217;t the only -ones interested by such kind of software. I decided to extend a bit more -the software to have a concept of projects and persons (the list of -persons was hard-coded in the first time,&nbsp;boooh!).</p> -<p>I then discussed with a friend of mine, who was excited about it and -wanted to learn python. Great! That&#8217;s a really nice way to get started. -Some more friends were also interested in it and contributed some -features and provided feedback (thanks -<a href="http://www.sneakernet.fr/">Arnaud</a> and&nbsp;Quentin!)</p> -<p>Since that, the project now support multiple languages and provides a -<span class="caps">REST</span> <span class="caps">API</span> (android and iphone apps in the tubes!), into other things. -There is no need to register for an account or whatnot, just enter a -project name, a secret code and a contact email, invite friends and -that&#8217;s it (this was inspired by&nbsp;doodle)!</p> -<p><img alt="Capture d'écran du site." src="/images/ihatemoney.png"></p> -<p>You can try the project at <a href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a> for now, -and the code lives at <a href="https://github.com/spiral-project/ihatemoney/">https://github.com/spiral-project/ihatemoney/</a>.</p> -<h2 id="features">Features</h2> -<p>In the wild, currently, there already are some implementations of this -shared budget manager thing. The fact is that most of them are either -hard to use, with a too much fancy design or simply trying to do too -much things at&nbsp;once.</p> -<p>No, I don&#8217;t want my budget manager to make my shopping list, or to run a -blog for me, thanks. I want it to let me focus on something else. Keep -out of my&nbsp;way.</p> -<h3 id="no-user-registration">No user&nbsp;registration</h3> -<p>You don&#8217;t need to register an account on the website to start using it. -You just have to create a project, set a secret code for it, and give -both the url and the code to the people you want to share it with (or -the website can poke them for&nbsp;you).</p> -<h3 id="keeping-things-simple">Keeping things&nbsp;simple</h3> -<p><span class="dquo">&#8220;</span>Keep It Simple, Stupid&#8221; really matches our philosophy here: you want to -add a bill? Okay. Just do it. You just have to enter who paid, for who, -how much, and a description, like you would have done when you&#8217;re back -from the farmer&#8217;s market on raw&nbsp;paper.</p> -<h3 id="no-categories">No&nbsp;categories</h3> -<p>Some people like to organise their stuff into different &#8220;categories&#8221;: -leisure, work, eating, etc. That&#8217;s not something I want (at least to -begin&nbsp;with).</p> -<p>I want things to be simple. Got that? Great. Just add your&nbsp;bills!</p> -<h3 id="balance">Balance</h3> -<p>One of the most useful thing is to know what&#8217;s your &#8220;balance&#8221; compared -to others. In other words, if you&#8217;re negative, you owe money, if you&#8217;re -positive, you have to receive money. This allows you to dispatch who has -to pay for the next thing, in order to re-equilibrate the&nbsp;balance.</p> -<p>Additionally, the system is able to compute for you who has to give how -much to who, in order to reduce the number of transactions needed to -restore the&nbsp;balance.</p> -<h3 id="api"><span class="caps">API</span></h3> -<p>All of what&#8217;s possible to do with the standard web interface is also -available through a <span class="caps">REST</span> <span class="caps">API</span>. I developed a simple <span class="caps">REST</span> toolkit for -flask for this (and I should release&nbsp;it!).</p> -<h2 id="interested">Interested?</h2> -<p>This project is open source. All of us like to share what we are doing -and would be happy to work with new people and implement new ideas. If -you have a nice idea about this, if you want to tweak it or to fill -bugs. Don&#8217;t hesitate a second! The project lives at -<a href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p>Using dbpedia to get languages influences2011-08-16T00:00:00+02:002011-08-16T00:00:00+02:00tag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.html -<p>While browsing the Python&#8217;s wikipedia page, I found information about -the languages influenced by python, and the languages that influenced -python&nbsp;itself.</p> -<p>Well, that&#8217;s kind of interesting to know which languages influenced -others, it could even be more interesting to have an overview of the -connexion between them …</p> -<p>While browsing the Python&#8217;s wikipedia page, I found information about -the languages influenced by python, and the languages that influenced -python&nbsp;itself.</p> -<p>Well, that&#8217;s kind of interesting to know which languages influenced -others, it could even be more interesting to have an overview of the -connexion between them, keeping python as the main&nbsp;focus.</p> -<p>This information is available on the wikipedia page, but not in a really -exploitable format. Hopefully, this information is provided into the -information box present on the majority of wikipedia pages. And… guess -what? there is project with the goal to scrap and index all this -information in a more queriable way, using the semantic web&nbsp;technologies.</p> -<p>Well, you may have guessed it, the project in question in dbpedia, and -exposes information in the form of <span class="caps">RDF</span> triples, which are way more easy -to work with than simple <span class="caps">HTML</span>.</p> -<p>For instance, let&#8217;s take the page about python: -<a href="http://dbpedia.org/page/Python_%28programming_language%29">http://dbpedia.org/page/Python_%28programming_language%29</a></p> -<p>The interesting properties here are &#8220;Influenced&#8221; and &#8220;InfluencedBy&#8221;, -which allows us to get a list of languages. Unfortunately, they are not -really using all the power of the Semantic Web here, and the list is -actually a string with coma separated values in&nbsp;it.</p> -<p>Anyway, we can use a simple rule: All wikipedia pages of programming -languages are either named after the name of the language itself, or -suffixed with &#8220;( programming language)&#8221;, which is the case for&nbsp;python.</p> -<p>So I&#8217;ve built <a href="https://github.com/ametaireau/experiments/blob/master/influences/get_influences.py">a tiny script to extract the information from -dbpedia</a> -and transform them into a shiny graph using&nbsp;graphviz.</p> -<p>After a&nbsp;nice:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>python<span class="w"> </span>get_influences.py<span class="w"> </span>python<span class="w"> </span>dot<span class="w"> </span><span class="p">|</span><span class="w"> </span>dot<span class="w"> </span>-Tpng<span class="w"> </span>&gt;<span class="w"> </span>influences.png -</code></pre></div> - -<p>The result is the following graph (<a href="http://files.lolnet.org/alexis/influences.png">see it directly -here</a>)</p> -<p><img alt="Graph des influances des langages les uns sur les -autres." src="http://files.lolnet.org/alexis/influences.png"></p> -<p>While reading this diagram, keep in mind that it is a) not listing all -the languages and b) keeping a python&nbsp;perspective.</p> -<p>This means that you can trust the scheme by following the arrows from -python to something and from something to python, it is not trying to -get the matching between all the languages at the same time to keep -stuff&nbsp;readable.</p> -<p>It would certainly be possible to have all the connections between all -languages (and the resulting script would be easier) to do so, but the -resulting graph would probably be way less&nbsp;readable.</p> -<p>You can find the script <a href="https://github.com/ametaireau/experiments">on my github -account</a>. Feel free to adapt -it for whatever you want if you feel&nbsp;hackish.</p>Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html -<p>Back in October, I released -<a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of -code I wrote to power this weblog. I had simple needs: I wanted to be -able to use my text editor of choice (vim), a vcs (mercurial) and -restructured text. I started to write a really simple blog engine in …</p> -<p>Back in October, I released -<a href="http://docs.notmyidea.org/alexis/pelican">pelican</a>, a little piece of -code I wrote to power this weblog. I had simple needs: I wanted to be -able to use my text editor of choice (vim), a vcs (mercurial) and -restructured text. I started to write a really simple blog engine in -something like a hundred python lines and released it on&nbsp;github.</p> -<p>And people started contributing. I wasn&#8217;t at all expecting to see people -interested in such a little piece of code, but it turned out that they -were. I refactored the code to make it evolve a bit more by two times -and eventually, in 9 months, got 49 forks, 139 issues and 73 pull&nbsp;requests.</p> -<p><strong>Which is clearly&nbsp;awesome.</strong></p> -<p>I pulled features such as translations, tag clouds, integration with -different services such as twitter or piwik, import from dotclear and -rss, fixed a number of mistakes and improved a lot the codebase. This -was a proof that there is a bunch of people that are willing to make -better softwares just for the sake of&nbsp;fun.</p> -<p>Thank you, guys, you&#8217;re why I like open source so&nbsp;much.</p>Using JPype to bridge python and Java2011-06-11T00:00:00+02:002011-06-11T00:00:00+02:00tag:blog.notmyidea.org,2011-06-11:/using-jpype-to-bridge-python-and-java.html -<p>Java provides some interesting libraries that have no exact equivalent -in python. In my case, the awesome boilerpipe library allows me to -remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other -&#8220;boilerplate&#8221;&nbsp;contents.</p> -<p>Boilerpipe is written in Java. Two solutions then: using java from -python or reimplement boilerpipe …</p> -<p>Java provides some interesting libraries that have no exact equivalent -in python. In my case, the awesome boilerpipe library allows me to -remove uninteresting parts of <span class="caps">HTML</span> pages, like menus, footers and other -&#8220;boilerplate&#8221;&nbsp;contents.</p> -<p>Boilerpipe is written in Java. Two solutions then: using java from -python or reimplement boilerpipe in python. I will let you guess which -one I chosen,&nbsp;meh.</p> -<p>JPype allows to bridge python project with java libraries. It takes -another point of view than Jython: rather than reimplementing python in -Java, both languages are interfacing at the <span class="caps">VM</span> level. This means you -need to start a <span class="caps">VM</span> from your python script, but it does the job and stay -fully compatible with Cpython and its C&nbsp;extensions.</p> -<h2 id="first-steps-with-jpype">First steps with&nbsp;JPype</h2> -<p>Once JPype installed (you&#8217;ll have to hack a bit some files to integrate -seamlessly with your system) you can access java classes by doing -something like&nbsp;that:</p> -<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">jpype</span> -<span class="n">jpype</span><span class="o">.</span><span class="n">startJVM</span><span class="p">(</span><span class="n">jpype</span><span class="o">.</span><span class="n">getDefaultJVMPath</span><span class="p">())</span> - -<span class="c1"># you can then access to the basic java functions</span> -<span class="n">jpype</span><span class="o">.</span><span class="n">java</span><span class="o">.</span><span class="n">lang</span><span class="o">.</span><span class="n">System</span><span class="o">.</span><span class="n">out</span><span class="o">.</span><span class="n">println</span><span class="p">(</span><span class="s2">&quot;hello world&quot;</span><span class="p">)</span> - -<span class="c1"># and you have to shutdown the VM at the end</span> -<span class="n">jpype</span><span class="o">.</span><span class="n">shutdownJVM</span><span class="p">()</span> -</code></pre></div> - -<p>Okay, now we have a hello world, but what we want seems somehow more -complex. We want to interact with java classes, so we will have to load&nbsp;them.</p> -<h2 id="interfacing-with-boilerpipe">Interfacing with&nbsp;Boilerpipe</h2> -<p>To install boilerpipe, you just have to run an ant&nbsp;script:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span><span class="nb">cd</span><span class="w"> </span>boilerpipe -$<span class="w"> </span>ant -</code></pre></div> - -<p>Here is a simple example of how to use boilerpipe in Java, from their&nbsp;sources</p> -<div class="highlight"><pre><span></span><code><span class="kn">package</span><span class="w"> </span><span class="nn">de.l3s.boilerpipe.demo</span><span class="p">;</span> -<span class="kn">import</span><span class="w"> </span><span class="nn">java.net.URL</span><span class="p">;</span> -<span class="kn">import</span><span class="w"> </span><span class="nn">de.l3s.boilerpipe.extractors.ArticleExtractor</span><span class="p">;</span> - -<span class="kd">public</span><span class="w"> </span><span class="kd">class</span> <span class="nc">Oneliner</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kd">static</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">main</span><span class="p">(</span><span class="kd">final</span><span class="w"> </span><span class="n">String</span><span class="o">[]</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="kd">throws</span><span class="w"> </span><span class="n">Exception</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">URL</span><span class="w"> </span><span class="n">url</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">URL</span><span class="p">(</span><span class="s">&quot;http://notmyidea.org&quot;</span><span class="p">);</span> -<span class="w"> </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="n">ArticleExtractor</span><span class="p">.</span><span class="na">INSTANCE</span><span class="p">.</span><span class="na">getText</span><span class="p">(</span><span class="n">url</span><span class="p">));</span> -<span class="w"> </span><span class="p">}</span> -<span class="p">}</span> -</code></pre></div> - -<p>To run&nbsp;it:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>javac<span class="w"> </span>-cp<span class="w"> </span>dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar<span class="w"> </span>src/demo/de/l3s/boilerpipe/demo/Oneliner.java -$<span class="w"> </span>java<span class="w"> </span>-cp<span class="w"> </span>src/demo:dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar<span class="w"> </span>de.l3s.boilerpipe.demo.Oneliner -</code></pre></div> - -<p>Yes, this is kind of ugly, sorry for your eyes. Let&#8217;s try something -similar, but from&nbsp;python</p> -<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">jpype</span> - -<span class="c1"># start the JVM with the good classpaths</span> -<span class="n">classpath</span> <span class="o">=</span> <span class="s2">&quot;dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar&quot;</span> -<span class="n">jpype</span><span class="o">.</span><span class="n">startJVM</span><span class="p">(</span><span class="n">jpype</span><span class="o">.</span><span class="n">getDefaultJVMPath</span><span class="p">(),</span> <span class="s2">&quot;-Djava.class.path=</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="n">classpath</span><span class="p">)</span> - -<span class="c1"># get the Java classes we want to use</span> -<span class="n">DefaultExtractor</span> <span class="o">=</span> <span class="n">jpype</span><span class="o">.</span><span class="n">JPackage</span><span class="p">(</span><span class="s2">&quot;de&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">l3s</span><span class="o">.</span><span class="n">boilerpipe</span><span class="o">.</span><span class="n">extractors</span><span class="o">.</span><span class="n">DefaultExtractor</span> - -<span class="c1"># call them !</span> -<span class="nb">print</span> <span class="n">DefaultExtractor</span><span class="o">.</span><span class="n">INSTANCE</span><span class="o">.</span><span class="n">getText</span><span class="p">(</span><span class="n">jpype</span><span class="o">.</span><span class="n">java</span><span class="o">.</span><span class="n">net</span><span class="o">.</span><span class="n">URL</span><span class="p">(</span><span class="s2">&quot;http://blog.notmyidea.org&quot;</span><span class="p">))</span> -</code></pre></div> - -<p>And you get what you&nbsp;want.</p> -<p>I must say I didn&#8217;t thought it could work so easily. This will allow me -to extract text content from URLs and remove the <em>boilerplate</em> text -easily for infuse (my master thesis project), without having to write -java code,&nbsp;nice!</p>Un coup de main pour mon mémoire !2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire.html -<p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du -reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais -besoin d&#8217;un petit coup de&nbsp;main.</p> -<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui -connaissent …</p> -<p>Ça y est, bientôt la fin. <span class="caps">LA</span> <span class="caps">FIN</span>. La fin des études, et le début du -reste. En attendant je bosse sur mon mémoire de fin d&#8217;études et j&#8217;aurais -besoin d&#8217;un petit coup de&nbsp;main.</p> -<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui -connaissent last.fm, je fais quelque chose de similaire mais pour les -sites internet: en me basant sur ce que vous visitez quotidiennement et -comment vous le visitez (quelles horaires, quelle emplacement -géographique, etc.) je souhaites proposer des liens qui vous -intéresseront potentiellement, en me basant sur l&#8217;avis des personnes -qui ont des profils similaires au&nbsp;votre.</p> -<p>Le projet est loin d&#8217;être terminé, mais la première étape est de -récupérer des données de navigation, idéalement beaucoup de données de -navigation. Donc si vous pouvez me filer un coup de main je vous en -serais éternellement reconnaissant (pour ceux qui font semblant de pas -comprendre, entendez &#8220;tournée&nbsp;générale&#8221;).</p> -<p>J&#8217;ai créé un petit site web (en anglais) qui résume un peu le concept, -qui vous propose de vous inscrire et de télécharger un plugin firefox -qui m&#8217;enverra des information sur les sites que vous visitez (si vous -avez l&#8217;habitude d&#8217;utiliser chrome vous pouvez considérer de switcher à -firefox4 pour les deux prochains mois pour me filer un coup de main). Il -est possible de désactiver le plugin d&#8217;un simple clic si vous souhaitez -garder votre vie privée privée&nbsp;;-)</p> -<p>Le site est par là: <a href="http://infuse.notmyidea.org">http://infuse.notmyidea.org</a>. Une fois le plugin -téléchargé et le compte créé il faut renseigner vos identifiants dans -le plugin en question, et c&#8217;est&nbsp;tout!</p> -<p>A votre bon cœur ! Je récupérerais probablement des données durant les -2 prochains mois pour ensuite les analyser&nbsp;correctement.</p> -<p>Merci pour votre aide&nbsp;!</p>Analyse users’ browsing context to build up a web recommender2011-04-01T00:00:00+02:002011-04-01T00:00:00+02:00tag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.html -<p>No, this is not an april&#8217;s fool&nbsp;;)</p> -<p>Wow, it&#8217;s been a long time. My year in Oxford is going really well. I -realized few days ago that the end of the year is approaching really -quickly. Exams are coming in one month or such and then I&#8217;ll …</p> -<p>No, this is not an april&#8217;s fool&nbsp;;)</p> -<p>Wow, it&#8217;s been a long time. My year in Oxford is going really well. I -realized few days ago that the end of the year is approaching really -quickly. Exams are coming in one month or such and then I&#8217;ll be working -full time on my dissertation&nbsp;topic.</p> -<p>When I learned we&#8217;ll have about 6 month to work on something, I first -thought about doing a packaging related stuff, but finally decided to -start something new. After all, that&#8217;s the good time to&nbsp;learn.</p> -<p>Since a long time, I&#8217;m being impressed by the <a href="http://last.fm">last.fm</a> -recommender system. They&#8217;re <em>scrobbling</em> the music I listen to since -something like 5 years now and the recommendations they&#8217;re doing are -really nice and accurate (I discovered <strong>a lot</strong> of great artists -listening to the &#8220;neighbour radio&#8221;.) (by the way, <a href="http://lastfm.com/user/akounet/">here -is</a> my lastfm&nbsp;account)</p> -<p>So I decided to work on recommender systems, to better understand what -is it&nbsp;about.</p> -<p>Recommender systems are usually used to increase the sales of products -(like Amazon.com does) which is not really what I&#8217;m looking for (The one -who know me a bit know I&#8217;m kind of sick about all this consumerism going&nbsp;on).</p> -<p>Actually, the most simple thing I thought of was the web: I&#8217;m browsing -it quite every day and each time new content appears. I&#8217;ve stopped to -follow <a href="https://bitbucket.org/bruno/aspirator/">my feed reader</a> because -of the information overload, and reduced drastically the number of -people I follow <a href="http://twitter.com/ametaireau/">on twitter</a>.</p> -<p>Too much information kills the&nbsp;information.</p> -<p>You shall got what will be my dissertation topic: a recommender system -for the web. Well, such recommender systems already exists, so I will -try to add contextual information to them: you&#8217;re probably not -interested by the same topics at different times of the day, or -depending on the computer you&#8217;re using. We can also probably make good -use of the way you browse to create groups into the content you&#8217;re -browsing (or even use the great firefox4 tab group&nbsp;feature).</p> -<p>There is a large part of concerns to have about user&#8217;s privacy as&nbsp;well.</p> -<p>Here is my proposal (copy/pasted from the one I had to do for my&nbsp;master)</p> -<h2 id="introduction-and-rationale">Introduction and&nbsp;rationale</h2> -<p>Nowadays, people surf the web more and more often. New web pages are -created each day so the amount of information to retrieve is more -important as the time passes. These users uses the web in different -contexts, from finding cooking recipes to technical&nbsp;articles.</p> -<p>A lot of people share the same interest to various topics, and the -quantity of information is such than it&#8217;s really hard to triage them -efficiently without spending hours doing it. Firstly because of the huge -quantity of information but also because the triage is something -relative to each person. Although, this triage can be facilitated by -fetching the browsing information of all particular individuals and put -the in&nbsp;perspective.</p> -<p>Machine learning is a branch of Artificial Intelligence (<span class="caps">AI</span>) which deals -with how a program can learn from data. Recommendation systems are a -particular application area of machine learning which is able to -recommend things (links in our case) to the users, given a particular -database containing the previous choices users have&nbsp;made.</p> -<p>This browsing information is currently available in browsers. Even if it -is not in a very usable format, it is possible to transform it to -something useful. This information gold mine just wait to be used. -Although, it is not as simple as it can seems at the first approach: It -is important to take care of the context the user is in while browsing -links. For instance, It&#8217;s more likely that during the day, a computer -scientist will browse computing related links, and that during the -evening, he browse cooking recipes or something&nbsp;else.</p> -<p>Page contents are also interesting to analyse, because that&#8217;s what -people browse and what actually contain the most interesting part of the -information. The raw data extracted from the browsing can then be -translated into something more useful (namely tags, type of resource, -visit frequency, navigation context&nbsp;etc.)</p> -<p>The goal of this dissertation is to create a recommender system for web -links, including this context&nbsp;information.</p> -<p>At the end of the dissertation, different pieces of software will be -provided, from raw data collection from the browser to a recommendation&nbsp;system.</p> -<h2 id="background-review">Background&nbsp;Review</h2> -<p>This dissertation is mainly about data extraction, analysis and -recommendation systems. Two different research area can be isolated: -Data preprocessing and Information&nbsp;filtering.</p> -<p>The first step in order to make recommendations is to gather some data. -The more data we have available, the better it is (T. Segaran, 2007). -This data can be retrieved in various ways, one of them is to get it -directly from user&#8217;s&nbsp;browsers.</p> -<h3 id="data-preparation-and-extraction">Data preparation and&nbsp;extraction</h3> -<p>The data gathered from browsers is basically URLs and additional -information about the context of the navigation. There is clearly a need -to extract more information about the meaning of the data the user is -browsing, starting by the content of the web&nbsp;pages.</p> -<p>Because the information provided on the current Web is not meant to be -read by machines (T. Berners Lee, 2001) there is a need of tools to -extract meaning from web pages. The information needs to be preprocessed -before stored in a machine readable format, allowing to make -recommendations (Choochart et Al,&nbsp;2004).</p> -<p>Data preparation is composed of two steps: cleaning and structuring ( -Castellano et Al, 2007). Because raw data can contain a lot of un-needed -text (such as menus, headers etc.) and need to be cleaned prior to be -stored. Multiple techniques can be used here and belongs to boilerplate -removal and full text extraction (Kohlschütter et Al,&nbsp;2010).</p> -<p>Then, structuring the information: category, type of content (news, -blog, wiki) can be extracted from raw data. This kind of information is -not clearly defined by <span class="caps">HTML</span> pages so there is a need of tools to -recognise&nbsp;them.</p> -<p>Some context-related information can also be inferred from each -resource. It can go from the visit frequency to the navigation group the -user was in while browsing. It is also possible to determine if the user -&#8220;liked&#8221; a resource, and determine a mark for it, which can be used by -information filtering a later step (T. Segaran,&nbsp;2007).</p> -<p>At this stage, structuring the data is required. Storing this kind of -information in <span class="caps">RDBMS</span> can be a bit tedious and require complex queries to -get back the data in an usable format. Graph databases can play a major -role in the simplification of information storage and&nbsp;querying.</p> -<h3 id="information-filtering">Information&nbsp;filtering</h3> -<p>To filter the information, three techniques can be used (Balabanovic et -Al,&nbsp;1997):</p> -<ul> -<li>The content-based approach states that if an user have liked - something in the past, he is more likely to like similar things in - the future. So it&#8217;s about establishing a profile for the user and - compare new items against&nbsp;it.</li> -<li>The collaborative approach will rather recommend items that other - similar users have liked. This approach consider only the - relationship between users, and not the profile of the user we are - making recommendations&nbsp;to.</li> -<li>the hybrid approach, which appeared recently combine both of the - previous approaches, giving recommendations when items score high - regarding user&#8217;s profile, or if a similar user already liked&nbsp;it.</li> -</ul> -<p>Grouping is also something to consider at this stage (G. Myatt, 2007). -Because we are dealing with huge amount of data, it can be useful to -detect group of data that can fit together. Data clustering is able to -find such groups (T. Segaran,&nbsp;2007).</p> -<p>References:</p> -<ul> -<li>Balabanović, M., <span class="amp">&amp;</span> Shoham, Y. (1997). Fab: content-based, - collaborative recommendation. Communications of the <span class="caps">ACM</span>, 40(3), - 66–72. <span class="caps">ACM</span>. Retrieved March 1, 2011, from - <a href="http://portal.acm.org/citation.cfm?id=245108.245124&amp;">http://portal.acm.org/citation.cfm?id=245108.245124&amp;</a>;.</li> -<li>Berners-Lee, T., Hendler, J., <span class="amp">&amp;</span> Lassila, O. (2001). The semantic - web: Scientific american. Scientific American, 284(5), 34–43. - Retrieved November 21, 2010, from - <a href="http://www.citeulike.org/group/222/article/1176986">http://www.citeulike.org/group/222/article/1176986</a>.</li> -<li>Castellano, G., Fanelli, A., <span class="amp">&amp;</span> Torsello, M. (2007). <span class="caps">LODAP</span>: a LOg - DAta Preprocessor for mining Web browsing patterns. Proceedings of - the 6th Conference on 6th <span class="caps">WSEAS</span> Int. Conf. on Artificial - Intelligence, Knowledge Engineering and Data Bases-Volume 6 (p. - 12–17). World Scientific and Engineering Academy and Society - (<span class="caps">WSEAS</span>). Retrieved March 8, 2011, from - <a href="http://portal.acm.org/citation.cfm?id=1348485.1348488">http://portal.acm.org/citation.cfm?id=1348485.1348488</a>.</li> -<li>Kohlschutter, C., Fankhauser, P., <span class="amp">&amp;</span> Nejdl, W. (2010). Boilerplate - detection using shallow text features. Proceedings of the third <span class="caps">ACM</span> - international conference on Web search and data mining (p. 441–450). - <span class="caps">ACM</span>. Retrieved March 8, 2011, from - <a href="http://portal.acm.org/citation.cfm?id=1718542">http://portal.acm.org/citation.cfm?id=1718542</a>.</li> -<li>Myatt, <span class="caps">G. J.</span>(2007). Making Sense of Data: A Practical Guide to - Exploratory Data Analysis and Data&nbsp;Mining.</li> -<li>Segaran, T. (2007). Collective&nbsp;Intelligence.</li> -</ul> -<h2 id="privacy">Privacy</h2> -<p>The first thing that&#8217;s come to people minds when it comes to process -their browsing data is privacy. People don&#8217;t want to be stalked. That&#8217;s -perfectly right, and I don&#8217;t&nbsp;either.</p> -<p>But such a system don&#8217;t have to deal with people identities. It&#8217;s -completely possible to process completely anonymous data, and that&#8217;s -probably what I&#8217;m gonna&nbsp;do.</p> -<p>By the way, if you have interesting thoughts about that, if you do know -projects that do seems related, fire the comments&nbsp;!</p> -<h2 id="whats-the-plan">What&#8217;s the plan&nbsp;?</h2> -<p>There is a lot of different things to explore, especially because I&#8217;m a -complete novice in that&nbsp;field.</p> -<ul> -<li>I want to develop a firefox plugin, to extract the browsing - informations ( still, I need to know exactly which kind of - informations to retrieve). The idea is to provide some <em>raw</em> - browsing data, and then to transform it and to store it in the - better possible&nbsp;way.</li> -<li>Analyse how to store the informations in a graph database. What can - be the different methods to store this data and to visualize the - relationship between different pieces of data? How can I define the - different contexts, and add those informations in the&nbsp;db?</li> -<li>Process the data using well known recommendation algorithms. Compare - the results and criticize their&nbsp;value.</li> -</ul> -<p>There is plenty of stuff I want to try during this&nbsp;experimentation:</p> -<ul> -<li>I want to try using Geshi to visualize the connexion between the - links, and the&nbsp;contexts</li> -<li>Try using graph databases such as&nbsp;Neo4j</li> -<li>Having a deeper look at tools such as scikit.learn (a machine - learning toolkit in&nbsp;python)</li> -<li>Analyse web pages in order to categorize them. Processing their - contents as well, to do some keyword based classification will be&nbsp;done.</li> -</ul> -<p>Lot of work on its way, yay&nbsp;!</p>Working directly on your server? How to backup and sync your dev environment with unison2011-03-16T00:00:00+01:002011-03-16T00:00:00+01:00tag:blog.notmyidea.org,2011-03-16:/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html -<p>I have a server running freebsd since some time now, and was wondering -about the possibility to directly have a development environment ready -to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> -<p>Since I use vim to code, and spend most of my …</p> -<p>I have a server running freebsd since some time now, and was wondering -about the possibility to directly have a development environment ready -to use when I get a internet connexion, even if I&#8217;m not on my&nbsp;computer.</p> -<p>Since I use vim to code, and spend most of my time in a console while -developing, it&#8217;s possible to work via ssh, from&nbsp;everywhere.</p> -<p>The only problem is the synchronisation of the source code, config files -etc. from my machine to the&nbsp;server.</p> -<p>Unison provides an interesting way to synchronise two folders, even over -a network. So let&#8217;s do it&nbsp;!</p> -<h2 id="creating-the-jail">Creating the&nbsp;jail</h2> -<p>In case you don&#8217;t use FreeBSD, you can skip this&nbsp;section.</p> -<div class="highlight"><pre><span></span><code># I have a flavour jail named default -$ ezjail-admin -f default workspace.notmyidea.org 172.19.1.6 -$ ezjail-admin start workspace.notmyidea.org -</code></pre></div> - -<p>In my case, because the &#8220;default&#8221; flavour contains already a lot of -interesting things, my jail come already setup with ssh, bash and vim -for instance, but maybe you&#8217;ll need it in your&nbsp;case.</p> -<p>I want to be redirected to the ssh of the jail when I connect to the -host with the 20006 port. Add lines in <code>/etc/pf.conf</code>:</p> -<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="nv">workspace_jail</span><span class="o">=</span><span class="s2">&quot;172.19.1.6&quot;</span> -<span class="w"> </span>rdr<span class="w"> </span>on<span class="w"> </span><span class="nv">$ext_if</span><span class="w"> </span>proto<span class="w"> </span>tcp<span class="w"> </span>from<span class="w"> </span>any<span class="w"> </span>to<span class="w"> </span><span class="nv">$ext_ip</span><span class="w"> </span>port<span class="w"> </span><span class="m">20006</span><span class="w"> </span>-&gt;<span class="w"> </span><span class="nv">$workspace_jail</span><span class="w"> </span>port<span class="w"> </span><span class="m">22</span> -</code></pre></div> - -<p>Reload packet filter&nbsp;rules</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>/etc/rc.d/pf<span class="w"> </span>reload -</code></pre></div> - -<h2 id="working-with-unison">Working with&nbsp;unison</h2> -<p>Now that we&#8217;ve set up the jail. Set up unison on the server and on your -client. Unison is available on the freebsd ports so just install&nbsp;it</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>notmyidea.org<span class="w"> </span>-p<span class="w"> </span><span class="m">20006</span> -$<span class="w"> </span>make<span class="w"> </span>-C<span class="w"> </span>/usr/ports/net/unison-nox11<span class="w"> </span>config-recursive -$<span class="w"> </span>make<span class="w"> </span>-C<span class="w"> </span>/usr/ports/net/unison-nox11<span class="w"> </span>package-recursive -</code></pre></div> - -<p>Install as well unison on your local machine. Double check to install -the same version on the client and on the server. Ubuntu contains the -2.27.57 as well as the&nbsp;2.32.52.</p> -<p>Check that unison is installed and reachable via ssh from your&nbsp;machine</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>ssh<span class="w"> </span>notmyidea.org<span class="w"> </span>-p<span class="w"> </span><span class="m">20006</span><span class="w"> </span>unison<span class="w"> </span>-version -unison<span class="w"> </span>version<span class="w"> </span><span class="m">2</span>.27.157 -$<span class="w"> </span>unison<span class="w"> </span>-version -unison<span class="w"> </span>version<span class="w"> </span><span class="m">2</span>.27.57 -</code></pre></div> - -<h2 id="let-sync-our-folders">Let sync our&nbsp;folders</h2> -<p>The first thing I want to sync is my vim configuration. Well, it&#8217;s -already <a href="http://github.com/ametaireau/dotfiles/">in a git repository</a> -but let&#8217;s try to use unison for it right&nbsp;now.</p> -<p>I have two machines then: workspace, the jail, and ecureuil my&nbsp;laptop.</p> -<div class="highlight"><pre><span></span><code>unison<span class="w"> </span>.vim<span class="w"> </span>ssh://notmyidea.org:20006/.vim -unison<span class="w"> </span>.vimrc<span class="w"> </span>ssh://notmyidea.org:20006/.vimrc -</code></pre></div> - -<p>It is also possible to put all the informations in a config file, and -then to only run unison. (fire up vim&nbsp;\~/.unison/default.prf.</p> -<p>Here is my&nbsp;config:</p> -<div class="highlight"><pre><span></span><code><span class="w"> </span><span class="na">root</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">/home/alexis</span> -<span class="w"> </span><span class="na">root</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">ssh://notmyidea.org:20006</span> - -<span class="w"> </span><span class="na">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">.vimrc</span> -<span class="w"> </span><span class="na">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">dotfiles</span> -<span class="w"> </span><span class="na">path</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">dev</span> - -<span class="w"> </span><span class="na">follow</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">Name *</span> -</code></pre></div> - -<p>My vimrc is in fact a symbolic link on my laptop, but I don&#8217;t want to -specify each of the links to unison. That&#8217;s why the follow = Name * is&nbsp;for.</p> -<p>The folders you want to synchronize are maybe a bit large. If so, -considering others options such as rsync for the first import may be a -good idea (I enjoyed my university huge upload bandwith to upload <span class="caps">2GB</span> in -20mn&nbsp;;)</p> -<h2 id="run-the-script-frequently">Run the script&nbsp;frequently</h2> -<p>Once that done, you just need to run the unison command line some times -when you want to sync your two machines. I&#8217;ve wrote a tiny script to get -some feedback from the&nbsp;sync:</p> -<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">os</span> -<span class="kn">from</span> <span class="nn">datetime</span> <span class="kn">import</span> <span class="n">datetime</span> - -<span class="n">DEFAULT_LOGFILE</span> <span class="o">=</span> <span class="s2">&quot;~/unison.log&quot;</span> -<span class="n">PROGRAM_NAME</span> <span class="o">=</span> <span class="s2">&quot;Unison syncer&quot;</span> - -<span class="k">def</span> <span class="nf">sync</span><span class="p">(</span><span class="n">logfile</span><span class="o">=</span><span class="n">DEFAULT_LOGFILE</span><span class="p">,</span> <span class="n">program_name</span><span class="o">=</span><span class="n">PROGRAM_NAME</span><span class="p">):</span> - <span class="c1"># init</span> - <span class="n">display_message</span> <span class="o">=</span> <span class="kc">True</span> - <span class="n">error</span> <span class="o">=</span> <span class="kc">False</span> - - <span class="n">before</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> - <span class="c1"># call unison to make the sync</span> - <span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">&#39;unison -batch &gt; </span><span class="si">{0}</span><span class="s1">&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">logfile</span><span class="p">))</span> - - <span class="c1"># get the duration of the operation</span> - <span class="n">td</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">now</span><span class="p">()</span> <span class="o">-</span> <span class="n">before</span> - <span class="n">delta</span> <span class="o">=</span> <span class="p">(</span><span class="n">td</span><span class="o">.</span><span class="n">microseconds</span> <span class="o">+</span> <span class="p">(</span><span class="n">td</span><span class="o">.</span><span class="n">seconds</span> <span class="o">+</span> <span class="n">td</span><span class="o">.</span><span class="n">days</span> <span class="o">*</span> <span class="mi">24</span> <span class="o">*</span> <span class="mi">3600</span><span class="p">)</span> <span class="o">*</span> <span class="mi">10</span><span class="o">**</span><span class="mi">6</span><span class="p">)</span> <span class="o">/</span> <span class="mi">10</span><span class="o">**</span><span class="mi">6</span> - - <span class="c1"># check what was the last entry in the log</span> - <span class="n">log</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="n">os</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">expanduser</span><span class="p">(</span><span class="n">logfile</span><span class="p">))</span> - <span class="n">lines</span> <span class="o">=</span> <span class="n">log</span><span class="o">.</span><span class="n">readlines</span><span class="p">()</span> - <span class="k">if</span> <span class="s1">&#39;No updates to propagate&#39;</span> <span class="ow">in</span> <span class="n">lines</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]:</span> - <span class="n">display_message</span> <span class="o">=</span> <span class="kc">False</span> - <span class="k">else</span><span class="p">:</span> - <span class="n">output</span> <span class="o">=</span> <span class="p">[</span><span class="n">l</span> <span class="k">for</span> <span class="n">l</span> <span class="ow">in</span> <span class="n">lines</span> <span class="k">if</span> <span class="s2">&quot;Synchronization&quot;</span> <span class="ow">in</span> <span class="n">l</span><span class="p">]</span> - - <span class="n">message</span> <span class="o">=</span> <span class="n">output</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span> - <span class="n">message</span> <span class="o">+=</span> <span class="s2">&quot; It took </span><span class="si">{0}</span><span class="s2">s.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">delta</span><span class="p">)</span> - - <span class="k">if</span> <span class="n">display_message</span><span class="p">:</span> - <span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="s1">&#39;notify-send -i </span><span class="si">{2}</span><span class="s1"> &quot;</span><span class="si">{0}</span><span class="s1">&quot; &quot;</span><span class="si">{1}</span><span class="s1">&quot;&#39;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">program_name</span><span class="p">,</span> <span class="n">message</span><span class="p">,</span> - <span class="s1">&#39;error&#39;</span> <span class="k">if</span> <span class="n">error</span> <span class="k">else</span> <span class="s1">&#39;info&#39;</span><span class="p">))</span> - -<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">&quot;__main__&quot;</span><span class="p">:</span> - <span class="n">sync</span><span class="p">()</span> -</code></pre></div> - -<p>This is probably perfectible, but that does the&nbsp;job.</p> -<p>Last step is to tell you machine to run that frequently. That&#8217;s what -crontab is made for, so let&#8217;s <code>crontab -e</code>:</p> -<div class="highlight"><pre><span></span><code> $ * */3 * * * . ~/.Xdbus; /usr/bin/python /home/alexis/dev/python/unison-syncer/sync.py -</code></pre></div> - -<p>The \~/.Xdbus allows cron to communicate with your X11 session. Here is -its&nbsp;content.</p> -<div class="highlight"><pre><span></span><code><span class="ch">#!/bin/bash</span> - -<span class="c1"># Get the pid of nautilus</span> -<span class="nv">nautilus_pid</span><span class="o">=</span><span class="k">$(</span>pgrep<span class="w"> </span>-u<span class="w"> </span><span class="nv">$LOGNAME</span><span class="w"> </span>-n<span class="w"> </span>nautilus<span class="k">)</span> - -<span class="c1"># If nautilus isn&#39;t running, just exit silently</span> -<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>-z<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$nautilus_pid</span><span class="s2">&quot;</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span> -<span class="nb">exit</span><span class="w"> </span><span class="m">0</span> -<span class="k">fi</span> - -<span class="c1"># Grab the DBUS_SESSION_BUS_ADDRESS variable from nautilus&#39;s environment</span> -<span class="nb">eval</span><span class="w"> </span><span class="k">$(</span>tr<span class="w"> </span><span class="s1">&#39;\0&#39;</span><span class="w"> </span><span class="s1">&#39;\n&#39;</span><span class="w"> </span>&lt;<span class="w"> </span>/proc/<span class="nv">$nautilus_pid</span>/environ<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span><span class="s1">&#39;^DBUS_SESSION_BUS_ADDRESS=&#39;</span><span class="k">)</span> - -<span class="c1"># Check that we actually found it</span> -<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>-z<span class="w"> </span><span class="s2">&quot;</span><span class="nv">$DBUS_SESSION_BUS_ADDRESS</span><span class="s2">&quot;</span><span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span> -<span class="nb">echo</span><span class="w"> </span><span class="s2">&quot;Failed to find bus address&quot;</span><span class="w"> </span>&gt;<span class="p">&amp;</span><span class="m">2</span> -<span class="nb">exit</span><span class="w"> </span><span class="m">1</span> -<span class="k">fi</span> - -<span class="c1"># export it so that child processes will inherit it</span> -<span class="nb">export</span><span class="w"> </span>DBUS_SESSION_BUS_ADDRESS -</code></pre></div> - -<p>And it comes from -<a href="http://ubuntuforums.org/showthread.php?p=10148738#post10148738">here</a>.</p> -<p>A sync takes about 20s + the upload time on my machine, which stay -acceptable for all of my&nbsp;developments.</p>Wrap up of the distutils2 paris’ sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.html -<p>Finally, thanks to a bunch of people that helped me to pay my train and -bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> -<p>They have been a bit more than 10 people to come during the sprint, and -it was very productive. Here&#8217;s a taste …</p> -<p>Finally, thanks to a bunch of people that helped me to pay my train and -bus tickets, I&#8217;ve made it to paris for the distutils2&nbsp;sprint.</p> -<p>They have been a bit more than 10 people to come during the sprint, and -it was very productive. Here&#8217;s a taste of what we&#8217;ve been working&nbsp;on:</p> -<ul> -<li>the datafiles, a way to specify and to handle the installation of - files which are not python-related (pictures, manpages and so&nbsp;on).</li> -<li>mkgcfg, a tool to help you to create a setup.cfg in minutes (and - with funny&nbsp;examples)</li> -<li>converters from setup.py scripts. We do now have a piece of code - which reads your current setup.py file and fill in some fields in - the setup.cfg for&nbsp;you.</li> -<li>a compatibility layer for distutils1, so it can read the setup.cfg - you will wrote for distutils2&nbsp;:-)</li> -<li>the uninstaller, so it&#8217;s now possible to uninstall what have been - installed by distutils2 (see <span class="caps">PEP</span>&nbsp;376)</li> -<li>the installer, and the setuptools compatibility layer, which will - allow you to rely on setuptools&#8217; based distributions (and there are - plenty of&nbsp;them!)</li> -<li>The compilers, so they are more flexible than they were. Since - that&#8217;s an obscure part of the code for distutils2 commiters (it - comes directly from the distutils1 ages), having some guys who - understood the problematics here was a&nbsp;must.</li> -</ul> -<p>Some people have also tried to port their packaging from distutils1 to -distutils2. They have spotted a number of bugs and made some -improvements to the code, to make it more friendly to&nbsp;use.</p> -<p>I&#8217;m really pleased to see how newcomers went trough the code, and -started hacking so fast. I must say it wasn&#8217;t the case when we started -to work on distutils1 so that&#8217;s a very good point: people now can hack -the code quicker than they could&nbsp;before.</p> -<p>Some of the features here are not <em>completely</em> finished yet, but are on -the tubes, and will be ready for a release (hopefully) at the end of the&nbsp;week.</p> -<p>Big thanks to logilab for hosting (and sponsoring my train ticket) and -providing us food, and to bearstech for providing some money for -breakfast and&nbsp;bears^Wbeers.</p> -<p>Again, a big thanks to all the people who gave me money to pay the -transport, I really wasn&#8217;t expecting such thing to happen&nbsp;:-)</p>PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.html -<p>By now, there are two ways to retrieve data from PyPI (the Python -Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The -simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several -existing&nbsp;drawbacks.</p> -<p>Basically, if you want to …</p> -<p>By now, there are two ways to retrieve data from PyPI (the Python -Package Index). You can both rely on xml/rpc or on the &#8220;simple&#8221; <span class="caps">API</span>. The -simple <span class="caps">API</span> is not so simple to use as the name suggest, and have several -existing&nbsp;drawbacks.</p> -<p>Basically, if you want to use informations coming from the simple <span class="caps">API</span>, -you will have to parse web pages manually, to extract informations using -some black vodoo magic. Badly, magic have a price, and it&#8217;s sometimes -impossible to get exactly the informations you want to get from this -index. That&#8217;s the technique currently being used by distutils2, -setuptools and&nbsp;pip.</p> -<p>On the other side, while <span class="caps">XML</span>/<span class="caps">RPC</span> is working fine, it&#8217;s requiring extra -work to the python servers each time you request something, which can -lead to some outages from time to time. Also, it&#8217;s important to point -out that, even if PyPI have a mirroring infrastructure, it&#8217;s only for -the so-called <em>simple</em> <span class="caps">API</span>, and not for the <span class="caps">XML</span>/<span class="caps">RPC</span>.</p> -<h2 id="couchdb">CouchDB</h2> -<p>Here comes CouchDB. CouchDB is a document oriented database, that knows -how to speak <span class="caps">REST</span> and <span class="caps">JSON</span>. It&#8217;s easy to use, and provides out of the -box a replication&nbsp;mechanism.</p> -<h2 id="so-what">So, what&nbsp;?</h2> -<p>Hmm, I&#8217;m sure you got it. I&#8217;ve wrote a piece of software to link -informations from PyPI to a CouchDB instance. Then you can replicate all -the PyPI index with only one <span class="caps">HTTP</span> request on the CouchDB server. You can -also access the informations from the index directly using a <span class="caps">REST</span> <span class="caps">API</span>, -speaking json.&nbsp;Handy.</p> -<p>So PyPIonCouch is using the PyPI <span class="caps">XML</span>/<span class="caps">RPC</span> <span class="caps">API</span> to get data from PyPI, and -generate records in the CouchDB&nbsp;instance.</p> -<p>The final goal is to avoid to rely on this &#8220;simple&#8221; <span class="caps">API</span>, and rely on a -<span class="caps">REST</span> insterface instead. I have set up a couchdb server on my server, -which is available at -<a href="http://couchdb.notmyidea.org/_utils/database.html?pypi">http://couchdb.notmyidea.org/_utils/database.html?pypi</a>.</p> -<p>There is not a lot to see there for now, but I&#8217;ve done the first import -from PyPI yesterday and all went fine: it&#8217;s possible to access the -metadata of all PyPI projects via a <span class="caps">REST</span> interface. Next step is to -write a client for this <span class="caps">REST</span> interface in&nbsp;distutils2.</p> -<h2 id="example">Example</h2> -<p>For now, you can use pypioncouch via the command line, or via the python -<span class="caps">API</span>.</p> -<h3 id="using-the-command-line">Using the command&nbsp;line</h3> -<p>You can do something like that for a full import. This <strong>will</strong> take -long, because it&#8217;s fetching all the projects at pypi and importing their&nbsp;metadata:</p> -<div class="highlight"><pre><span></span><code><span class="err">$</span> <span class="n">pypioncouch</span> <span class="o">--</span><span class="n">fullimport</span> <span class="n">http</span><span class="p">:</span><span class="o">//</span><span class="n">your</span><span class="o">.</span><span class="n">couchdb</span><span class="o">.</span><span class="n">instance</span><span class="o">/</span> -</code></pre></div> - -<p>If you already have the data on your couchdb instance, you can just -update it with the last informations from pypi. <strong>However, I recommend -to just replicate the principal node, hosted at -<a href="http://couchdb.notmyidea.org/pypi/">http://couchdb.notmyidea.org/pypi/</a></strong>, to avoid the duplication of&nbsp;nodes:</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pypioncouch<span class="w"> </span>--update<span class="w"> </span>http://your.couchdb.instance/ -</code></pre></div> - -<p>The principal node is updated once a day by now, I&#8217;ll try to see if it&#8217;s -enough, and ajust with the&nbsp;time.</p> -<h3 id="using-the-python-api">Using the python <span class="caps">API</span></h3> -<p>You can also use the python <span class="caps">API</span> to interact with&nbsp;pypioncouch:</p> -<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="kn">from</span> <span class="nn">pypioncouch</span> <span class="kn">import</span> <span class="n">XmlRpcImporter</span><span class="p">,</span> <span class="n">import_all</span><span class="p">,</span> <span class="n">update</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">full_import</span><span class="p">()</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">update</span><span class="p">()</span> -</code></pre></div> - -<h2 id="whats-next">What&#8217;s next&nbsp;?</h2> -<p>I want to make a couchapp, in order to navigate PyPI easily. Here are -some of the features I want to&nbsp;propose:</p> -<ul> -<li>List all the available&nbsp;projects</li> -<li>List all the projects, filtered by&nbsp;specifiers</li> -<li>List all the projects by&nbsp;author/maintainer</li> -<li>List all the projects by&nbsp;keywords</li> -<li>Page for each&nbsp;project.</li> -<li>Provide a PyPI &#8220;Simple&#8221; <span class="caps">API</span> equivalent, even if I want to replace - it, I do think it will be really easy to setup mirrors that way, - with the out of the box couchdb&nbsp;replication</li> -</ul> -<p>I also still need to polish the import mechanism, so I can directly -store in&nbsp;couchdb:</p> -<ul> -<li>The <span class="caps">OPML</span> files for each&nbsp;project</li> -<li>The upload_time as couchdb friendly format (list of&nbsp;int)</li> -<li>The tags as lists (currently it&#8217;s only a string separated by&nbsp;spaces</li> -</ul> -<p>The work I&#8217;ve done by now is available on -<a href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it&#8217;s -still a work in progress, and everything can break at any time. However, -any feedback will be appreciated&nbsp;!</p>Help me to go to the distutils2 paris’ sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.html -<p><strong>Edit: Thanks to logilab and some amazing people, I can make it to -paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> -<p>There will be a distutils2 sprint from the 27th to the 30th of january, -thanks to logilab which will host the&nbsp;event.</p> -<p>You can find more …</p> -<p><strong>Edit: Thanks to logilab and some amazing people, I can make it to -paris for the sprint. Many thanks to them for the&nbsp;support!</strong></p> -<p>There will be a distutils2 sprint from the 27th to the 30th of january, -thanks to logilab which will host the&nbsp;event.</p> -<p>You can find more informations about the sprint on the wiki page of the -event (<a href="http://wiki.python.org/moin/Distutils/SprintParis">http://wiki.python.org/moin/Distutils/SprintParis</a>).</p> -<p>I really want to go there but I&#8217;m unfortunately blocked in <span class="caps">UK</span> for money -reasons. The cheapest two ways I&#8217;ve found is about £80, which I can&#8217;t -afford. Following some advices on #distutils, I&#8217;ve set up a ChipIn -account for that, so if some people want to help me making it to go -there, they can give me some money that&nbsp;way.</p> -<p>I&#8217;ll probably work on the installer (to support old distutils and -setuptools distributions) and on the uninstaller (depending on the first -task). If I can&#8217;t make it to paris, I&#8217;ll hang around on <span class="caps">IRC</span> to give some -help while&nbsp;needed.</p> -<p>If you want to contribute some money to help me go there, feel free to -use this chipin page: -<a href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> -<p>Thanks for your support&nbsp;!</p>How to reboot your bebox using the CLI2010-10-21T00:00:00+02:002010-10-21T00:00:00+02:00tag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.html -<p>I&#8217;ve an internet connection which, for some obscure reasons, tend to be -very slow from time to time. After rebooting the box (yes, that&#8217;s a hard -solution), all the things seems to go fine&nbsp;again.</p> -<h2 id="edit-using-grep"><span class="caps">EDIT</span> : Using&nbsp;grep</h2> -<p>After a bit of reflexion, that&#8217;s also really easy …</p> -<p>I&#8217;ve an internet connection which, for some obscure reasons, tend to be -very slow from time to time. After rebooting the box (yes, that&#8217;s a hard -solution), all the things seems to go fine&nbsp;again.</p> -<h2 id="edit-using-grep"><span class="caps">EDIT</span> : Using&nbsp;grep</h2> -<p>After a bit of reflexion, that&#8217;s also really easy to do using directly -the command line tools curl, grep and tail (but really harder to&nbsp;read).</p> -<div class="highlight"><pre><span></span><code>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>-u<span class="w"> </span>joel:joel<span class="w"> </span>http://bebox.config/cgi/b/info/restart/<span class="se">\?</span>be<span class="se">\=</span><span class="m">0</span><span class="se">\&amp;</span>l0<span class="se">\=</span><span class="m">1</span><span class="se">\&amp;</span>l1<span class="se">\=</span><span class="m">0</span><span class="se">\&amp;</span>tid<span class="se">\=</span>RESTART<span class="w"> </span>-d<span class="w"> </span><span class="s2">&quot;0=17&amp;2=`curl -u joel:joel http://bebox.config/cgi/b/info/restart/\?be\=0\&amp;l0\=1\&amp;l1\=0\&amp;tid\=RESTART | grep -o &quot;</span><span class="nv">name</span><span class="o">=</span><span class="s1">&#39;2&#39;</span><span class="w"> </span><span class="nv">value</span><span class="o">=</span><span class="err">&#39;</span><span class="o">[</span><span class="m">0</span>-9<span class="o">]</span><span class="se">\+</span><span class="s2">&quot; | grep -o &quot;</span><span class="o">[</span><span class="m">0</span>-9<span class="o">]</span><span class="se">\+</span><span class="s2">&quot; | tail -n 1`&amp;1&quot;</span> -</code></pre></div> - -<h2 id="the-python-version">The Python&nbsp;version</h2> -<p>Well, that&#8217;s not the optimal solution, that&#8217;s a bit &#8220;gruik&#8221;, but it&nbsp;works.</p> -<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">urllib2</span> -<span class="kn">import</span> <span class="nn">urlparse</span> -<span class="kn">import</span> <span class="nn">re</span> -<span class="kn">import</span> <span class="nn">argparse</span> - -<span class="n">REBOOT_URL</span> <span class="o">=</span> <span class="s1">&#39;/b/info/restart/?be=0&amp;l0=1&amp;l1=0&amp;tid=RESTART&#39;</span> -<span class="n">BOX_URL</span> <span class="o">=</span> <span class="s1">&#39;http://bebox.config/cgi&#39;</span> - -<span class="k">def</span> <span class="nf">open_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span> - <span class="n">passman</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">HTTPPasswordMgrWithDefaultRealm</span><span class="p">()</span> - <span class="n">passman</span><span class="o">.</span><span class="n">add_password</span><span class="p">(</span><span class="kc">None</span><span class="p">,</span> <span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span> - <span class="n">authhandler</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">HTTPBasicAuthHandler</span><span class="p">(</span><span class="n">passman</span><span class="p">)</span> - - <span class="n">opener</span> <span class="o">=</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">build_opener</span><span class="p">(</span><span class="n">authhandler</span><span class="p">)</span> - - <span class="n">urllib2</span><span class="o">.</span><span class="n">install_opener</span><span class="p">(</span><span class="n">opener</span><span class="p">)</span> - - <span class="k">return</span> <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">url</span><span class="p">)</span><span class="o">.</span><span class="n">read</span><span class="p">()</span> - -<span class="k">def</span> <span class="nf">reboot</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">):</span> - <span class="n">data</span> <span class="o">=</span> <span class="n">open_url</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">username</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span> - <span class="n">token</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="s2">&quot;name\=</span><span class="se">\\</span><span class="s2">&#39;2</span><span class="se">\\</span><span class="s2">&#39; value=</span><span class="se">\\</span><span class="s2">&#39;([0-9]+)</span><span class="se">\\</span><span class="s2">&#39;&quot;</span><span class="p">,</span> <span class="n">data</span><span class="p">)[</span><span class="mi">1</span><span class="p">]</span> - <span class="n">urllib2</span><span class="o">.</span><span class="n">urlopen</span><span class="p">(</span><span class="n">urllib2</span><span class="o">.</span><span class="n">Request</span><span class="p">(</span><span class="n">url</span><span class="o">=</span><span class="n">url</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="s1">&#39;0=17&amp;2=</span><span class="si">%s</span><span class="s1">&amp;1&#39;</span> <span class="o">%</span> <span class="n">token</span><span class="p">))</span> - -<span class="k">if</span> <span class="vm">__file__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span> - <span class="n">parser</span> <span class="o">=</span> <span class="n">argparse</span><span class="o">.</span><span class="n">ArgumentParser</span><span class="p">(</span><span class="n">description</span><span class="o">=</span><span class="s2">&quot;&quot;&quot;Reboot your bebox !&quot;&quot;&quot;</span><span class="p">)</span> - - <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="n">dest</span><span class="o">=</span><span class="s1">&#39;user&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;username&#39;</span><span class="p">)</span> - <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="n">dest</span><span class="o">=</span><span class="s1">&#39;password&#39;</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;password&#39;</span><span class="p">)</span> - <span class="n">parser</span><span class="o">.</span><span class="n">add_argument</span><span class="p">(</span><span class="n">boxurl</span><span class="o">=</span><span class="s1">&#39;boxurl&#39;</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="n">BOX_URL</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s1">&#39;Base box url. Default is </span><span class="si">%s</span><span class="s1">&#39;</span> <span class="o">%</span> <span class="n">BOX_URL</span><span class="p">)</span> - - <span class="n">args</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">parse_args</span><span class="p">()</span> - <span class="n">url</span> <span class="o">=</span> <span class="n">urlparse</span><span class="o">.</span><span class="n">urljoin</span><span class="p">(</span><span class="n">args</span><span class="o">.</span><span class="n">boxurl</span><span class="p">,</span> <span class="n">REBOOT_URL</span><span class="p">)</span> - <span class="n">reboot</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">username</span><span class="p">,</span> <span class="n">args</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> -</code></pre></div>Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html -<p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s -not so easy, and you can&#8217;t just tell: use the pictures in this folder to -do&nbsp;so.</p> -<p>You can have a look to the git repository if you want: -<a href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau …</a></p> -<p>In gnome, you can can use a <span class="caps">XML</span> file to have a dynamic wallpaper. It&#8217;s -not so easy, and you can&#8217;t just tell: use the pictures in this folder to -do&nbsp;so.</p> -<p>You can have a look to the git repository if you want: -<a href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> -<p>Some time ago, I&#8217;ve made a little python script to ease that, and you -can now use it too. It&#8217;s named &#8220;gnome-background-generator&#8221;, and you can -install it via pip for&nbsp;instance.</p> -<div class="highlight"><pre><span></span><code>shell -$ pip install gnome-background-generator -</code></pre></div> - -<p>Then, you have just to use it this&nbsp;way:</p> -<div class="highlight"><pre><span></span><code><span class="n">shell</span> -<span class="n">$ gnome-background-generator -p ~/Images/walls -s</span> -<span class="n">/home/alexis/Images/walls/dynamic-wallpaper.xml generated</span> -</code></pre></div> - -<p>Here is a extract of the&nbsp;`&#8212;help`:</p> -<div class="highlight"><pre><span></span><code><span class="n">shell</span> -<span class="o">$</span><span class="w"> </span><span class="n">gnome</span><span class="o">-</span><span class="n">background</span><span class="o">-</span><span class="n">generator</span><span class="w"> </span><span class="o">--</span><span class="n">help</span> -<span class="n">usage</span><span class="p">:</span><span class="w"> </span><span class="n">gnome</span><span class="o">-</span><span class="n">background</span><span class="o">-</span><span class="n">generator</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">h</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">p</span><span class="w"> </span><span class="n">PATH</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="n">OUTPUT</span><span class="p">]</span> -<span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">t</span><span class="w"> </span><span class="n">TRANSITION_TIME</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">d</span><span class="w"> </span><span class="n">DISPLAY_TIME</span><span class="p">]</span><span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">s</span><span class="p">]</span> -<span class="w"> </span><span class="p">[</span><span class="o">-</span><span class="n">b</span><span class="p">]</span> - -<span class="n">A</span><span class="w"> </span><span class="n">simple</span><span class="w"> </span><span class="n">command</span><span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="k">tool</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">generate</span><span class="w"> </span><span class="n">an</span><span class="w"> </span><span class="n">XML</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">gnome</span> -<span class="n">wallpapers</span><span class="p">,</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">have</span><span class="w"> </span><span class="n">dynamic</span><span class="w"> </span><span class="n">walls</span> - -<span class="n">optional</span><span class="w"> </span><span class="n">arguments</span><span class="p">:</span> -<span class="w"> </span><span class="o">-</span><span class="n">h</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">help</span><span class="w"> </span><span class="n">show</span><span class="w"> </span><span class="n">this</span><span class="w"> </span><span class="n">help</span><span class="w"> </span><span class="n">message</span><span class="w"> </span><span class="ow">and</span><span class="w"> </span><span class="n">exit</span> -<span class="w"> </span><span class="o">-</span><span class="n">p</span><span class="w"> </span><span class="n">PATH</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">path</span><span class="w"> </span><span class="n">PATH</span><span class="w"> </span><span class="n">Path</span><span class="w"> </span><span class="n">to</span><span class="w"> </span><span class="n">look</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">pictures</span><span class="o">.</span><span class="w"> </span><span class="n">If</span><span class="w"> </span><span class="n">no</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="k">is</span> -<span class="w"> </span><span class="n">specified</span><span class="p">,</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">used</span><span class="w"> </span><span class="n">too</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">outputing</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">dynamic</span><span class="o">-</span> -<span class="w"> </span><span class="n">wallpaper</span><span class="o">.</span><span class="n">xml</span><span class="w"> </span><span class="n">file</span><span class="o">.</span><span class="w"> </span><span class="n">Default</span><span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">current</span> -<span class="w"> </span><span class="n">directory</span><span class="w"> </span><span class="p">(</span><span class="o">.</span><span class="p">)</span> -<span class="w"> </span><span class="o">-</span><span class="n">o</span><span class="w"> </span><span class="n">OUTPUT</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">output</span><span class="w"> </span><span class="n">OUTPUT</span> -<span class="w"> </span><span class="n">Output</span><span class="w"> </span><span class="n">filename</span><span class="o">.</span><span class="w"> </span><span class="n">If</span><span class="w"> </span><span class="n">no</span><span class="w"> </span><span class="n">filename</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="n">specified</span><span class="p">,</span><span class="w"> </span><span class="n">a</span> -<span class="w"> </span><span class="n">dynamic</span><span class="o">-</span><span class="n">wallpaper</span><span class="o">.</span><span class="n">xml</span><span class="w"> </span><span class="n">file</span><span class="w"> </span><span class="n">will</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">generated</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">the</span> -<span class="w"> </span><span class="n">path</span><span class="w"> </span><span class="n">containing</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">pictures</span><span class="o">.</span><span class="w"> </span><span class="n">You</span><span class="w"> </span><span class="n">can</span><span class="w"> </span><span class="n">also</span><span class="w"> </span><span class="n">use</span><span class="w"> </span><span class="s2">&quot;-&quot;</span><span class="w"> </span><span class="n">to</span> -<span class="w"> </span><span class="n">display</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">xml</span><span class="w"> </span><span class="ow">in</span><span class="w"> </span><span class="n">the</span><span class="w"> </span><span class="n">stdout</span><span class="o">.</span> -<span class="w"> </span><span class="o">-</span><span class="n">t</span><span class="w"> </span><span class="n">TRANSITION_TIME</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">transition</span><span class="o">-</span><span class="n">time</span><span class="w"> </span><span class="n">TRANSITION_TIME</span> -<span class="w"> </span><span class="n">Time</span><span class="w"> </span><span class="p">(</span><span class="ow">in</span><span class="w"> </span><span class="n">seconds</span><span class="p">)</span><span class="w"> </span><span class="n">transitions</span><span class="w"> </span><span class="n">must</span><span class="w"> </span><span class="n">last</span><span class="w"> </span><span class="p">(</span><span class="n">default</span><span class="w"> </span><span class="n">value</span> -<span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="n">seconds</span><span class="p">)</span> -<span class="w"> </span><span class="o">-</span><span class="n">d</span><span class="w"> </span><span class="n">DISPLAY_TIME</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">display</span><span class="o">-</span><span class="n">time</span><span class="w"> </span><span class="n">DISPLAY_TIME</span> -<span class="w"> </span><span class="n">Time</span><span class="w"> </span><span class="p">(</span><span class="ow">in</span><span class="w"> </span><span class="n">seconds</span><span class="p">)</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="n">picture</span><span class="w"> </span><span class="n">must</span><span class="w"> </span><span class="n">be</span><span class="w"> </span><span class="n">displayed</span><span class="o">.</span><span class="w"> </span><span class="n">Default</span> -<span class="w"> </span><span class="n">value</span><span class="w"> </span><span class="k">is</span><span class="w"> </span><span class="mi">900</span><span class="w"> </span><span class="p">(</span><span class="mi">15</span><span class="n">mn</span><span class="p">)</span> -<span class="w"> </span><span class="o">-</span><span class="n">s</span><span class="p">,</span><span class="w"> </span><span class="o">--</span><span class="n">set</span><span class="o">-</span><span class="n">background</span><span class="w"> </span><span class="s1">&#39;&#39;&#39;try to set the background using gnome-appearance-</span> -<span class="s1"> properties</span> -<span class="s1"> -b, --debug</span> -</code></pre></div>How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html -<ul> -<li> -<p>date<br>&nbsp;2010-10-10</p> -</li> -<li> -<p>category<br>&nbsp;tech</p> -</li> -</ul> -<p>I&#8217;ve not managed so far to get completely rid of php, so here&#8217;s a simple -reminder about how to install php on <span class="caps">NGINX</span>, for FreeBSD. Nothing hard, -but that&#8217;s worse to have the piece of configuration somewhere&nbsp;!</p> -<div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="nx">update</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">ports</span> -<span class="err">$</span><span class="w"> </span><span class="nx">portsnap</span><span class="w"> </span><span class="nx">fetch</span><span class="w"> </span><span class="nx">update …</span></code></pre></div> -<ul> -<li> -<p>date<br>&nbsp;2010-10-10</p> -</li> -<li> -<p>category<br>&nbsp;tech</p> -</li> -</ul> -<p>I&#8217;ve not managed so far to get completely rid of php, so here&#8217;s a simple -reminder about how to install php on <span class="caps">NGINX</span>, for FreeBSD. Nothing hard, -but that&#8217;s worse to have the piece of configuration somewhere&nbsp;!</p> -<div class="highlight"><pre><span></span><code><span class="err">#</span><span class="w"> </span><span class="nx">update</span><span class="w"> </span><span class="nx">the</span><span class="w"> </span><span class="nx">ports</span> -<span class="err">$</span><span class="w"> </span><span class="nx">portsnap</span><span class="w"> </span><span class="nx">fetch</span><span class="w"> </span><span class="nx">update</span> - -<span class="err">#</span><span class="w"> </span><span class="nx">install</span><span class="w"> </span><span class="nx">php5</span><span class="w"> </span><span class="nx">port</span> -<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="nx">config</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">lang</span><span class="o">/</span><span class="nx">php5</span><span class="o">-</span><span class="nx">extensions</span> -<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="kn">package</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">lang</span><span class="o">/</span><span class="nx">php5</span><span class="o">-</span><span class="nx">extensions</span> - -<span class="err">#</span><span class="w"> </span><span class="nx">install</span><span class="w"> </span><span class="nx">nginx</span> -<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="nx">config</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">nginx</span><span class="o">-</span><span class="nx">devel</span> -<span class="err">$</span><span class="w"> </span><span class="nx">make</span><span class="w"> </span><span class="kn">package</span><span class="o">-</span><span class="nx">recursive</span><span class="w"> </span><span class="o">-</span><span class="nx">C</span><span class="w"> </span><span class="o">/</span><span class="nx">usr</span><span class="o">/</span><span class="nx">ports</span><span class="o">/</span><span class="nx">www</span><span class="o">/</span><span class="nx">nginx</span><span class="o">-</span><span class="nx">devel</span> -</code></pre></div> - -<p>Now we have all the dependencies installed, we need to configure a bit -the&nbsp;server.</p> -<p>That&#8217;s a simple thing in fact, but it could be good to have something -that will work without effort over&nbsp;time.</p> -<p>Here&#8217;s a sample of my&nbsp;configuration:</p> -<div class="highlight"><pre><span></span><code><span class="nt">server</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="err">server_name</span><span class="w"> </span><span class="err">ndd</span><span class="p">;</span> -<span class="w"> </span><span class="err">set</span><span class="w"> </span><span class="err">$path</span><span class="w"> </span><span class="err">/path/to/your/files</span><span class="p">;</span> -<span class="w"> </span><span class="err">root</span><span class="w"> </span><span class="err">$path</span><span class="p">;</span> - -<span class="w"> </span><span class="err">location</span><span class="w"> </span><span class="err">/</span><span class="w"> </span><span class="err">{</span> -<span class="w"> </span><span class="err">index</span><span class="w"> </span><span class="err">index.php</span><span class="p">;</span> -<span class="w"> </span><span class="p">}</span> - -<span class="w"> </span><span class="nt">location</span><span class="w"> </span><span class="o">~*</span><span class="w"> </span><span class="o">^.+.(</span><span class="nt">jpg</span><span class="o">|</span><span class="nt">jpeg</span><span class="o">|</span><span class="nt">gif</span><span class="o">|</span><span class="nt">css</span><span class="o">|</span><span class="nt">png</span><span class="o">|</span><span class="nt">js</span><span class="o">|</span><span class="nt">ico</span><span class="o">|</span><span class="nt">xml</span><span class="o">)$</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="err">access_log</span><span class="w"> </span><span class="err">off</span><span class="p">;</span> -<span class="w"> </span><span class="err">expires</span><span class="w"> </span><span class="err">30d</span><span class="p">;</span> -<span class="w"> </span><span class="p">}</span> - -<span class="w"> </span><span class="nt">location</span><span class="w"> </span><span class="o">~</span><span class="w"> </span><span class="p">.</span><span class="nc">php</span><span class="o">$</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="err">fastcgi_param</span><span class="w"> </span><span class="err">SCRIPT_FILENAME</span><span class="w"> </span><span class="err">$path$fastcgi_script_name</span><span class="p">;</span> -<span class="w"> </span><span class="err">fastcgi_pass</span><span class="w"> </span><span class="err">backend</span><span class="p">;</span> -<span class="w"> </span><span class="err">include</span><span class="w"> </span><span class="err">fastcgi_params</span><span class="p">;</span> -<span class="w"> </span><span class="p">}</span> -<span class="err">}</span> - -<span class="nt">upstream</span><span class="w"> </span><span class="nt">backend</span><span class="w"> </span><span class="p">{</span> -<span class="w"> </span><span class="err">server</span><span class="w"> </span><span class="err">127.0.0.1:9000</span><span class="p">;</span> -<span class="p">}</span> -</code></pre></div> - -<p>And that&#8217;s it&nbsp;!</p>Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html -<p>Those days, I&#8217;ve wrote a little python application to fit my blogging -needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text -and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> -<p><a href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple -tool …</p> -<p>Those days, I&#8217;ve wrote a little python application to fit my blogging -needs. I&#8217;m an occasional blogger, a vim lover, I like restructured text -and DVCSes, so I&#8217;ve made a little tool that makes good use of all&nbsp;that.</p> -<p><a href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple -tool to generate your blog as static files, letting you using your -editor of choice (vim!). It&#8217;s easy to extend, and has a template -support (via&nbsp;jinja2).</p> -<p>I&#8217;ve made it to fit <em>my</em> needs. I hope it will fit yours, but maybe it -wont, and it have not be designed to feet everyone&#8217;s&nbsp;needs.</p> -<p>Need an example ? You&#8217;re looking at it ! This weblog is using pelican -to be generated, also for the atom&nbsp;feeds.</p> -<p>I&#8217;ve released it under <span class="caps">AGPL</span>, since I want all the modifications to be -profitable to all the&nbsp;users.</p> -<p>You can find a repository to fork at -<a href="https://github.com/getpelican/pelican/">https://github.com/getpelican/pelican/</a>. feel free to hack it&nbsp;!</p> -<p>If you just want to get started, use your installer of choice (pip, -easy_install, …) And then have a look to the help (pelican&nbsp;&#8212;help)</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pip<span class="w"> </span>install<span class="w"> </span>pelican -</code></pre></div> - -<h2 id="usage">Usage</h2> -<p>Here&#8217;s a sample usage of&nbsp;pelican</p> -<div class="highlight"><pre><span></span><code>$<span class="w"> </span>pelican<span class="w"> </span>. -writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/index.html -writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/tags.html -writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/categories.html -writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/archives.html -writing<span class="w"> </span>/home/alexis/projets/notmyidea.org/output/category/python.html -writing -/home/alexis/projets/notmyidea.org/output/pelican-a-simple-static-blog-generator-in-python.html -Done<span class="w"> </span>! -</code></pre></div> - -<p>You also can use the &#8212;help option for the command line to get more&nbsp;informations</p> -<div class="highlight"><pre><span></span><code><span class="nv">$pelican</span><span class="w"> </span>--help -usage:<span class="w"> </span>pelican<span class="w"> </span><span class="o">[</span>-h<span class="o">]</span><span class="w"> </span><span class="o">[</span>-t<span class="w"> </span>TEMPLATES<span class="o">]</span><span class="w"> </span><span class="o">[</span>-o<span class="w"> </span>OUTPUT<span class="o">]</span><span class="w"> </span><span class="o">[</span>-m<span class="w"> </span>MARKUP<span class="o">]</span><span class="w"> </span><span class="o">[</span>-s<span class="w"> </span>SETTINGS<span class="o">]</span><span class="w"> </span><span class="o">[</span>-b<span class="o">]</span> -<span class="w"> </span>path - -A<span class="w"> </span>tool<span class="w"> </span>to<span class="w"> </span>generate<span class="w"> </span>a<span class="w"> </span>static<span class="w"> </span>blog,<span class="w"> </span>with<span class="w"> </span>restructured<span class="w"> </span>text<span class="w"> </span>input<span class="w"> </span>files. - -positional<span class="w"> </span>arguments: -<span class="w"> </span>path<span class="w"> </span>Path<span class="w"> </span>where<span class="w"> </span>to<span class="w"> </span>find<span class="w"> </span>the<span class="w"> </span>content<span class="w"> </span>files<span class="w"> </span><span class="o">(</span>default<span class="w"> </span>is -<span class="w"> </span><span class="s2">&quot;content&quot;</span><span class="o">)</span>. - -optional<span class="w"> </span>arguments: -<span class="w"> </span>-h,<span class="w"> </span>--help<span class="w"> </span>show<span class="w"> </span>this<span class="w"> </span><span class="nb">help</span><span class="w"> </span>message<span class="w"> </span>and<span class="w"> </span><span class="nb">exit</span> -<span class="w"> </span>-t<span class="w"> </span>TEMPLATES,<span class="w"> </span>--templates-path<span class="w"> </span>TEMPLATES -<span class="w"> </span>Path<span class="w"> </span>where<span class="w"> </span>to<span class="w"> </span>find<span class="w"> </span>the<span class="w"> </span>templates.<span class="w"> </span>If<span class="w"> </span>not<span class="w"> </span>specified, -<span class="w"> </span>will<span class="w"> </span>uses<span class="w"> </span>the<span class="w"> </span>ones<span class="w"> </span>included<span class="w"> </span>with<span class="w"> </span>pelican. -<span class="w"> </span>-o<span class="w"> </span>OUTPUT,<span class="w"> </span>--output<span class="w"> </span>OUTPUT -<span class="w"> </span>Where<span class="w"> </span>to<span class="w"> </span>output<span class="w"> </span>the<span class="w"> </span>generated<span class="w"> </span>files.<span class="w"> </span>If<span class="w"> </span>not<span class="w"> </span>specified, -<span class="w"> </span>a<span class="w"> </span>directory<span class="w"> </span>will<span class="w"> </span>be<span class="w"> </span>created,<span class="w"> </span>named<span class="w"> </span><span class="s2">&quot;output&quot;</span><span class="w"> </span><span class="k">in</span><span class="w"> </span>the -<span class="w"> </span>current<span class="w"> </span>path. -<span class="w"> </span>-m<span class="w"> </span>MARKUP,<span class="w"> </span>--markup<span class="w"> </span>MARKUP -<span class="w"> </span>the<span class="w"> </span>markup<span class="w"> </span>language<span class="w"> </span>to<span class="w"> </span>use.<span class="w"> </span>Currently<span class="w"> </span>only -<span class="w"> </span>ReSTreucturedtext<span class="w"> </span>is<span class="w"> </span>available. -<span class="w"> </span>-s<span class="w"> </span>SETTINGS,<span class="w"> </span>--settings<span class="w"> </span>SETTINGS -<span class="w"> </span>the<span class="w"> </span>settings<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>application.<span class="w"> </span>Default<span class="w"> </span>to<span class="w"> </span>None. -<span class="w"> </span>-b,<span class="w"> </span>--debug -</code></pre></div> - -<p>Enjoy&nbsp;:)</p>An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html -<p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent -working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It -was a really amazing experience, for many&nbsp;reasons.</p> -<p>First of all, we had a very good team, we were 5 students working on -distutils2: <a href="http://zubin71.wordpress.com">Zubin</a>, -<a href="http://wokslog.wordpress.com/">Éric</a>, -<a href="http://gsoc.djolonga.com/">Josip</a>, -<a href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, -<a href="http://mouadino.blogspot.com/">Mouad</a> have worked on …</p> -<p>The <a href="http://code.google.com/soc/">Google Summer of Code</a> I&#8217;ve spent -working on <a href="http://hg.python.org/distutils2/">distutils2</a> is over. It -was a really amazing experience, for many&nbsp;reasons.</p> -<p>First of all, we had a very good team, we were 5 students working on -distutils2: <a href="http://zubin71.wordpress.com">Zubin</a>, -<a href="http://wokslog.wordpress.com/">Éric</a>, -<a href="http://gsoc.djolonga.com/">Josip</a>, -<a href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, -<a href="http://mouadino.blogspot.com/">Mouad</a> have worked on the PyPI testing -infrastructure. You could find what each person have done on <a href="http://bitbucket.org/tarek/distutils2/wiki/GSoC_2010_teams">the wiki -page of -distutils2</a>.</p> -<p>We were in contact with each others really often, helping us when -possible (in #distutils), and were continuously aware of the state of -the work of each participant. This, in my opinion, have bring us in a -good&nbsp;shape.</p> -<p>Then, I&#8217;ve learned a lot. Python packaging was completely new to me at -the time of the GSoC start, and I was pretty unfamiliar with python good -practices too, as I&#8217;ve been introducing myself to python in the late&nbsp;2009.</p> -<p>I&#8217;ve recently looked at some python code I wrote just three months ago, -and I was amazed to think about many improvements to made on it. I guess -this is a good indicator of the path I&#8217;ve traveled since I wrote&nbsp;it.</p> -<p>This summer was awesome because I&#8217;ve learned about python good -practices, now having some strong -<a href="http://mercurial.selenic.com/">mercurial</a> knowledge, and I&#8217;ve seen a -little how the python community&nbsp;works.</p> -<p>Then, I would like to say a big thanks to all the mentors that have -hanged around while needed, on <span class="caps">IRC</span> or via mail, and especially my mentor -for this summer, <a href="http://tarek.ziade.org">Tarek Ziadé</a>.</p> -<p>Thanks a lot for your motivation, your leadership and your cheerfulness, -even with a new-born and a new&nbsp;work!</p> -<h2 id="why">Why&nbsp;?</h2> -<p>I wanted to work on python packaging because, as the time pass, we were -having a sort of complex tools in this field. Each one wanted to add -features to distutils, but not in a standard&nbsp;way.</p> -<p>Now, we have PEPs that describes some format we agreed on (see <span class="caps">PEP</span> 345), -and we wanted to have a tool on which users can base their code on, -that&#8217;s <a href="http://hg.python.org/distutils2/">distutils2</a>.</p> -<h2 id="my-job">My&nbsp;job</h2> -<p>I had to provide a way to crawl the PyPI indexes in a simple way, and do -some installation / uninstallation&nbsp;scripts.</p> -<p>All the work done is available in <a href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket -repository</a>.</p> -<h3 id="crawling-the-pypi-indexes">Crawling the PyPI&nbsp;indexes</h3> -<p>There are two ways of requesting informations from the indexes: using -the &#8220;simple&#8221; index, that is a kind of <span class="caps">REST</span> index, and using <span class="caps">XML</span>-<span class="caps">RPC</span>.</p> -<p>I&#8217;ve done the two implementations, and a high level <span class="caps">API</span> to query those -twos. Basically, this supports the mirroring infrastructure defined in -<span class="caps">PEP</span> 381. So far, the work I&#8217;ve done is gonna be used in pip (they&#8217;ve -basically copy/paste the code, but this will change as soon as we get -something completely stable for distutils2), and that&#8217;s a good news, as -it was the main reason for what I&#8217;ve done&nbsp;that.</p> -<p>I&#8217;ve tried to have an unified <span class="caps">API</span> for the clients, to switch from one to -another implementation easily. I&#8217;m already thinking of adding others -crawlers to this stuff, and it was made to be&nbsp;extensible.</p> -<p>If you want to get more informations about the crawlers/PyPI clients, -please refer to the distutils2 documentation, especially <a href="http://distutils2.notmyidea.org/library/distutils2.index.html">the pages -about -indexes</a>.</p> -<p>You can find the changes I made about this in the -<a href="http://hg.python.org/distutils2/">distutils2</a> source code&nbsp;.</p> -<h3 id="installation-uninstallation-scripts">Installation / Uninstallation&nbsp;scripts</h3> -<p>Next step was to think about an installation script, and an uninstaller. -I&#8217;ve not done the uninstaller part, and it&#8217;s a smart part, as it&#8217;s -basically removing some files from the system, so I&#8217;ll probably do it in -a near&nbsp;future.</p> -<p><a href="http://hg.python.org/distutils2/">distutils2</a> provides a way to install -distributions, and to handle dependencies between releases. For now, -this support is only about the last version of the <span class="caps">METADATA</span> (1.2) (See, -the <span class="caps">PEP</span> 345), but I&#8217;m working on a compatibility layer for the old -metadata, and for the informations provided via <span class="caps">PIP</span> requires.txt, for&nbsp;instance.</p> -<h3 id="extra-work">Extra&nbsp;work</h3> -<p>Also, I&#8217;ve done some extra work. this&nbsp;includes:</p> -<ul> -<li>working on the <span class="caps">PEP</span> 345, and having some discussion about it (about - the names of some&nbsp;fields).</li> -<li>writing a PyPI server mock, useful for tests. you can find more - information about it on the - <a href="http://distutils.notmyidea.org">documentation</a>.</li> -</ul> -<h2 id="futures-plans">Futures&nbsp;plans</h2> -<p>As I said, I&#8217;ve enjoyed working on distutils2, and the people I&#8217;ve met -here are really pleasant to work with. So I <em>want</em> to continue -contributing on python, and especially on python packaging, because -there is still a lot of things to do in this scope, to get something -really&nbsp;usable.</p> -<p>I&#8217;m not plainly satisfied by the work I&#8217;ve done, so I&#8217;ll probably tweak -it a bit: the installer part is not yet completely finished, and I want -to add support for a real -<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"><span class="caps">REST</span></a> -index in the&nbsp;future.</p> -<p>We&#8217;ll talk again of this in the next months, probably, but we definitely -need a real -<a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"><span class="caps">REST</span></a> <span class="caps">API</span> -for <a href="http://pypi.python.org">PyPI</a>, as the &#8220;simple&#8221; index <em>is</em> an ugly -hack, in my opinion. I&#8217;ll work on a serious proposition about this, -maybe involving <a href="http://couchdb.org">CouchDB</a>, as it seems to be a good -option for what we want&nbsp;here.</p> -<h2 id="issues">Issues</h2> -<p>I&#8217;ve encountered some issues during this summer. The main one is that&#8217;s -hard to work remotely, especially being in the same room that we live, -with others. I like to just think about a project with other people, a -paper and a pencil, no computers. This have been not so possible at the -start of the project, as I needed to read a lot of code to understand -the codebase, and then to read/write&nbsp;emails.</p> -<p>I&#8217;ve finally managed to work in an office, so good point for home/office&nbsp;separation.</p> -<p>I&#8217;d not planned there will be so a high number of emails to read, in -order to follow what&#8217;s up in the python world, and be a part of the -community seems to takes some times to read/write emails, especially for -those (like me) that arent so confortable with english (but this had -brought me some english fu&nbsp;!).</p> -<h2 id="thanks">Thanks&nbsp;!</h2> -<p>A big thanks to <a href="http://www.graine-libre.fr/">Graine Libre</a> and <a href="http://www.makina-corpus.com/">Makina -Corpus</a>, which has offered me to come -into their offices from time to time, to share they cheerfulness ! Many -thanks too to the Google Summer of Code program for setting up such an -initiative. If you&#8217;re a student, if you&#8217;re interested about <span class="caps">FOSS</span>, dont -hesitate any second, it&#8217;s a really good opportunity to work on -interesting&nbsp;projects!</p>Sprinting on distutils2 in Tours2010-07-10T00:00:00+02:002010-07-10T00:00:00+02:00tag:blog.notmyidea.org,2010-07-10:/sprinting-on-distutils2-in-tours.html -<ul> -<li> -<p>date<br>&nbsp;2010-07-06</p> -</li> -<li> -<p>category<br>&nbsp;tech</p> -</li> -</ul> -<p>Yesterday, as I was traveling to Tours, I&#8217;ve took some time to visit -Éric, another student who&#8217;s working on distutils2 this summer, as a -part of the GSoC. Basically, it was to take a drink, discuss a bit about -distutils2, our respective tasks and …</p> -<ul> -<li> -<p>date<br>&nbsp;2010-07-06</p> -</li> -<li> -<p>category<br>&nbsp;tech</p> -</li> -</ul> -<p>Yesterday, as I was traveling to Tours, I&#8217;ve took some time to visit -Éric, another student who&#8217;s working on distutils2 this summer, as a -part of the GSoC. Basically, it was to take a drink, discuss a bit about -distutils2, our respective tasks and general feelings, and to put a face -on a pseudonym. I&#8217;d really enjoyed this time, because Éric knows a lot -of things about mercurial and python good practices, and I&#8217;m eager to -learn about those. So, we have discussed about things, have not wrote so -much code, but have some things to propose so far, about documentation, -and I also provides here some bribes of conversations we&nbsp;had.</p> -<h2 id="documentation">Documentation</h2> -<p>While writing the PyPI simple index crawler documentation, I realized -that we miss some structure, or how-to about the documentation. Yep, you -read well. We lack documentation on how to make documentation. Heh. -We&#8217;re missing some rules to follow, and this lead to a not-so-structured -final documentation. We probably target three type of publics, and we -can split the documentation regarding&nbsp;those:</p> -<ul> -<li><strong>Packagers</strong> who want to distribute their&nbsp;softwares.</li> -<li><strong>End users</strong> who need to understand how to use end user commands, - like the&nbsp;installer/uninstaller</li> -<li><strong>packaging coders</strong> who <em>use</em> distutils2, as a base for building a - package&nbsp;manager.</li> -</ul> -<p>We also need to discuss about a pattern to follow while writing -documentation. How many parts do we need ? Where to put the <span class="caps">API</span> -description ? etc. That&#8217;s maybe seems to be not so important, but I -guess the readers would appreciate to have the same structure all along -distutils2&nbsp;documentation.</p> -<h2 id="mercurial">Mercurial</h2> -<p>I&#8217;m really <em>not</em> a mercurial power user. I use it on daily basis, but I -lack of basic knowledge about it. Big thanks Éric for sharing yours with -me, you&#8217;re of a great help. We have talked about some mercurial -extensions that seems to make the life simpler, while used the right -way. I&#8217;ve not used them so far, so consider this as a personal&nbsp;note.</p> -<ul> -<li>hg histedit, to edit the&nbsp;history</li> -<li>hg crecord, to select the changes to&nbsp;commit</li> -</ul> -<p>We have spent some time to review a merge I made sunday, to re-merge it, -and commit the changes as a new changeset. Awesome. These things make me -say I <strong>need</strong> to read <a href="http://hgbook.red-bean.com/read/">the hg book</a>, -and will do as soon as I got some spare time: mercurial seems to be -simply great. So &#8230; Great. I&#8217;m a powerful merger now&nbsp;!</p> -<h2 id="on-using-tools">On using&nbsp;tools</h2> -<p>Because we <em>also</em> are <em>hackers</em>, we have shared a bit our ways to code, -the tools we use, etc. Both of us were using vim, and I&#8217;ve discovered -vimdiff and hgtk, which will completely change the way I navigate into -the mercurial history. We aren&#8217;t &#8220;power users&#8221;, so we have learned from -each other about vim tips. You can find <a href="http://github.com/ametaireau/dotfiles">my dotfiles on -github</a>, if it could help. -They&#8217;re not perfect, and not intended to be, because changing all the -time, as I learn. Don&#8217;t hesitate to have a look, and to propose -enhancements if you have&nbsp;!</p> -<h2 id="on-being-pythonic">On being&nbsp;pythonic</h2> -<p>My background as an old Java user disserves me so far, as the paradigms -are not the same while coding in python. Hard to find the more pythonic -way to do, and sometimes hard to unlearn my way to think about software -engineering. Well, it seems that the only solution is to read code, and -to re-read import this from times to times ! <a href="http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html">Coding like a -pythonista</a> -seems to be a must-read, so, I know what to&nbsp;do.</p> -<h2 id="conclusion">Conclusion</h2> -<p>It was really great. Next time, we&#8217;ll need to focus a bit more on -distutils2, and to have a bullet list of things to do, but days like -this one are opportunities to catch ! We&#8217;ll probably do another sprint -in a few weeks, stay tuned&nbsp;!</p>Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html -<p>I&#8217;m working for about a month for distutils2, even if I was being a bit -busy (as I had some class courses and exams to work&nbsp;on)</p> -<p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so -far. You can also find, if …</p> -<p>I&#8217;m working for about a month for distutils2, even if I was being a bit -busy (as I had some class courses and exams to work&nbsp;on)</p> -<p>I&#8217;ll try do sum-up my general feelings here, and the work I&#8217;ve made so -far. You can also find, if you&#8217;re interested, my weekly summaries in <a href="http://wiki.notmyidea.org/distutils2_schedule">a -dedicated wiki page</a>.</p> -<h2 id="general-feelings">General&nbsp;feelings</h2> -<p>First, and it&#8217;s a really important point, the GSoC is going very well, -for me as for other students, at least from my perspective. It&#8217;s a -pleasure to work with such enthusiast people, as this make the global -atmosphere very pleasant to&nbsp;live.</p> -<p>First of all, I&#8217;ve spent time to read the existing codebase, and to -understand what we&#8217;re going to do, and what&#8217;s the rationale to do&nbsp;so.</p> -<p>It&#8217;s really clear for me now: what we&#8217;re building is the foundations of -a packaging infrastructure in python. The fact is that many projects -co-exists, and comes all with their good concepts. Distutils2 tries to -take the interesting parts of all, and to provide it in the python -standard libs, respecting the recently written <span class="caps">PEP</span> about&nbsp;packaging.</p> -<p>With distutils2, it will be simpler to make &#8220;things&#8221; compatible. So if -you think about a new way to deal with distributions and packaging in -python, you can use the Distutils2 APIs to do&nbsp;so.</p> -<h2 id="tasks">Tasks</h2> -<p>My main task while working on distutils2 is to provide an installation -and an un-installation command, as described in <span class="caps">PEP</span> 376. For this, I -first need to get informations about the existing distributions (what&#8217;s -their version, name, metadata, dependencies,&nbsp;etc.)</p> -<p>The main index, you probably know and use, is PyPI. You can access it at -<a href="http://pypi.python.org">http://pypi.python.org</a>.</p> -<h2 id="pypi-index-crawling">PyPI index&nbsp;crawling</h2> -<p>There is two ways to get these informations from PyPI: using the simple -<span class="caps">API</span>, or via xml-rpc&nbsp;calls.</p> -<p>A goal was to use the version specifiers defined -in<a href="http://www.python.org/dev/peps/pep-0345/"><span class="caps">PEP</span> 345</a> and to provides a -way to sort the grabbed distributions depending our needs, to pick the -version we&nbsp;want/need.</p> -<h3 id="using-the-simple-api">Using the simple <span class="caps">API</span></h3> -<p>The simple <span class="caps">API</span> is composed of <span class="caps">HTML</span> pages you can access at -<a href="http://pypi.python.org/simple/">http://pypi.python.org/simple/</a>.</p> -<p>Distribute and Setuptools already provides a crawler for that, but it -deals with their internal mechanisms, and I found that the code was not -so clear as I want, that&#8217;s why I&#8217;ve preferred to pick up the good ideas, -and some implementation details, plus re-thinking the global&nbsp;architecture.</p> -<p>The rules are simple: each project have a dedicated page, which allows -us to get informations&nbsp;about:</p> -<ul> -<li>the distribution download locations (for some&nbsp;versions)</li> -<li>homepage&nbsp;links</li> -<li>some other useful informations, as the bugtracker address, for&nbsp;instance.</li> -</ul> -<p>If you want to find all the distributions of the &#8220;EggsAndSpam&#8221; project, -you could do the following (do not take so attention to the names here, -as the <span class="caps">API</span> will probably change a&nbsp;bit):</p> -<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="n">index</span> <span class="o">=</span> <span class="n">SimpleIndex</span><span class="p">()</span> -<span class="o">&gt;&gt;&gt;</span> <span class="n">index</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&quot;EggsAndSpam&quot;</span><span class="p">)</span> -<span class="p">[</span><span class="n">EggsAndSpam</span> <span class="mf">1.1</span><span class="p">,</span> <span class="n">EggsAndSpam</span> <span class="mf">1.2</span><span class="p">,</span> <span class="n">EggsAndSpam</span> <span class="mf">1.3</span><span class="p">]</span> -</code></pre></div> - -<p>We also could use version&nbsp;specifiers:</p> -<div class="highlight"><pre><span></span><code><span class="o">&gt;&gt;&gt;</span> <span class="n">index</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s2">&quot;EggsAndSpam (&lt; =1.2)&quot;</span><span class="p">)</span> -<span class="p">[</span><span class="n">EggsAndSpam</span> <span class="mf">1.1</span><span class="p">,</span> <span class="n">EggsAndSpam</span> <span class="mf">1.2</span><span class="p">]</span> -</code></pre></div> - -<p>Internally, what&#8217;s done here is the&nbsp;following:</p> -<ul> -<li>it process the <a href="http://pypi.python.org/simple/FooBar/">http://pypi.python.org/simple/FooBar/</a> page, - searching for download&nbsp;URLs.</li> -<li>for each found distribution download <span class="caps">URL</span>, it creates an object, - containing informations about the project name, the version and the - <span class="caps">URL</span> where the archive&nbsp;remains.</li> -<li>it sort the found distributions, using version numbers. The default - behavior here is to prefer source distributions (over binary ones), - and to rely on the last &#8220;final&#8221; distribution (rather than beta, - alpha etc.&nbsp;ones)</li> -</ul> -<p>So, nothing hard or difficult&nbsp;here.</p> -<p>We provides a bunch of other features, like relying on the new PyPI -mirroring infrastructure or filter the found distributions by some -criterias. If you&#8217;re curious, please browse the <a href="http://distutils2.notmyidea.org/">distutils2 -documentation</a>.</p> -<h3 id="using-xml-rpc">Using&nbsp;xml-rpc</h3> -<p>We also can make some xmlrpc calls to retreive informations from PyPI. -It&#8217;s a really more reliable way to get informations from from the index -(as it&#8217;s just the index that provides the informations), but cost -processes on the PyPI distant&nbsp;server.</p> -<p>For now, this way of querying the xmlrpc client is not available on -Distutils2, as I&#8217;m working on it. The main pieces are already present -(I&#8217;ll reuse some work I&#8217;ve made from the SimpleIndex querying, and <a href="http://github.com/ametaireau/pypiclient">some -code already set up</a>), what I -need to do is to provide a xml-rpc PyPI mock server, and that&#8217;s on what -I&#8217;m actually working&nbsp;on.</p> -<h2 id="processes">Processes</h2> -<p>For now, I&#8217;m trying to follow the &#8220;documentation, then test, then code&#8221; -path, and that seems to be really needed while working with a community. -Code is hard to read/understand, compared to documentation, and it&#8217;s -easier to&nbsp;change.</p> -<p>While writing the simple index crawling work, I must have done this to -avoid some changes on the <span class="caps">API</span>, and some loss of&nbsp;time.</p> -<p>Also, I&#8217;ve set up <a href="http://wiki.notmyidea.org/distutils2_schedule">a -schedule</a>, and the goal -is to be sure everything will be ready in time, for the end of the -summer. (And now, I need to learn to follow schedules&nbsp;&#8230;)</p>Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html -<ul> -<li> -<p>date<br>&nbsp;2010-06-25</p> -</li> -<li> -<p>category<br>&nbsp;tech</p> -</li> -</ul> -<p>Wednesday, we give a presentation, with some friends, about the CouchDB -Database, to <a href="http://www.toulibre.org">the Toulouse local <span class="caps">LUG</span></a>. Thanks a -lot to all the presents for being there, it was a pleasure to talk about -this topic with you. Too bad the season is over now an …</p> -<ul> -<li> -<p>date<br>&nbsp;2010-06-25</p> -</li> -<li> -<p>category<br>&nbsp;tech</p> -</li> -</ul> -<p>Wednesday, we give a presentation, with some friends, about the CouchDB -Database, to <a href="http://www.toulibre.org">the Toulouse local <span class="caps">LUG</span></a>. Thanks a -lot to all the presents for being there, it was a pleasure to talk about -this topic with you. Too bad the season is over now an I quit Toulouse -next&nbsp;year.</p> -<p>During our brainstorming about the topic, we used some paper, and we -wanted to make a presentation the simpler way. First thing that come to -my mind was using <a href="http://docutils.sourceforge.net/rst.html">restructured -text</a>, so I&#8217;ve wrote a simple -file containing our different bullet points. In fact, there is quite -nothing to do then, to have a working&nbsp;presentation.</p> -<p>So far, I&#8217;ve used <a href="http://code.google.com/p/rst2pdf/">the rst2pdf -program</a>, and a simple template, to -generate output. It&#8217;s probably simple to have similar results using -latex + beamer, I&#8217;ll try this next time, but as I&#8217;m not familiar with -latex syntax, restructured text was a great&nbsp;option.</p> -<p>Here are <a href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.pdf">the final <span class="caps">PDF</span> -output</a>, -<a href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.rst">Rhe ReST -source</a>, -<a href="http://files.lolnet.org/alexis/rst-presentations/slides.style">the theme -used</a>, -and the command line to generate the <span class="caps">PDF</span>:</p> -<div class="highlight"><pre><span></span><code>rst2pdf couchdb.rst -b1 -s ../slides.style -</code></pre></div>first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html -<p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> -during the past week, taking part of the -<a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short -summary of what I&#8217;ve done so&nbsp;far.</p> -<p>As my courses are not over yet, I&#8217;ve not worked as much as I wanted, and -this will continues until …</p> -<p>As I&#8217;ve been working on <a href="http://hg.python.org/distutils2/">Distutils2</a> -during the past week, taking part of the -<a href="http://code.google.com/intl/fr/soc/"><span class="caps">GSOC</span></a> program, here is a short -summary of what I&#8217;ve done so&nbsp;far.</p> -<p>As my courses are not over yet, I&#8217;ve not worked as much as I wanted, and -this will continues until the end of June. My main tasks are about -making installation and uninstallation commands, to have a simple way to -install distributions via -<a href="http://hg.python.org/distutils2/">Distutils2</a>.</p> -<p>To do this, we need to rely on informations provided by the Python -Package Index (<a href="http://pypi.python.org/">PyPI</a>), and there is at least -two ways to retreive informations from here: <span class="caps">XML</span>-<span class="caps">RPC</span> and the &#8220;simple&#8221; -<span class="caps">API</span>.</p> -<p>So, I&#8217;ve been working on porting some -<a href="http://bitbucket.org/tarek/distribute/">Distribute</a> related stuff to -<a href="http://hg.python.org/distutils2/">Distutils2</a>, cutting off all non -distutils&#8217; things, as we do not want to depend from Distribute&#8217;s -internals. My main work has been about reading the whole code, writing -tests about this and making those tests&nbsp;possible.</p> -<p>In fact, there was a need of a pypi mocked server, and, after reading -and introducing myself to the distutils behaviors and code, I&#8217;ve taken -some time to improve the work <a href="http://bitbucket.org/konrad">Konrad</a> -makes about this&nbsp;mock.</p> -<h2 id="a-pypi-server-mock">A PyPI Server&nbsp;mock</h2> -<p>The mock is embeded in a thread, to make it available during the tests, -in a non blocking way. We first used <a href="http://wsgi.org"><span class="caps">WSGI</span></a> and -<a href="http://docs.python.org/library/wsgiref.html">wsgiref</a> in order control -what to serve, and to log the requests made to the server, but finally -realised that <a href="http://docs.python.org/library/wsgiref.html">wsgiref</a> is -not python 2.4 compatible (and we <em>need</em> to be python 2.4 compatible in&nbsp;Distutils2).</p> -<p>So, we switched to -<a href="http://docs.python.org/library/basehttpserver.html">BaseHTTPServer</a> and -<a href="http://docs.python.org/library/simplehttpserver.html">SimpleHTTPServer</a>, -and updated our tests accordingly. It&#8217;s been an opportunity to realize -that <a href="http://wsgi.org"><span class="caps">WSGI</span></a> has been a great step forward for making -<span class="caps">HTTP</span> servers, and expose a really simplest way to discuss with <span class="caps">HTTP</span>&nbsp;!</p> -<p>You can find <a href="http://bitbucket.org/ametaireau/distutils2/changesets">the modifications I -made</a>, and the -<a href="http://bitbucket.org/ametaireau/distutils2/src/tip/docs/source/test_framework.rst">related -docs</a> -about this on <a href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket distutils2 -clone</a>.</p> -<h2 id="the-pypi-simple-api">The PyPI Simple <span class="caps">API</span></h2> -<p>So, back to the main problematic: make a python library to access and -request information stored on PyPI, via the simple <span class="caps">API</span>. As I said, I&#8217;ve -just grabbed the work made from -<a href="http://bitbucket.org/tarek/distribute/">Distribute</a>, and played a bit -with, in order to view what are the different use cases, and started to -write the related&nbsp;tests.</p> -<h2 id="the-work-to-come">The work to&nbsp;come</h2> -<p>So, once all use cases covered with tests, I&#8217;ll rewrite a bit the -grabbed code, and do some software design work (to not expose all things -as privates methods, have a clear <span class="caps">API</span>, and other things like this), then -update the tests accordingly and write a documentation to make this&nbsp;clear.</p> -<p>Next step is to a little client, as I&#8217;ve <a href="http://github.com/ametaireau/pypiclient">already started -here</a> I&#8217;ll take you updated&nbsp;!</p>A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html -<p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of -Code</a> program, and will work on -<a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> -<blockquote> -<p>So, it&#8217;s about building the successor of Distutils2, ie. &#8220;the python -package manager&#8221;. Today, there is too many ways to package …</p></blockquote> -<p><span class="caps">WOW</span>. I&#8217;ve been accepted to be a part of the <a href="http://code.google.com/intl/fr/soc/">Google Summer Of -Code</a> program, and will work on -<a href="http://python.org/">python</a> <a href="http://hg.python.org/distutils2/">distutils2</a>, with <a href="http://pygsoc.wordpress.com/">a</a> <a href="http://konryd.blogspot.com/">lot</a> <a href="http://ziade.org/">of</a> (intersting !) <a href="http://zubin71.wordpress.com/">people</a>.</p> -<blockquote> -<p>So, it&#8217;s about building the successor of Distutils2, ie. &#8220;the python -package manager&#8221;. Today, there is too many ways to package a python -application (pip, setuptools, distribute, distutils, etc.) so there is -a huge effort to make in order to make all this packaging stuff -interoperable, as pointed out by -the <a href="http://www.python.org/dev/peps/pep-0376/"><span class="caps">PEP</span> 376</a>.</p> -</blockquote> -<p>In more details, I&#8217;m going to work on the Installer / Uninstaller features of Distutils2, and on a PyPI <span class="caps">XML</span>-<span class="caps">RPC</span> client for distutils2. Here are the already defined&nbsp;tasks:</p> -<ul> -<li>Implement Distutils2 APIs described in <span class="caps">PEP</span>&nbsp;376.</li> -<li>Add the uninstall&nbsp;command.</li> -<li>think about a basic installer / uninstaller script. (with deps) &#8212; - similar to&nbsp;pip/easy_install</li> -<li>in a pypi&nbsp;subpackage;</li> -<li>Integrate a module similar to setuptools&#8217;&nbsp;package_index&#8217;</li> -<li>PyPI <span class="caps">XML</span>-<span class="caps">RPC</span> client for distutils 2: - <a href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> -</ul> -<p>As I&#8217;m relatively new to python, I&#8217;ll need some extra work in order to apply all good practice, among other things that can make a developper-life joyful. I&#8217;ll post here, each week, my advancement, and my tought about python and especialy python packaging&nbsp;world.</p>Python ? go !2009-12-17T00:00:00+01:002009-12-17T00:00:00+01:00tag:blog.notmyidea.org,2009-12-17:/python-go.html -<p>Cela fait maintenant un peu plus d&#8217;un mois que je travaille sur un -projet en <a href="http://www.djangoproject.org">django</a>, et que, -nécessairement, je me forme à <a href="http://python.org/">Python</a>. Je prends -un plaisir non dissimulé à découvrir ce langage (et à l&#8217;utiliser), qui -ne cesse de me surprendre. Les premiers mots qui me …</p> -<p>Cela fait maintenant un peu plus d&#8217;un mois que je travaille sur un -projet en <a href="http://www.djangoproject.org">django</a>, et que, -nécessairement, je me forme à <a href="http://python.org/">Python</a>. Je prends -un plaisir non dissimulé à découvrir ce langage (et à l&#8217;utiliser), qui -ne cesse de me surprendre. Les premiers mots qui me viennent à l&#8217;esprit -à propos de Python, sont &#8220;logique&#8221; et &#8220;simple&#8221;. Et pourtant puissant -pour autant. Je ne manque d&#8217;ailleurs pas une occasion pour faire un peu -d&#8217;<em>évangélisation</em> auprès des quelques personnes qui veulent bien&nbsp;m&#8217;écouter.</p> -<h2 id="the-zen-of-python">The Zen of&nbsp;Python</h2> -<p>Avant toute autre chose, je pense utile de citer Tim Peters, et <a href="http://www.python.org/dev/peps/pep-0020/">le -<span class="caps">PEP20</span></a>, qui constituent une -très bonne introduction au langage, qui prends la forme d&#8217;un <em>easter -egg</em> présent dans&nbsp;python</p> -<div class="highlight"><pre><span></span><code>&gt;&gt;&gt;<span class="w"> </span>import<span class="w"> </span>this -The<span class="w"> </span>Zen<span class="w"> </span>of<span class="w"> </span>Python,<span class="w"> </span>by<span class="w"> </span>Tim<span class="w"> </span>Peters - -Beautiful<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>ugly. -Explicit<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>implicit. -Simple<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>complex. -Complex<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>complicated. -Flat<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>nested. -Sparse<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>dense. -Readability<span class="w"> </span>counts. -Special<span class="w"> </span>cases<span class="w"> </span>aren<span class="s1">&#39;t special enough to break the rules.</span> -<span class="s1">Although practicality beats purity.</span> -<span class="s1">Errors should never pass silently.</span> -<span class="s1">Unless explicitly silenced.</span> -<span class="s1">In the face of ambiguity, refuse the temptation to guess.</span> -<span class="s1">There should be one-- and preferably only one --obvious way to do it.</span> -<span class="s1">Although that way may not be obvious at first unless you&#39;</span>re<span class="w"> </span>Dutch. -Now<span class="w"> </span>is<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>never. -Although<span class="w"> </span>never<span class="w"> </span>is<span class="w"> </span>often<span class="w"> </span>better<span class="w"> </span>than<span class="w"> </span>*right*<span class="w"> </span>now. -If<span class="w"> </span>the<span class="w"> </span>implementation<span class="w"> </span>is<span class="w"> </span>hard<span class="w"> </span>to<span class="w"> </span>explain,<span class="w"> </span>it<span class="s1">&#39;s a bad idea.</span> -<span class="s1">If the implementation is easy to explain, it may be a good idea.</span> -<span class="s1">Namespaces are one honking great idea -- let&#39;</span>s<span class="w"> </span><span class="k">do</span><span class="w"> </span>more<span class="w"> </span>of<span class="w"> </span>those! -</code></pre></div> - -<p>J&#8217;ai la vague impression que c&#8217;est ce que j&#8217;ai toujours cherché à faire -en <span class="caps">PHP</span>, et particulièrement dans <a href="http://www.spiral-project.org">le framework -Spiral</a>, mais en ajoutant ces concepts -dans une sur-couche au langage. Ici, c&#8217;est directement de <em>l&#8217;esprit</em> de -python qu&#8217;il s&#8217;agit, ce qui signifie que la plupart des bibliothèques -python suivent ces concepts. Elle est pas belle la vie&nbsp;?</p> -<h2 id="comment-commencer-et-par-ou">Comment commencer, et par ou&nbsp;?</h2> -<p>Pour ma part, j&#8217;ai commencé par la lecture de quelques livres et -articles intéressants, qui constituent une bonne entrée en matière sur -le sujet (La liste n&#8217;est bien évidemment pas exhaustive et vos -commentaires sont les bienvenus)&nbsp;:</p> -<ul> -<li><a href="http://diveintopython.adrahon.org/">Dive into&nbsp;python</a></li> -<li><a href="http://www.swaroopch.com/notes/Python_fr:Table_des_Matières">A byte of&nbsp;python</a></li> -<li><a href="http://www.amazon.fr/Python-Petit-guide-lusage-développeur/dp/2100508830">Python: petit guide à l&#8217;usage du développeur - agile</a> - de <a href="http://tarekziade.wordpress.com/">Tarek&nbsp;Ziadé</a></li> -<li><a href="http://docs.python.org/index.html">La documentation officielle - python</a>, bien sûr&nbsp;!</li> -<li><a href="http://video.pycon.fr/videos/pycon-fr-2009/">Les vidéos du - pyconfr 2009</a>!</li> -<li>Un peu de temps, et une console python ouverte&nbsp;:)</li> -</ul> -<p>J&#8217;essaye par ailleurs de partager au maximum les ressources que je -trouve de temps à autres, que ce soit <a href="http://www.twitter.com/ametaireau">via -twitter</a> ou <a href="http://delicious.com/ametaireau">via mon compte -delicious</a>. Allez jeter un œil <a href="http://delicious.com/ametaireau/python">au tag -python</a> sur mon profil, peut -être que vous trouverez des choses intéressantes, qui&nbsp;sait!</p> -<h2 id="un-python-sexy">Un python&nbsp;sexy</h2> -<p>Quelques fonctionnalités qui devraient vous mettre l&#8217;eau à la&nbsp;bouche:</p> -<ul> -<li><a href="http://docs.python.org/library/stdtypes.html#comparisons">Le chaînage des opérateurs de - comparaison</a> - est possible (a\&lt;b \&lt;c dans une&nbsp;condition)</li> -<li>Assignation de valeurs multiples (il est possible de faire a,b,c = - 1,2,3 par&nbsp;exemple)</li> -<li><a href="http://docs.python.org/tutorial/datastructures.html">Les listes</a> - sont simples à manipuler&nbsp;!</li> -<li>Les <a href="http://docs.python.org/tutorial/datastructures.html#list-comprehensions">list - comprehension</a>, - ou comment faire des opérations complexes sur les listes, de manière&nbsp;simple.</li> -<li>Les - <a href="http://docs.python.org/library/doctest.html?highlight=doctest">doctests</a>: - ou comment faire des tests directement dans la documentation de vos - classes, tout en la documentant avec de vrais&nbsp;exemples.</li> -<li>Les - <a href="http://www.python.org/doc/essays/metaclasses/meta-vladimir.txt">métaclasses</a>, - ou comment contrôler la manière dont les classes se&nbsp;construisent</li> -<li>Python est <a href="http://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language">un langage à typage fort - dynamique</a>: - c&#8217;est ce qui m&#8217;agaçait avec <span class="caps">PHP</span> qui est un langage à typage faible&nbsp;dynamique.</li> -</ul> -<p>Cous pouvez également aller regarder <a href="http://video.pycon.fr/videos/free/53/">l&#8217;atelier donné par Victor Stinner -durant le Pyconfr 09</a>. Have fun&nbsp;!</p> \ No newline at end of file diff --git a/feeds/weeknotes.atom.xml b/feeds/weeknotes.atom.xml index daaed4d..30c2f68 100644 --- a/feeds/weeknotes.atom.xml +++ b/feeds/weeknotes.atom.xml @@ -1,5 +1,39 @@ -Alexis Métaireau - weeknoteshttps://blog.notmyidea.org/2023-09-24T00:00:00+02:002023, Semaine 382023-09-24T00:00:00+02:002023-09-24T00:00:00+02:00tag:blog.notmyidea.org,2023-09-24:/2023-semaine-38.html +Alexis Métaireau - weeknoteshttps://blog.notmyidea.org/2023-09-29T00:00:00+02:002023, Semaine 392023-09-29T00:00:00+02:002023-09-29T00:00:00+02:00tag:blog.notmyidea.org,2023-09-29:/2023-semaine-39.html +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques …</dd></dl> +<h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> +<dl> +<dt>Framasoft</dt> +<dd>J&#8217;ai commencé à travailler sur l&#8217;outil de supervision, en partant bille en tête sur une solution qui s&#8217;est avérée ne pas être la plus simple à mettre en place. J&#8217;ai passé pas mal de temps à questionner mes choix techniques, pour finalement en changer et me questionner sur la partie <strong>metier</strong>, ce qui me semblait plus intéressant. A partir du moment où j&#8217;ai arrêté d&#8217;essayer d&#8217;appliquer une solution « déjà faite » j&#8217;ai pu me questionner sur le modèle de données et aller de l&#8217;avant. Étrangement c&#8217;est quand j&#8217;ai produit le moins de code que j&#8217;ai trouvé que j&#8217;étais le plus&nbsp;productif.</dd> +<dt>Notmyidea</dt> +<dd>Je n&#8217;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&nbsp;décider.</dd> +<dd>J&#8217;ai <del>procrastiné</del> passé beaucoup plus de temps que prévu sur la mise en place d&#8217;outils utiles pour moi, et à peaufiné mon site web. J&#8217;ai maintenant un bouncer <span class="caps">ZNC</span> et un <span class="caps">VPN</span> fait maison qui me permettent de travailler dans de meilleures conditions. Je suis à la fois content d&#8217;avoir pris le temps de mettre en place des outils, et en même temps j&#8217;ai une impression de&nbsp;procrastination.</dd> +</dl> +<h2 id="des-joies">Des&nbsp;joies</h2> +<ul> +<li>Avoir pris le temps d&#8217;aller « à la ville » pour passer du temps avec des amis et&nbsp;sociabiliser.</li> +<li>M&#8217;écouter et décider de dormir sur place pour travailler aussi sur Rennes le&nbsp;lendemain.</li> +<li>Aller à l&#8217;espace de coworkig à côté de chez&nbsp;moi.</li> +<li>Prendre le temps de faire des choses peu importantes entassées dans ma todolist depuis trop&nbsp;longtemps.</li> +<li>Récolter des fruits de discussions passées lors d&#8217;une soirée. Vive les todo-list&nbsp;!</li> +<li>Voir qu&#8217;une demande de modifications que j&#8217;ai faite soit appréciée et intégrée&nbsp;rapidement.</li> +<li>Dépanner le serveur de <a href="https://github.com/almet/copanier">copanier</a>, trouver le problème rapidement et le régler&nbsp;facilement.</li> +</ul> +<h2 id="des-peines">Des&nbsp;peines</h2> +<ul> +<li>Je suis retombé malade en fin de semaine, et donc bien fatigué. Ca impacte mon moral et ma capacité de&nbsp;concentration.</li> +<li>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&nbsp;autres.</li> +<li>Sentir que ma posture dans les conversations est plus ferme que par le passé. Je suis à la fois content de ne pas <strong>toujours</strong> me remettre en question, mais j&#8217;aimerai réussir à faire preuve de plus d&#8217;ouverture. Il faut trouver&nbsp;l&#8217;équilibre </li> +<li>Triste de voir des conflits escalader alors que ça pourrait être&nbsp;autrement.</li> +</ul> +<h2 id="vu-lu-ecoute">Vu, lu,&nbsp;écouté</h2> +<ul> +<li>🎮 J&#8217;ai continué <a href="https://fr.wikipedia.org/wiki/Baba_Is_You">Baba is you</a> avec Arthur. C&#8217;était sympa de se faire les reflexions à deux&nbsp;cerveaux.</li> +<li>▶︎ <a href="https://www.youtube.com/watch?app=desktop&amp;v=dVzfNZN9NKI&amp;list=PL8uoeex94UhFcwvAfWHybD7SfNgIUBRo-&amp;index=128">Vu une présentation sur DuckDB</a>, une base de données locale et minimaliste qui semble adaptée pour de la visualisation de données à grande&nbsp;échelle.</li> +</ul>2023, Semaine 382023-09-24T00:00:00+02:002023-09-24T00:00:00+02:00tag:blog.notmyidea.org,2023-09-24:/2023-semaine-38.html <h2 id="ce-qui-sest-passe">Ce qui s&#8217;est&nbsp;passé</h2> <dl> <dt>Framasoft</dt> diff --git a/first-week-working-on-distutils2.html b/first-week-working-on-distutils2.html index e59beb2..c0c2ccf 100644 --- a/first-week-working-on-distutils2.html +++ b/first-week-working-on-distutils2.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -90,6 +90,9 @@ update the tests accordingly and write a documentation to make this clear.<

    Next step is to a little client, as I’ve already started here I’ll take you updated !

    +
    + +
    diff --git a/focusing-on-what-matters.html b/focusing-on-what-matters.html index a40a223..eba2f2b 100644 --- a/focusing-on-what-matters.html +++ b/focusing-on-what-matters.html @@ -73,6 +73,9 @@ and I’ll report back in here my findings. Here’s the challenge:

    Let’s see how it goes :)

    +
    + +
    diff --git a/fork-you-or-how-the-social-coding-can-help-you.html b/fork-you-or-how-the-social-coding-can-help-you.html index 0a50755..2f37a0e 100644 --- a/fork-you-or-how-the-social-coding-can-help-you.html +++ b/fork-you-or-how-the-social-coding-can-help-you.html @@ -140,6 +140,9 @@ on how the programs you’re using are made, consider publishing your experimentations, and share them with others, you will see, it’s kind of addictive !

    +
    + +
    diff --git a/forum-ouvert-animation-et-posture.html b/forum-ouvert-animation-et-posture.html index 6a5fefc..d2ea6f2 100644 --- a/forum-ouvert-animation-et-posture.html +++ b/forum-ouvert-animation-et-posture.html @@ -78,6 +78,9 @@

    En tout cas, j’aime bien l’idée qu’il soit possible d’à la fois animer les temps de forums et de participer. Dans ce cas là, existe-il des stratagèmes / artifices pour permettre de visibiliser ces prises de pouvoir pendant les discussions ?

    Je suis preneur de tout retour d’expérience sur le sujet !

    +
    + +
    diff --git a/francis-dupuis-deri-democratie.html b/francis-dupuis-deri-democratie.html index 4f49e0c..0c6a953 100644 --- a/francis-dupuis-deri-democratie.html +++ b/francis-dupuis-deri-democratie.html @@ -127,6 +127,9 @@

    On parle donc d’une pince à ciseler un clôture d’un réacteur nucléaire. Il ne faut surtout pas casser les vitrines de banques parce que c’est de la violence. C’est incroyable. Dans les mouvement sociaux, des personnes sont tellement concernés par la violence que ça crée des débats. Le débat éthique violence / non-violence est traversé par des exemples qui sont mal compris. Par exemple Gandi et MLK.

    Mais c’est une illusion complète. Dans le mouvement d’indépendance de l’inde auquel participait gandi, dans le même mouvement des personnes attaquaient avec des bombes et des mitraillettes.

    +
    + +
    diff --git a/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html b/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html index 1dc8f8d..fabfedf 100644 --- a/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html +++ b/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html @@ -61,6 +61,9 @@ qui comme les maths n’ont besoin que d’une craie et d’un tableau noir besoin de l’apprendre.

    +
    + +
    diff --git a/generation-de-formulaires-geolocalises.html b/generation-de-formulaires-geolocalises.html index 9f03a58..ebc1fd7 100644 --- a/generation-de-formulaires-geolocalises.html +++ b/generation-de-formulaires-geolocalises.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -214,6 +214,9 @@ vos commentaires, c’est son objectif!

    Merci à Arnaud pour la relecture et la correction de quelques typos dans le texte :)

    +
    + +
    diff --git a/gnome-3-extensions.html b/gnome-3-extensions.html index 3bfc3da..ae84657 100644 --- a/gnome-3-extensions.html +++ b/gnome-3-extensions.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -72,6 +72,9 @@ que je liste ici.

    Vous pouvez aller faire un tour sur https://extensions.gnome.org/ pour en trouver d’autres à votre gout.

    +
    + +
    diff --git a/groovy.html b/groovy.html index 73434ff..06ccd54 100644 --- a/groovy.html +++ b/groovy.html @@ -40,6 +40,9 @@ tête commence à hocher.

    C’est pour ça que j’ai du mal à répondre quand on me demande quel type de musique j’aime bien. Bah voila, maintenant je sais, je l’aime groovy ;)

    +
    + +
    diff --git a/groupe-de-paroles-hommes.html b/groupe-de-paroles-hommes.html index 43f0f84..720f67f 100644 --- a/groupe-de-paroles-hommes.html +++ b/groupe-de-paroles-hommes.html @@ -53,6 +53,9 @@

    Mais quand je challenge l’idée de la non-mixité, je ne trouve pas de raison — autre que la peur d’être jugé — de refuser la mixité dans notre groupe. Je crois qu’ouvrir nos discussions nous permettrait d’affronter certains sujets de manière plus juste.

    Lors d’un de nos regroupements, nous décidons donc, après quelques discussions, d’ouvrir le groupe à d’autres personnes, peu importe leur sexe, tout en cherchant à conserver un groupe de petite taille, pour que la création d’une confiance mutuelle soit plus simple à obtenir.

    +
    + +
    diff --git a/groupement-dachats-partage-dexperience.html b/groupement-dachats-partage-dexperience.html index dcf8fca..5ed19a7 100644 --- a/groupement-dachats-partage-dexperience.html +++ b/groupement-dachats-partage-dexperience.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -92,6 +92,9 @@ paiements s’effectuent directement entre nous.

    Bon groupement d’achat ;)

    +
    + +
    diff --git a/habitat-collectif.html b/habitat-collectif.html index ba0bda9..84e1fba 100644 --- a/habitat-collectif.html +++ b/habitat-collectif.html @@ -48,6 +48,9 @@ changer nos modes de vie et prendre plus de temps les uns pour les autres.<
  • +
    + +
    diff --git a/help-me-to-go-to-the-distutils2-paris-sprint.html b/help-me-to-go-to-the-distutils2-paris-sprint.html index e222855..b4b646e 100644 --- a/help-me-to-go-to-the-distutils2-paris-sprint.html +++ b/help-me-to-go-to-the-distutils2-paris-sprint.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -53,6 +53,9 @@ use this chipin page: http://ametaireau.chipin.com/distutils2-sprint-in-paris

    Thanks for your support !

    +
    + +
    diff --git a/hommes-anarchistes-face-au-feminisme.html b/hommes-anarchistes-face-au-feminisme.html index 33e6ae8..b22c393 100644 --- a/hommes-anarchistes-face-au-feminisme.html +++ b/hommes-anarchistes-face-au-feminisme.html @@ -26,7 +26,7 @@
    -

    « Hommes Anarchistes face au féminisme » par Françis Dupuis-Déri

    +

    Hommes Anarchistes face au féminisme
    par Françis Dupuis-Déri

    Pistes de réflexion au sujet de la politique, de l'amour et de la sexualité

    @@ -53,6 +53,9 @@ #féminisme, #anarchisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/how-are-you-handling-your-shared-expenses.html b/how-are-you-handling-your-shared-expenses.html index e5499f2..a513bff 100644 --- a/how-are-you-handling-your-shared-expenses.html +++ b/how-are-you-handling-your-shared-expenses.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -103,6 +103,9 @@ you have a nice idea about this, if you want to tweak it or to fill bugs. Don’t hesitate a second! The project lives at http://github.com/spiral-project/ihatemoney/

    +
    + +
    diff --git a/how-to-install-nginx-php-53-on-freebsd.html b/how-to-install-nginx-php-53-on-freebsd.html index 588a9ef..6f9fb1c 100644 --- a/how-to-install-nginx-php-53-on-freebsd.html +++ b/how-to-install-nginx-php-53-on-freebsd.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -89,6 +89,9 @@ that will work without effort over time.

    And that’s it !

    +
    + +
    diff --git a/how-to-reboot-your-bebox-using-the-cli.html b/how-to-reboot-your-bebox-using-the-cli.html index 1aac5e3..3c958f7 100644 --- a/how-to-reboot-your-bebox-using-the-cli.html +++ b/how-to-reboot-your-bebox-using-the-cli.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -80,6 +80,9 @@ the command line tools curl, grep and tail (but really harder to read).

    reboot(url, args.username, args.password) +
    + +
    diff --git a/how-to-run-the-vigogne-model-locally.html b/how-to-run-the-vigogne-model-locally.html index 81ec1a1..27e45f4 100644 --- a/how-to-run-the-vigogne-model-locally.html +++ b/how-to-run-the-vigogne-model-locally.html @@ -44,6 +44,9 @@ llm models default #llm - Posté dans la catégorie code

    +
    + +
    diff --git a/ignorance-et-vertu.html b/ignorance-et-vertu.html index baf0e9a..d4edddb 100644 --- a/ignorance-et-vertu.html +++ b/ignorance-et-vertu.html @@ -38,6 +38,9 @@

    Reconnaître mon ignorance me permet de découvrir de laisser mes interlocut⋅eurs⋅rices m’expliquer de manière claire ce que je ne connais pas encore, là où laisser penser que je connais ne m’apporte que du flou et une posture éthiquement bancale.

    +
    + +
    diff --git a/images/isbn-covers/31eql7bSB8L._SL160_.jpg b/images/isbn-covers/31eql7bSB8L._SL160_.jpg new file mode 100644 index 0000000..3506984 Binary files /dev/null and b/images/isbn-covers/31eql7bSB8L._SL160_.jpg differ diff --git a/images/isbn-covers/9781260474183.jpg b/images/isbn-covers/9781260474183.jpg new file mode 100644 index 0000000..fa6f267 Binary files /dev/null and b/images/isbn-covers/9781260474183.jpg differ diff --git a/images/isbn-covers/9782080420015.jpg b/images/isbn-covers/9782080420015.jpg new file mode 100644 index 0000000..eae0733 Binary files /dev/null and b/images/isbn-covers/9782080420015.jpg differ diff --git a/images/isbn-covers/9782354801786.jpg b/images/isbn-covers/9782354801786.jpg new file mode 100644 index 0000000..12af4ee Binary files /dev/null and b/images/isbn-covers/9782354801786.jpg differ diff --git a/images/isbn-covers/9782358721974.jpg b/images/isbn-covers/9782358721974.jpg new file mode 100644 index 0000000..1596c73 Binary files /dev/null and b/images/isbn-covers/9782358721974.jpg differ diff --git a/images/isbn-covers/9782371000926.jpg b/images/isbn-covers/9782371000926.jpg new file mode 100644 index 0000000..3506984 Binary files /dev/null and b/images/isbn-covers/9782371000926.jpg differ diff --git a/images/isbn-covers/9782849503812.jpg b/images/isbn-covers/9782849503812.jpg new file mode 100644 index 0000000..8259a35 Binary files /dev/null and b/images/isbn-covers/9782849503812.jpg differ diff --git a/images/isbn-covers/9782954323701.jpg b/images/isbn-covers/9782954323701.jpg new file mode 100644 index 0000000..0399912 Binary files /dev/null and b/images/isbn-covers/9782954323701.jpg differ diff --git a/images/isbn-covers/9782955678244.jpg b/images/isbn-covers/9782955678244.jpg new file mode 100644 index 0000000..57f10e0 Binary files /dev/null and b/images/isbn-covers/9782955678244.jpg differ diff --git a/images/isbn-covers/9791091772198.jpg b/images/isbn-covers/9791091772198.jpg new file mode 100644 index 0000000..bbcd410 Binary files /dev/null and b/images/isbn-covers/9791091772198.jpg differ diff --git a/images/un-an/chainon-manquant.png b/images/un-an/chainon-manquant.png new file mode 100644 index 0000000..ad53d05 Binary files /dev/null and b/images/un-an/chainon-manquant.png differ diff --git a/images/un-an/monstrueuse-normalite.png b/images/un-an/monstrueuse-normalite.png new file mode 100644 index 0000000..3defd2d Binary files /dev/null and b/images/un-an/monstrueuse-normalite.png differ diff --git a/images/un-an/sobacha.png b/images/un-an/sobacha.png new file mode 100644 index 0000000..040982f Binary files /dev/null and b/images/un-an/sobacha.png differ diff --git a/implementing-cors-in-cornice.html b/implementing-cors-in-cornice.html index 259d64c..e96932b 100644 --- a/implementing-cors-in-cornice.html +++ b/implementing-cors-in-cornice.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -255,6 +255,9 @@ want to either understand how CORS works, or if you wa specification isn’t hard to read, so you may want to go through it. Especially the “resource processing model” section

    +
    + +
    diff --git a/index.html b/index.html index 8cd48b4..cb141db 100644 --- a/index.html +++ b/index.html @@ -124,6 +124,9 @@ même. La maintenance des serveurs fait donc partie du lot :-)
  • BTS Informatique et Réseau, Angers.
  • +
    + +
    diff --git a/installation-de-mosquitto-influxdb-telegraf-et-grafana.html b/installation-de-mosquitto-influxdb-telegraf-et-grafana.html index b0f3407..46cf024 100644 --- a/installation-de-mosquitto-influxdb-telegraf-et-grafana.html +++ b/installation-de-mosquitto-influxdb-telegraf-et-grafana.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -205,9 +205,12 @@ sudo /bin/systemctl startVoilà ! A ce moment là, tout doit être fonctionnel, il ne reste plus qu’à configurer le Grafana pour grapher les données enregistrées dans InfluxDB.

    - #Administration Système - Posté dans la catégorie technologie + #Administration Système - Posté dans la catégorie code

    +
    + +
    diff --git a/introducing-cornice.html b/introducing-cornice.html index 049388d..41872f3 100644 --- a/introducing-cornice.html +++ b/introducing-cornice.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -173,6 +173,9 @@ haskish and want to see the sources, + diff --git a/introducing-the-distutils2-index-crawlers.html b/introducing-the-distutils2-index-crawlers.html index 2986246..3b33807 100644 --- a/introducing-the-distutils2-index-crawlers.html +++ b/introducing-the-distutils2-index-crawlers.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -134,6 +134,9 @@ schedule, and the goal is to be sure everything will be ready in time, for the end of the summer. (And now, I need to learn to follow schedules …)

    +
    + +
    diff --git a/journal/index.html b/journal/index.html index c2f308d..7e28958 100644 --- a/journal/index.html +++ b/journal/index.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index10.html b/journal/index10.html index c2f308d..7e28958 100644 --- a/journal/index10.html +++ b/journal/index10.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index11.html b/journal/index11.html index c2f308d..7e28958 100644 --- a/journal/index11.html +++ b/journal/index11.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index12.html b/journal/index12.html index c2f308d..7e28958 100644 --- a/journal/index12.html +++ b/journal/index12.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index13.html b/journal/index13.html index c2f308d..7e28958 100644 --- a/journal/index13.html +++ b/journal/index13.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index14.html b/journal/index14.html index c2f308d..7e28958 100644 --- a/journal/index14.html +++ b/journal/index14.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index15.html b/journal/index15.html index c2f308d..7e28958 100644 --- a/journal/index15.html +++ b/journal/index15.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index16.html b/journal/index16.html index c2f308d..7e28958 100644 --- a/journal/index16.html +++ b/journal/index16.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index17.html b/journal/index17.html index c2f308d..7e28958 100644 --- a/journal/index17.html +++ b/journal/index17.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index18.html b/journal/index18.html index c2f308d..7e28958 100644 --- a/journal/index18.html +++ b/journal/index18.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index19.html b/journal/index19.html index c2f308d..7e28958 100644 --- a/journal/index19.html +++ b/journal/index19.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index2.html b/journal/index2.html index c2f308d..7e28958 100644 --- a/journal/index2.html +++ b/journal/index2.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index20.html b/journal/index20.html index c2f308d..7e28958 100644 --- a/journal/index20.html +++ b/journal/index20.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index21.html b/journal/index21.html index c2f308d..7e28958 100644 --- a/journal/index21.html +++ b/journal/index21.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index22.html b/journal/index22.html index c2f308d..7e28958 100644 --- a/journal/index22.html +++ b/journal/index22.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index23.html b/journal/index23.html index c2f308d..7e28958 100644 --- a/journal/index23.html +++ b/journal/index23.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index3.html b/journal/index3.html index c2f308d..7e28958 100644 --- a/journal/index3.html +++ b/journal/index3.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index4.html b/journal/index4.html index c2f308d..7e28958 100644 --- a/journal/index4.html +++ b/journal/index4.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index5.html b/journal/index5.html index c2f308d..7e28958 100644 --- a/journal/index5.html +++ b/journal/index5.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index6.html b/journal/index6.html index c2f308d..7e28958 100644 --- a/journal/index6.html +++ b/journal/index6.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index7.html b/journal/index7.html index c2f308d..7e28958 100644 --- a/journal/index7.html +++ b/journal/index7.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index8.html b/journal/index8.html index c2f308d..7e28958 100644 --- a/journal/index8.html +++ b/journal/index8.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/journal/index9.html b/journal/index9.html index c2f308d..7e28958 100644 --- a/journal/index9.html +++ b/journal/index9.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Journal

    +

    Journal + +

    Quelques pensées partagées, bien souvent sur le monde du travail ou de la technologie.

    @@ -221,6 +223,9 @@
  • AMAP + Média = Paniers bio à 5e ?!
  • +
    + +
    diff --git a/la-conjuration-des-egos.html b/la-conjuration-des-egos.html index f1792e0..da00c16 100644 --- a/la-conjuration-des-egos.html +++ b/la-conjuration-des-egos.html @@ -26,7 +26,7 @@
    -

    « La conjuration des égos » par Aude Vidal

    +

    La conjuration des égos
    par Aude Vidal

    Féminismes et individualisme

    @@ -72,6 +72,9 @@ #féminisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/la-simplicite-volontaire-contre-le-mythe-de-labondance.html b/la-simplicite-volontaire-contre-le-mythe-de-labondance.html index a778135..4a8a7c2 100644 --- a/la-simplicite-volontaire-contre-le-mythe-de-labondance.html +++ b/la-simplicite-volontaire-contre-le-mythe-de-labondance.html @@ -41,6 +41,9 @@ l’abondance”

    Nous ne devons plus accepter de faire de la politique aux conditions de nos adversaires, car c’est la seule façon d’éviter le pessimisme, le ressentiment, une désensibilisation croissante et… la mort lente.

    +
    + +
    diff --git a/language.html b/language.html index 81b19f0..04f245f 100644 --- a/language.html +++ b/language.html @@ -70,6 +70,9 @@ la mienne.

    la langue n’est pas la mienne, dans tels cas, traduire les contenus intéressants vers l’anglais semble une solution (chronophage).

    +
    + +
    diff --git a/languages.html b/languages.html index 7395176..7e31cd0 100644 --- a/languages.html +++ b/languages.html @@ -39,6 +39,9 @@ comme d’hab font un travail impeccable.

    http://www.studiomezzanine.fr/natascha-rogers/

    +
    + +
    diff --git a/larrivee-du-trouble-ou-comment-faire-des-neipa.html b/larrivee-du-trouble-ou-comment-faire-des-neipa.html index 20df78b..f721930 100644 --- a/larrivee-du-trouble-ou-comment-faire-des-neipa.html +++ b/larrivee-du-trouble-ou-comment-faire-des-neipa.html @@ -69,6 +69,9 @@

    La révolution de la côte Est bat son plein et si vous ne pouvez pas venir sur place pour goûter un extrait, vous pouvez maintenant au moins commencer à brasser des bières avec un caractère similaire. Et si vous n’êtes pas un fan de ce type de bière, faites bien attention à laisser ceux qui apprécient déguster en paix.

    Remerciements spéciaux à tous les brasseurs qui ont contribué à la production de cet article: John Kimmich de The Alchemist, Shaun Hill de Hill Farmstead, Joel Mahaffrey de Foundation Brewing, Matt Nadeau de Rock Art Brewery et JC Tetrealt de Trillium. Allez leur rendre visite !

    +
    + +
    diff --git a/le-mail-doit-il-mourir.html b/le-mail-doit-il-mourir.html index 6d44308..a81ba07 100644 --- a/le-mail-doit-il-mourir.html +++ b/le-mail-doit-il-mourir.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -51,6 +51,9 @@ mail fonctionnel.

    Avec au moins ces besoins en tête, il semble qu’une revue de l’ensemble des projets existants pointe du doigt vers pond, ou vers Signal.

    Malheureusement, Pond est le projet d’une seule personne, qui veut plutôt utiliser ce code comme démonstration du concept en question.

    +
    + +
    diff --git a/le-piege-du-developpement-personnel.html b/le-piege-du-developpement-personnel.html index 3e0142c..9cc1651 100644 --- a/le-piege-du-developpement-personnel.html +++ b/le-piege-du-developpement-personnel.html @@ -79,6 +79,9 @@ +
    + +
    diff --git a/le-revenu-de-base.html b/le-revenu-de-base.html index 327d606..ea75c26 100644 --- a/le-revenu-de-base.html +++ b/le-revenu-de-base.html @@ -189,6 +189,9 @@ et à reconnaître à ces activités qui n’ont pas la rémunération pour but une dignité et une valeur éminentes, tant pour les individus que pour la société elle-même.

    +
    + +
    diff --git a/le-secret-du-bonheur.html b/le-secret-du-bonheur.html index fe0558f..bd6e25c 100644 --- a/le-secret-du-bonheur.html +++ b/le-secret-du-bonheur.html @@ -69,6 +69,9 @@ tu fais, il y aura toujours quelqu’un pour y trouver à redire. Fais ce qui te plaît et là tu seras vraiment heureux.

    +
    + +
    diff --git a/le-temps-des-graces-courrez-y.html b/le-temps-des-graces-courrez-y.html index d8e19c5..c381dc2 100644 --- a/le-temps-des-graces-courrez-y.html +++ b/le-temps-des-graces-courrez-y.html @@ -91,6 +91,9 @@ lobbys. Passionnant, vraiment.

    Courrez-y, je vous dis.

    +
    + +
    diff --git a/lectures/index.html b/lectures/index.html index c8df4f7..02975b6 100644 --- a/lectures/index.html +++ b/lectures/index.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Notes de lecture

    +

    Notes de lecture + +

    Quelques notes prises au détour d'une lecture, plutôt pour ne pas les oublier, et me remémorer le livre quand j'en ai besoin.

    @@ -112,6 +114,9 @@
  • Comment la non-violence protège l’état
  • +
    + +
    diff --git a/lectures/index2.html b/lectures/index2.html index c8df4f7..02975b6 100644 --- a/lectures/index2.html +++ b/lectures/index2.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Notes de lecture

    +

    Notes de lecture + +

    Quelques notes prises au détour d'une lecture, plutôt pour ne pas les oublier, et me remémorer le livre quand j'en ai besoin.

    @@ -112,6 +114,9 @@
  • Comment la non-violence protège l’état
  • +
    + +
    diff --git a/lectures/index3.html b/lectures/index3.html index c8df4f7..02975b6 100644 --- a/lectures/index3.html +++ b/lectures/index3.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Notes de lecture

    +

    Notes de lecture + +

    Quelques notes prises au détour d'une lecture, plutôt pour ne pas les oublier, et me remémorer le livre quand j'en ai besoin.

    @@ -112,6 +114,9 @@
  • Comment la non-violence protège l’état
  • +
    + +
    diff --git a/lectures/index4.html b/lectures/index4.html index c8df4f7..02975b6 100644 --- a/lectures/index4.html +++ b/lectures/index4.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Notes de lecture

    +

    Notes de lecture + +

    Quelques notes prises au détour d'une lecture, plutôt pour ne pas les oublier, et me remémorer le livre quand j'en ai besoin.

    @@ -112,6 +114,9 @@
  • Comment la non-violence protège l’état
  • +
    + +
    diff --git a/lectures/index5.html b/lectures/index5.html index c8df4f7..02975b6 100644 --- a/lectures/index5.html +++ b/lectures/index5.html @@ -24,7 +24,9 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Notes de lecture

    +

    Notes de lecture + +

    Quelques notes prises au détour d'une lecture, plutôt pour ne pas les oublier, et me remémorer le livre quand j'en ai besoin.

    @@ -112,6 +114,9 @@
  • Comment la non-violence protège l’état
  • +
    + +
    diff --git a/leffondrement-parlons-en.html b/leffondrement-parlons-en.html index 13cd22b..c6891d5 100644 --- a/leffondrement-parlons-en.html +++ b/leffondrement-parlons-en.html @@ -26,7 +26,7 @@
    -

    « L’effondrement, parlons-en… » par Jérémie Cravatte

    +

    L’effondrement, parlons-en…
    par Jérémie Cravatte

    Les limites de la "collapsologie".

    @@ -77,6 +77,9 @@ manières dont les basculements écologiques sont et seront vécus.

    #écologie, #collapsologie - Posté dans la catégorie lectures

    +
    + +
    diff --git a/lere-de-la-critique.html b/lere-de-la-critique.html index 4ecb946..36275c2 100644 --- a/lere-de-la-critique.html +++ b/lere-de-la-critique.html @@ -69,6 +69,9 @@ #Savoir-Être - Posté dans la catégorie journal

    +
    + +
    diff --git a/les-dangers-du-livre-numerique.html b/les-dangers-du-livre-numerique.html index d4b940f..bd0056f 100644 --- a/les-dangers-du-livre-numerique.html +++ b/les-dangers-du-livre-numerique.html @@ -81,6 +81,9 @@ pas le choix du grand verrou numérique.

    initiatives existent déjà ?

    Et vous, vous les achetez ou vos livres ?

    +
    + +
    diff --git a/les-ignorances-affectives.html b/les-ignorances-affectives.html index 54f21d9..fd51185 100644 --- a/les-ignorances-affectives.html +++ b/les-ignorances-affectives.html @@ -26,7 +26,7 @@
    -

    « Les ignorances affectives » par Jérémie Lefranc

    +

    Les ignorances affectives
    par Jérémie Lefranc

    Un texte de Jérémie Lefranc, dont j'ai beaucoup apprécié la lecture. Ça parle d'un collectif auquel j'ai pu me rendre il y a plusieurs années, « Cravirola », et de la manière dont certains conflits s'y sont déroulés.

    @@ -58,6 +58,9 @@ #collectif, #médiation - Posté dans la catégorie lectures

    +
    + +
    diff --git a/les-problemes-de-pgp.html b/les-problemes-de-pgp.html index e59ccd4..e9b1c37 100644 --- a/les-problemes-de-pgp.html +++ b/les-problemes-de-pgp.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -97,6 +97,9 @@ de chiffrement d’échanges de messages et de VPN encore quelque chose à regarder.

    Enfin bref, y’a du taf.

    +
    + +
    diff --git a/lets-encrypt-haproxy.html b/lets-encrypt-haproxy.html index 90069b1..d609b7d 100644 --- a/lets-encrypt-haproxy.html +++ b/lets-encrypt-haproxy.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -141,6 +141,9 @@ compatible avec HAProxy:

    github, si jamais ça peut vous servir, tant mieux !

    +
    + +
    diff --git a/lhorizon.html b/lhorizon.html index 4acb510..9edc043 100644 --- a/lhorizon.html +++ b/lhorizon.html @@ -74,6 +74,9 @@ se refait pas !)

    peu et d’expérimenter des choses collectivement…

    On se recroisera surement :)

    +
    + +
    diff --git a/lifestyle.html b/lifestyle.html index 8eff103..daa4a20 100644 --- a/lifestyle.html +++ b/lifestyle.html @@ -120,6 +120,9 @@ revenir dessus jour après jour me permettra surement d’avoir un aperçu un peu plus global du travail accompli.

    L’avenir dira si tout ça fonctionne :-)

    +
    + +
    diff --git a/limites-horaires.html b/limites-horaires.html index 39517a4..d461e85 100644 --- a/limites-horaires.html +++ b/limites-horaires.html @@ -36,6 +36,9 @@

    Depuis que j’ai décidé de faire un break technologique, je ne m’en sors pas si mal. Parmi les mesures que j’avais envie de prendre, était le fait de limiter le temps d’utilisation de mon ordinateur personnel.

    J’utilise le logiciel timekpr-next qui me permet de définir une limite d’utilisation par jour. Le logiciel me notifie quand je dois m’arrêter, et même si je peux rajouter du temps si j’en ai besoin, ça semble plutôt marcher : ça me donne un moyen de percevoir le temps que je dépense derrière cet ordinateur.

    +
    + +
    diff --git a/llm-command-line-tips.html b/llm-command-line-tips.html index 62defe2..0e3d7b7 100644 --- a/llm-command-line-tips.html +++ b/llm-command-line-tips.html @@ -42,6 +42,9 @@ #python, #llm, #bash, #sqlite - Posté dans la catégorie code

    +
    + +
    diff --git a/micropolitiques-des-groupes.html b/micropolitiques-des-groupes.html index e5e1325..abf76bc 100644 --- a/micropolitiques-des-groupes.html +++ b/micropolitiques-des-groupes.html @@ -26,7 +26,10 @@
    -

    « Micropolitiques des groupes » par David Vercauteren

    +
    + +
    +

    Micropolitiques des groupes
    par David Vercauteren

    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.

    @@ -91,6 +94,9 @@ L’analyse, l’élaboration, la remise en question des relations de pouvoi

    Réunions

    micropolitiques des groupes - pour une écologie des pratiques collectives

    +
    + +
    diff --git a/motivation-benevolat-et-participation.html b/motivation-benevolat-et-participation.html index fa80327..e990bbc 100644 --- a/motivation-benevolat-et-participation.html +++ b/motivation-benevolat-et-participation.html @@ -102,6 +102,9 @@ projets qui pourraient êtres réalisés.

    ensemble durant une semaine sans objectif commun à priori et sans distractions, vous verrez bien ce qui en ressortira !

    +
    + +
    diff --git a/mozilla-first-months.html b/mozilla-first-months.html index e1f4cf9..2c6dc2e 100644 --- a/mozilla-first-months.html +++ b/mozilla-first-months.html @@ -82,6 +82,9 @@ things seems to be going.

    Oh, and I will try to post some more technical articles soon, I’m missing them :)

    +
    + +
    diff --git a/musique-creation-et-partage.html b/musique-creation-et-partage.html index 6a57bf3..027f1dc 100644 --- a/musique-creation-et-partage.html +++ b/musique-creation-et-partage.html @@ -37,6 +37,9 @@

    Composer, proposer, écouter, échanger, faire évoluer des sons et des idées se passe sans encombre, retrouver cette passion que j’avais mise de côté me plaît.

    Je sors de ma zone de confort : je joue sur un synthé analogique et j’apprends à faire un peu d’enregistrement sonore par la même occasion.

    +
    + +
    diff --git a/neipa-2.html b/neipa-2.html index d71a687..633d4f7 100644 --- a/neipa-2.html +++ b/neipa-2.html @@ -114,6 +114,9 @@ pH: 5.2 (atteint)

  • Sur l’avoine toujours, il faut dépasser 18% pour avoir un côté moelleux. Certains mettent jusqu’à 40% !
  • +
    + +
    diff --git a/neipa-3.html b/neipa-3.html index 2897000..840d789 100644 --- a/neipa-3.html +++ b/neipa-3.html @@ -118,6 +118,9 @@ pH: 5.2 (5.4 mesuré)

  • D’une manière générale, j’ai l’impression d’être un peu à l’arrache sur la partie fermentation. Il faudrait vraiment que j’ai un plan et que je m’y tienne. Plusieurs questions me semblent encore à résoudre: combien de temps laisser le houblon à cru ? A quelle température ?
  • +
    + +
    diff --git a/new-year-python-meme-2012.html b/new-year-python-meme-2012.html index d0dee43..b0fc760 100644 --- a/new-year-python-meme-2012.html +++ b/new-year-python-meme-2012.html @@ -103,6 +103,9 @@ a nice way in Python, I would like to see packaging fixed in python :-)

  • tweet it with the #2012pythonmeme hashtag
  • +
    + +
    diff --git a/notes-economie-libidinale-et-economie-politique.html b/notes-economie-libidinale-et-economie-politique.html index bdbc2da..01fee1d 100644 --- a/notes-economie-libidinale-et-economie-politique.html +++ b/notes-economie-libidinale-et-economie-politique.html @@ -61,6 +61,9 @@ révolutions aussi.

    l’amérique (d’après Juliet Score)

    +
    + +
    diff --git a/notes/index.html b/notes/index.html index 1435d8a..0c168e6 100644 --- a/notes/index.html +++ b/notes/index.html @@ -24,8 +24,10 @@ href="https://blog.notmyidea.org/lectures/">Lectures - -

    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.

    @@ -139,6 +141,9 @@ changer nos modes de vie et prendre plus de temps les uns pour les autres.<
  • Semences paysannes
  • +
    + +
    diff --git a/notes/index2.html b/notes/index2.html index 1435d8a..0c168e6 100644 --- a/notes/index2.html +++ b/notes/index2.html @@ -24,8 +24,10 @@ href="https://blog.notmyidea.org/lectures/">Lectures
    - -

    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.

    @@ -139,6 +141,9 @@ changer nos modes de vie et prendre plus de temps les uns pour les autres.<
  • Semences paysannes
  • +
    + +
    diff --git a/notes/index3.html b/notes/index3.html index 1435d8a..0c168e6 100644 --- a/notes/index3.html +++ b/notes/index3.html @@ -24,8 +24,10 @@ href="https://blog.notmyidea.org/lectures/">Lectures
    - -

    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.

    @@ -139,6 +141,9 @@ changer nos modes de vie et prendre plus de temps les uns pour les autres.<
  • Semences paysannes
  • +
    + +
    diff --git a/notes/index4.html b/notes/index4.html index 1435d8a..0c168e6 100644 --- a/notes/index4.html +++ b/notes/index4.html @@ -24,8 +24,10 @@ href="https://blog.notmyidea.org/lectures/">Lectures
    - -

    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.

    @@ -139,6 +141,9 @@ changer nos modes de vie et prendre plus de temps les uns pour les autres.<
  • Semences paysannes
  • +
    + +
    diff --git a/notes/index5.html b/notes/index5.html index 1435d8a..0c168e6 100644 --- a/notes/index5.html +++ b/notes/index5.html @@ -24,8 +24,10 @@ href="https://blog.notmyidea.org/lectures/">Lectures
    - -

    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.

    @@ -139,6 +141,9 @@ changer nos modes de vie et prendre plus de temps les uns pour les autres.<
  • Semences paysannes
  • +
    + +
    diff --git a/notre-dame-des-landes.html b/notre-dame-des-landes.html index d9a4ead..a056abd 100644 --- a/notre-dame-des-landes.html +++ b/notre-dame-des-landes.html @@ -48,6 +48,9 @@ décembre 2012:

    aéroport http://www.bastamag.net/article2866.html +
    + +
    diff --git a/open-space-technology.html b/open-space-technology.html index e7e9ee6..3430306 100644 --- a/open-space-technology.html +++ b/open-space-technology.html @@ -26,7 +26,10 @@
    -

    « Open space technology » par Harrison Owen

    +
    + +
    +

    Open space technology
    par Harrison Owen

    A User's guide

    @@ -54,6 +57,9 @@ #organisation, #open-space - Posté dans la catégorie lectures

    +
    + +
    diff --git a/ours.html b/ours.html index 56fb078..364adeb 100644 --- a/ours.html +++ b/ours.html @@ -38,6 +38,9 @@ capacité relationnelle générale.

    De manière plus large, est-ce normal de tolérer des comportements qu’on estime anormaux, voire immoraux ? Quand est-ce que la tolérance laisse place a de l’acceptation de comportements problématiques ?

    Suis-je en train de devenir un ours ?

    +
    + +
    diff --git a/packager-du-python-pour-debian.html b/packager-du-python-pour-debian.html index f74a447..ed0f0d5 100644 --- a/packager-du-python-pour-debian.html +++ b/packager-du-python-pour-debian.html @@ -72,6 +72,9 @@ Deux fichiers sont importants, pour commencer : control et ch
  • Faire une intégration avec systemd pour avoir un service qui se lance automatiquement. Ce qui veut aussi dire créer un utilisateur spécifique pour notre service.
  • +
    + +
    diff --git a/pelican-9-months-later.html b/pelican-9-months-later.html index c171948..4286fc4 100644 --- a/pelican-9-months-later.html +++ b/pelican-9-months-later.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -51,6 +51,9 @@ was a proof that there is a bunch of people that are willing to make better softwares just for the sake of fun.

    Thank you, guys, you’re why I like open source so much.

    +
    + +
    diff --git a/pelican-a-simple-static-blog-generator-in-python.html b/pelican-a-simple-static-blog-generator-in-python.html index fd2c27e..ae1a100 100644 --- a/pelican-a-simple-static-blog-generator-in-python.html +++ b/pelican-a-simple-static-blog-generator-in-python.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -96,6 +96,9 @@ optional arguments:

    Enjoy :)

    +
    + +
    diff --git a/phrases-de-passe-et-bonnes-pratiques.html b/phrases-de-passe-et-bonnes-pratiques.html index 7000338..52b24eb 100644 --- a/phrases-de-passe-et-bonnes-pratiques.html +++ b/phrases-de-passe-et-bonnes-pratiques.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -89,6 +89,9 @@ chiffrée, que je n’ai pas encore résolue. Bref, tout cela me semble bien compliqué pour réussir à l’expliquer à des novices, qui pour certains ne sont même pas sur de l’intérêt de la chose.

    +
    + +
    diff --git a/pourquoi-mozilla.html b/pourquoi-mozilla.html index c67aa87..61853c7 100644 --- a/pourquoi-mozilla.html +++ b/pourquoi-mozilla.html @@ -167,6 +167,9 @@ Mozilla pour l’instant:

  • http://chaussette.readthedocs.org/en/0.3/index.html
  • +
    + +
    diff --git a/prendre-le-temps.html b/prendre-le-temps.html index 1ce7cdd..3ddf264 100644 --- a/prendre-le-temps.html +++ b/prendre-le-temps.html @@ -38,6 +38,9 @@

    Je prends plus de temps pour ressentir ce que je fais, et les effets semblent également se sentir sur ma relation aux autres, et sur le soin que je veux porter à mes relations.

    Ça me donne l’impression d’avoir un contrôle sur le temps qui s’écoule (et ça c’est cool :-)).

    +
    + +
    diff --git a/prendre-soin.html b/prendre-soin.html index c88a412..bc35550 100644 --- a/prendre-soin.html +++ b/prendre-soin.html @@ -37,6 +37,9 @@

    C’est peut-être l’effet des deux semaines de vacances : je me retrouve à prendre plus soin de mes relations aux autres humain⋅e⋅s, à avoir plus d’empathie, et j’ai l’impression de tisser des liens plus forts avec les personnes que je croise.

    C’est agréable :-)

    +
    + +
    diff --git a/prix-libre-et-conscient.html b/prix-libre-et-conscient.html index 2ef1c66..9fdaf82 100644 --- a/prix-libre-et-conscient.html +++ b/prix-libre-et-conscient.html @@ -52,6 +52,9 @@
  • Avoir une jauge qui indique à quel point l’évènement est déficitaire ou excédentaire (particulièrement pour les évènements qui se déroulent sur plusieurs jours), et afficher cette jauge à la fin de l’évènement.
  • +
    + +
    diff --git a/profiling-and-speeding-up-django-and-pytest.html b/profiling-and-speeding-up-django-and-pytest.html index b092bc1..9133840 100644 --- a/profiling-and-speeding-up-django-and-pytest.html +++ b/profiling-and-speeding-up-django-and-pytest.html @@ -79,6 +79,9 @@ HostName
    differ, then you might be in this case. Here is the fix :#django, #pytest - Posté dans la catégorie code

    +
    + +
    diff --git a/pypi-on-couchdb.html b/pypi-on-couchdb.html index 48aa6e4..a62f6a9 100644 --- a/pypi-on-couchdb.html +++ b/pypi-on-couchdb.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -118,6 +118,9 @@ store in couchdb:

    still a work in progress, and everything can break at any time. However, any feedback will be appreciated !

    +
    + +
    diff --git a/python-go.html b/python-go.html index 6c8e2eb..8e71c89 100644 --- a/python-go.html +++ b/python-go.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -126,6 +126,9 @@ python sur mon profil, peut

    Cous pouvez également aller regarder l’atelier donné par Victor Stinner durant le Pyconfr 09. Have fun !

    +
    + +
    diff --git a/python-packaging-with-hatch-pipx-and-zsh-environment-variables.html b/python-packaging-with-hatch-pipx-and-zsh-environment-variables.html index dc23836..5ab10dc 100644 --- a/python-packaging-with-hatch-pipx-and-zsh-environment-variables.html +++ b/python-packaging-with-hatch-pipx-and-zsh-environment-variables.html @@ -60,6 +60,9 @@ can actually use +=, like this:

    #python, #packaging, #zsh - Posté dans la catégorie code

    +
    + +
    diff --git a/quel-metier-quelle-utilite.html b/quel-metier-quelle-utilite.html index ecf92e7..ed2b66a 100644 --- a/quel-metier-quelle-utilite.html +++ b/quel-metier-quelle-utilite.html @@ -122,11 +122,14 @@ de génération de formulaires en ligne, qui ne soit pas centré sur les services de google…

    Allez, au boulot !

    PS: je me rends compte après relecture que ce billet fait echo à un -billet que j’ai écris juste alors que je terminais mes études, sur le +billet que j’ai écris juste alors que je terminais mes études, sur le sens du travail et de l’informatique, ça fait du bien :)

    +
    + +
    diff --git a/quels-usages-pour-linformatique.html b/quels-usages-pour-linformatique.html index 880c68b..c4cfdec 100644 --- a/quels-usages-pour-linformatique.html +++ b/quels-usages-pour-linformatique.html @@ -134,6 +134,9 @@ nous parlent (fermes autogérées, initiatives d’éducation populaire) et&

    Faisons en sorte de rendre l’informatique accessible et utile dans les milieux ou elle peut apporter quelque chose !

    +
    + +
    diff --git a/reconnexion.html b/reconnexion.html index 6d11c03..ea14241 100644 --- a/reconnexion.html +++ b/reconnexion.html @@ -52,6 +52,9 @@ Mais… je me retrouve encore derrière un écran.

    Peut-être que ce qui me gène n’est pas tant l’écran en tant que tel, mais la posture dans laquelle celui-ci me plonge ?

    Plutôt que de chercher à passer très peu de temps derrière un écran, je peux essayer de maximiser le temps ou j’y fais quelque chose qui m’intéresse, et pour lequel je suis dans un usage créatif ?

    +
    + +
    diff --git a/refactoring-cornice.html b/refactoring-cornice.html index 5167e4e..706dd60 100644 --- a/refactoring-cornice.html +++ b/refactoring-cornice.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -217,6 +217,9 @@ the documentation from it.

    it.

    Any suggestions are of course welcome :-)

    +
    + +
    diff --git a/refuser-detre-un-homme.html b/refuser-detre-un-homme.html index 7cd6fab..6243af4 100644 --- a/refuser-detre-un-homme.html +++ b/refuser-detre-un-homme.html @@ -26,7 +26,10 @@
    -

    « Refuser d’être un homme » par John Stolenberg

    +
    + +
    +

    Refuser d’être un homme
    par John Stolenberg

    Pour en finir avec la virilité

    @@ -54,6 +57,9 @@ #féminisme, #masculinisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/remettre-les-choses-a-plus-tard.html b/remettre-les-choses-a-plus-tard.html index 2d0d7cd..26286df 100644 --- a/remettre-les-choses-a-plus-tard.html +++ b/remettre-les-choses-a-plus-tard.html @@ -36,6 +36,9 @@

    Une autre astuce qui me permet de retrouver du temps, c’est de remettre certaines choses à plus tard. Certain⋅ne⋅s diraient que c’est de la procrastination, mais je demande par exemple aux personnes de passer par les canaux qui me permettent de mieux compartimenter les choses.

    Par exemple, si je reçois un SMS qui me demande de faire quelque chose en rapport avec la technologie, je demande à la personne émettrice de m’envoyer un email.

    +
    + +
    diff --git a/rentree.html b/rentree.html index ab2fb21..7daf138 100644 --- a/rentree.html +++ b/rentree.html @@ -60,6 +60,9 @@

    Considérer les relations pour ce qu’elles sont — plutôt que ce qu’elles ne sont pas — me permet de faire baisser considérablement la pression que je crée à leur endroit, et de les laisser s’exprimer de manière plus naturelle.

    Ça me permet également d’être plus naturel, et de faire baisser la pression que je peux parfois me mettre tout seul.

    +
    + +
    diff --git a/retours-sur-deux-ans-a-mozilla.html b/retours-sur-deux-ans-a-mozilla.html index 578c497..778b905 100644 --- a/retours-sur-deux-ans-a-mozilla.html +++ b/retours-sur-deux-ans-a-mozilla.html @@ -43,7 +43,7 @@ restent intacts.

    Deux ans ça parait énorme, c’est le temps le plus long que j’ai passé à travailler sur un projet, avec quasiment les mêmes personnes. Si vous suivez un peu ces carnets, vous savez surement que j’ai beaucoup -travaillé avec Tarek par exemple.

    +travaillé avec Tarek par exemple.

    Ça a été (et c’est toujours) un réel plaisir de bosser avec la personne dont j’avais lu les livres pour apprendre le python, merci !

    Services

    @@ -271,6 +271,9 @@ projet avance et soit utilisé au sein de mozilla.

    qu’il soit plus simple d’expliquer ce que Daybed souhaite faire, mais… c’est une autre histoire.

    +
    + +
    diff --git a/retours-sur-un-atelier-zeronet.html b/retours-sur-un-atelier-zeronet.html index 0553e6a..5a969fd 100644 --- a/retours-sur-un-atelier-zeronet.html +++ b/retours-sur-un-atelier-zeronet.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -137,6 +137,9 @@ un tas de petites ressources (par catégorie par ex.). Les gros médias pourraie mais pour l’instant pas encore implémenté. L’utilisation de la DHT BitTorrent n’est pas une option puisque Tor ne supporte pas UDP.

    +
    + +
    diff --git a/reveil-difficile.html b/reveil-difficile.html index f71a6c6..7864d97 100644 --- a/reveil-difficile.html +++ b/reveil-difficile.html @@ -43,6 +43,9 @@ #Poésie - Posté dans la catégorie journal

    +
    + +
    diff --git a/roles.html b/roles.html index 98aac4b..7c14d42 100644 --- a/roles.html +++ b/roles.html @@ -163,6 +163,9 @@ environnement horizontal, avec une considération partagée de la direction que le groupe souhaite prendre pour qu’un tel dispositif ait du sens.

    +
    + +
    diff --git a/routine.html b/routine.html index 2d175d8..ea78baa 100644 --- a/routine.html +++ b/routine.html @@ -51,6 +51,9 @@

    Il me semble également que les routines permettent d’obtenir une quiétude. Se questionner (une fois), décider, puis faire de manière routinière, sans se poser à nouveau la même question sans cesse.

    Ça vient me questionner à beaucoup d’endroits, de ma gestion quotidienne de mon temps à mon rapport à l’apprentissage. Ça me plait.

    +
    + +
    diff --git a/running-the-gitlab-ci-locally.html b/running-the-gitlab-ci-locally.html index aff4cb1..3fe8a37 100644 --- a/running-the-gitlab-ci-locally.html +++ b/running-the-gitlab-ci-locally.html @@ -171,6 +171,9 @@ PASS test #gitlab, #docker - Posté dans la catégorie code

    +
    + +
    diff --git a/rupture-anarchiste-et-trahison-pro-feministe.html b/rupture-anarchiste-et-trahison-pro-feministe.html index 2ccf6d1..06c0fad 100644 --- a/rupture-anarchiste-et-trahison-pro-feministe.html +++ b/rupture-anarchiste-et-trahison-pro-feministe.html @@ -26,7 +26,10 @@
    -

    « Rupture anarchiste et trahison pro-féministe » par Léo Thiers-Vidal

    +
    + +
    +

    Rupture anarchiste et trahison pro-féministe
    par Léo Thiers-Vidal

    Écrits et échanges de Léo Thiers-Vidal.

    @@ -53,6 +56,9 @@ #féminisme, #anarchisme, #masculinismes - Posté dans la catégorie lectures

    +
    + +
    diff --git a/semaine-de-lenvironnement-la-consommation-etudiante.html b/semaine-de-lenvironnement-la-consommation-etudiante.html index 6daff17..b134250 100644 --- a/semaine-de-lenvironnement-la-consommation-etudiante.html +++ b/semaine-de-lenvironnement-la-consommation-etudiante.html @@ -80,6 +80,9 @@ que vous pouvez compléter en une petite 10aine de minutes, n’hésitez pas ! La page sur la consommation étudiante sur le site du GRAPPE

    +
    + +
    diff --git a/semences-paysannes.html b/semences-paysannes.html index e168d6f..82cec44 100644 --- a/semences-paysannes.html +++ b/semences-paysannes.html @@ -56,6 +56,9 @@ demandée, qu’en est il ?

    Série de vidéos sur la paysannerie: http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86

    +
    + +
    diff --git a/separation-travail-et-loisirs.html b/separation-travail-et-loisirs.html index 545eb8d..67bd2d2 100644 --- a/separation-travail-et-loisirs.html +++ b/separation-travail-et-loisirs.html @@ -71,6 +71,9 @@ Et qué s’apelerio exploitation.

    #Travail, #Facilitation, #Savoir-Être - Posté dans la catégorie journal

    +
    + +
    diff --git a/service-de-nuages-achievement-unlocked-fr.html b/service-de-nuages-achievement-unlocked-fr.html index a95f5de..94dd61f 100644 --- a/service-de-nuages-achievement-unlocked-fr.html +++ b/service-de-nuages-achievement-unlocked-fr.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -96,6 +96,9 @@ est pluggable). +
    + +
    diff --git a/service-de-nuages-fr.html b/service-de-nuages-fr.html index a25ec38..46263f9 100644 --- a/service-de-nuages-fr.html +++ b/service-de-nuages-fr.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -104,6 +104,9 @@ et de vous présenter notre vision via des exemples et tutoriaux.

    +
    + +
    diff --git a/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.html b/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.html index cf96ec3..10aa700 100644 --- a/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.html +++ b/service-de-nuages-garantir-lintegrite-des-donnees-via-des-signatures-fr.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -127,6 +127,9 @@ pourrait ressembler à ceci :

    +
    + +
    diff --git a/service-de-nuages-la-gestion-des-permissions-fr.html b/service-de-nuages-la-gestion-des-permissions-fr.html index a5caf78..72d8c8b 100644 --- a/service-de-nuages-la-gestion-des-permissions-fr.html +++ b/service-de-nuages-la-gestion-des-permissions-fr.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -638,6 +638,9 @@ réflexions, n’hésitez pas à nous interrompre pendant qu’il est en +
    + +
    diff --git a/service-de-nuages-perspectives-pour-lete-fr.html b/service-de-nuages-perspectives-pour-lete-fr.html index 5688b48..e57a22c 100644 --- a/service-de-nuages-perspectives-pour-lete-fr.html +++ b/service-de-nuages-perspectives-pour-lete-fr.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -198,6 +198,9 @@ de données sur le Web :)

    +
    + +
    diff --git a/service-de-nuages-pourquoi-avons-nous-fait-cliquet.html b/service-de-nuages-pourquoi-avons-nous-fait-cliquet.html index 938b2ba..211657a 100644 --- a/service-de-nuages-pourquoi-avons-nous-fait-cliquet.html +++ b/service-de-nuages-pourquoi-avons-nous-fait-cliquet.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -131,7 +131,7 @@ pour des millions d’utilisateurs et des retours d’expérience de l&# de Firefox Sync pour la gestion de la concurrence et de l’«offline-first».

    Il est documenté en détail.

    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.). [2]

    @@ -203,7 +203,7 @@ au fur et à mesure que ses besoins se précisent.

    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.

    Dans les prochaines semaines, nous allons introduire la notion d’«évènements» (ou signaux), qui permettraient aux extensions de s’interfacer beaucoup plus proprement.

    @@ -354,7 +354,7 @@ projets en cascade.
    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 bien envie de refaire du Python.

    @@ -426,6 +426,9 @@ et les mécanismes d’extension fournis permettent de l’implémenter +
    + +
    diff --git a/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html b/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html index f3f6d34..8e692e1 100644 --- a/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html +++ b/service-de-nuages-stocker-et-interroger-les-permissions-avec-kinto-fr.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -316,6 +316,9 @@ records de la collection, ou toutes les collections du bucket.

    +
    + +
    diff --git a/setting-up-a-irc-bouncer-with-znc.html b/setting-up-a-irc-bouncer-with-znc.html index ec2dd9f..f2d71cb 100644 --- a/setting-up-a-irc-bouncer-with-znc.html +++ b/setting-up-a-irc-bouncer-with-znc.html @@ -137,6 +137,9 @@ Version = 1.8.2 #ZNC, #Weechat, #IRC - Posté dans la catégorie code

    +
    + +
    diff --git a/simplifier-les-preuves-didentites.html b/simplifier-les-preuves-didentites.html index 8bde2b5..f55095b 100644 --- a/simplifier-les-preuves-didentites.html +++ b/simplifier-les-preuves-didentites.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -108,6 +108,9 @@ soulève des questions qui méritent qu’on s’y attarde un brin. similaires existent, via le projet LEAP, mais je n’ai pas encore creusé.

    +
    + +
    diff --git a/sprinting-on-distutils2-in-tours.html b/sprinting-on-distutils2-in-tours.html index 5fcb7c1..89f26ee 100644 --- a/sprinting-on-distutils2-in-tours.html +++ b/sprinting-on-distutils2-in-tours.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -108,6 +108,9 @@ distutils2, and to have a bullet list of things to do, but days like this one are opportunities to catch ! We’ll probably do another sprint in a few weeks, stay tuned !

    +
    + +
    diff --git a/status-board.html b/status-board.html index b979aa3..6c23399 100644 --- a/status-board.html +++ b/status-board.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -110,6 +110,9 @@ fois SSL et TLS activés, et

    Finalement, j’ai mon joli status-board qui tourne à merveille sur http://status.lolnet.org :-)

    +
    + +
    diff --git a/tag/administration-systeme.html b/tag/administration-systeme.html index 9c223c4..45fbe6e 100644 --- a/tag/administration-systeme.html +++ b/tag/administration-systeme.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Administration Système tag

    +

    Tag « Administration Système »

    @@ -35,6 +35,9 @@
    +
    + +
    diff --git a/tag/amitie.html b/tag/amitie.html index 0e47864..bcd4386 100644 --- a/tag/amitie.html +++ b/tag/amitie.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #amitié tag

    +

    Tag « amitié »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/anarchisme.html b/tag/anarchisme.html index 3475758..8566a67 100644 --- a/tag/anarchisme.html +++ b/tag/anarchisme.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #anarchisme tag

    +

    Tag « anarchisme »

    @@ -46,6 +46,9 @@
    +
    + +
    diff --git a/tag/arch-linux.html b/tag/arch-linux.html index 083b06f..9c231d8 100644 --- a/tag/arch-linux.html +++ b/tag/arch-linux.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #arch-linux tag

    +

    Tag « arch-linux »

    @@ -38,6 +38,9 @@ longue période je me retrouve avec des soucis de clé qui ne sont plus à jour
    +
    + +
    diff --git a/tag/bash.html b/tag/bash.html index 8e57bf6..7332009 100644 --- a/tag/bash.html +++ b/tag/bash.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #bash tag

    +

    Tag « bash »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/collapsologie.html b/tag/collapsologie.html index 19916ed..6c47214 100644 --- a/tag/collapsologie.html +++ b/tag/collapsologie.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #collapsologie tag

    +

    Tag « collapsologie »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/collectif.html b/tag/collectif.html index d9e8e43..73bc5a0 100644 --- a/tag/collectif.html +++ b/tag/collectif.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #collectif tag

    +

    Tag « collectif »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/conflit.html b/tag/conflit.html index d07c434..9a577bf 100644 --- a/tag/conflit.html +++ b/tag/conflit.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Conflit tag

    +

    Tag « Conflit »

    @@ -40,6 +40,9 @@
    +
    + +
    diff --git a/tag/cooperation.html b/tag/cooperation.html index c525961..28bc203 100644 --- a/tag/cooperation.html +++ b/tag/cooperation.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Coopération tag

    +

    Tag « Coopération »

    @@ -46,6 +46,9 @@
    +
    + +
    diff --git a/tag/covid.html b/tag/covid.html index b21f8a8..460c8df 100644 --- a/tag/covid.html +++ b/tag/covid.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Covid tag

    +

    Tag « Covid »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/developpement-personnel.html b/tag/developpement-personnel.html index 97d99f3..8570d95 100644 --- a/tag/developpement-personnel.html +++ b/tag/developpement-personnel.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #développement-personnel tag

    +

    Tag « développement-personnel »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/django.html b/tag/django.html index 405b81f..e107931 100644 --- a/tag/django.html +++ b/tag/django.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #django tag

    +

    Tag « django »

    @@ -42,6 +42,9 @@ speedup the tests, with some great tooling for pytest that I wasn’t aware&
    +
    + +
    diff --git a/tag/docker.html b/tag/docker.html index 0ad9bbb..6753575 100644 --- a/tag/docker.html +++ b/tag/docker.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #docker tag

    +

    Tag « docker »

    @@ -39,6 +39,9 @@ local which makes it possible …

    +
    + +
    diff --git a/tag/ecologie.html b/tag/ecologie.html index 9f44afb..da05ac9 100644 --- a/tag/ecologie.html +++ b/tag/ecologie.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #écologie tag

    +

    Tag « écologie »

    @@ -40,6 +40,9 @@
    +
    + +
    diff --git a/tag/facilitation.html b/tag/facilitation.html index 78455ac..d5c0201 100644 --- a/tag/facilitation.html +++ b/tag/facilitation.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Facilitation tag

    +

    Tag « Facilitation »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/fatigue.html b/tag/fatigue.html index 8334b18..8431866 100644 --- a/tag/fatigue.html +++ b/tag/fatigue.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Fatigue tag

    +

    Tag « Fatigue »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/feminisme.html b/tag/feminisme.html index e1b812b..f618907 100644 --- a/tag/feminisme.html +++ b/tag/feminisme.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #féminisme tag

    +

    Tag « féminisme »

    @@ -58,6 +58,9 @@
    +
    + +
    diff --git a/tag/feminisme2.html b/tag/feminisme2.html index e1b812b..f618907 100644 --- a/tag/feminisme2.html +++ b/tag/feminisme2.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #féminisme tag

    +

    Tag « féminisme »

    @@ -58,6 +58,9 @@
    +
    + +
    diff --git a/tag/gitlab.html b/tag/gitlab.html index 6a011ad..2231b45 100644 --- a/tag/gitlab.html +++ b/tag/gitlab.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #gitlab tag

    +

    Tag « gitlab »

    @@ -39,6 +39,9 @@ local which makes it possible …

    +
    + +
    diff --git a/tag/irc.html b/tag/irc.html index e7511fa..47bddc2 100644 --- a/tag/irc.html +++ b/tag/irc.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #IRC tag

    +

    Tag « IRC »

    @@ -35,6 +35,9 @@
    +
    + +
    diff --git a/tag/limites.html b/tag/limites.html index 5d816e7..d6afaec 100644 --- a/tag/limites.html +++ b/tag/limites.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Limites tag

    +

    Tag « Limites »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/llm.html b/tag/llm.html index 497a6d5..a991422 100644 --- a/tag/llm.html +++ b/tag/llm.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #llm tag

    +

    Tag « llm »

    @@ -42,6 +42,9 @@
    +
    + +
    diff --git a/tag/masculinisme.html b/tag/masculinisme.html index 2477ed3..f037997 100644 --- a/tag/masculinisme.html +++ b/tag/masculinisme.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #masculinisme tag

    +

    Tag « masculinisme »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/masculinismes.html b/tag/masculinismes.html index f760d98..52b8f73 100644 --- a/tag/masculinismes.html +++ b/tag/masculinismes.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #masculinismes tag

    +

    Tag « masculinismes »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/mediation.html b/tag/mediation.html index c13059b..a23c190 100644 --- a/tag/mediation.html +++ b/tag/mediation.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #médiation tag

    +

    Tag « médiation »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/non-violence.html b/tag/non-violence.html index 0374fe2..2957f6a 100644 --- a/tag/non-violence.html +++ b/tag/non-violence.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #non-violence tag

    +

    Tag « non-violence »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/open-space.html b/tag/open-space.html index d0e0f7c..6446f2e 100644 --- a/tag/open-space.html +++ b/tag/open-space.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #open-space tag

    +

    Tag « open-space »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/organisation.html b/tag/organisation.html index 92f68be..970a275 100644 --- a/tag/organisation.html +++ b/tag/organisation.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #organisation tag

    +

    Tag « organisation »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/packaging.html b/tag/packaging.html index 396acd0..11dd14e 100644 --- a/tag/packaging.html +++ b/tag/packaging.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #packaging tag

    +

    Tag « packaging »

    @@ -40,6 +40,9 @@ discovered hatch

    +
    + +
    diff --git a/tag/poesie.html b/tag/poesie.html index 33527a0..b33888b 100644 --- a/tag/poesie.html +++ b/tag/poesie.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Poésie tag

    +

    Tag « Poésie »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/pytest.html b/tag/pytest.html index 38774b8..4e7cc49 100644 --- a/tag/pytest.html +++ b/tag/pytest.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #pytest tag

    +

    Tag « pytest »

    @@ -42,6 +42,9 @@ speedup the tests, with some great tooling for pytest that I wasn’t aware&
    +
    + +
    diff --git a/tag/python.html b/tag/python.html index 8b65438..8a380d9 100644 --- a/tag/python.html +++ b/tag/python.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #python tag

    +

    Tag « python »

    @@ -46,6 +46,9 @@ discovered hatch

    +
    + +
    diff --git a/tag/racisme.html b/tag/racisme.html index 56b1756..4b611b7 100644 --- a/tag/racisme.html +++ b/tag/racisme.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #racisme tag

    +

    Tag « racisme »

    @@ -41,6 +41,9 @@
    +
    + +
    diff --git a/tag/relations.html b/tag/relations.html index 1f3ac28..f729722 100644 --- a/tag/relations.html +++ b/tag/relations.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #relations tag

    +

    Tag « relations »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/sante.html b/tag/sante.html index cbf03e3..089ce04 100644 --- a/tag/sante.html +++ b/tag/sante.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Santé tag

    +

    Tag « Santé »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/savoir-etre.html b/tag/savoir-etre.html index 84b5125..21e37aa 100644 --- a/tag/savoir-etre.html +++ b/tag/savoir-etre.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Savoir-Être tag

    +

    Tag « Savoir-Être »

    @@ -58,6 +58,9 @@
    +
    + +
    diff --git a/tag/savoir-etre2.html b/tag/savoir-etre2.html index 84b5125..21e37aa 100644 --- a/tag/savoir-etre2.html +++ b/tag/savoir-etre2.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Savoir-Être tag

    +

    Tag « Savoir-Être »

    @@ -58,6 +58,9 @@
    +
    + +
    diff --git a/tag/sexisme.html b/tag/sexisme.html index c005f19..dbd8209 100644 --- a/tag/sexisme.html +++ b/tag/sexisme.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #sexisme tag

    +

    Tag « sexisme »

    @@ -41,6 +41,9 @@
    +
    + +
    diff --git a/tag/sexualite.html b/tag/sexualite.html index 57dd3d6..e3113c8 100644 --- a/tag/sexualite.html +++ b/tag/sexualite.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #sexualité tag

    +

    Tag « sexualité »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/sqlite.html b/tag/sqlite.html index ee78390..8d28428 100644 --- a/tag/sqlite.html +++ b/tag/sqlite.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #sqlite tag

    +

    Tag « sqlite »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/travail.html b/tag/travail.html index 71808b6..0c386af 100644 --- a/tag/travail.html +++ b/tag/travail.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Travail tag

    +

    Tag « Travail »

    @@ -40,6 +40,9 @@
    +
    + +
    diff --git a/tag/vaccination.html b/tag/vaccination.html index 64e64f7..ef9cfb2 100644 --- a/tag/vaccination.html +++ b/tag/vaccination.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Vaccination tag

    +

    Tag « Vaccination »

    @@ -34,6 +34,9 @@
    +
    + +
    diff --git a/tag/voile.html b/tag/voile.html index 758fd5a..5dcd779 100644 --- a/tag/voile.html +++ b/tag/voile.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #voile tag

    +

    Tag « voile »

    @@ -35,6 +35,9 @@
    +
    + +
    diff --git a/tag/weechat.html b/tag/weechat.html index 63c7ba4..9c812b3 100644 --- a/tag/weechat.html +++ b/tag/weechat.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #Weechat tag

    +

    Tag « Weechat »

    @@ -35,6 +35,9 @@
    +
    + +
    diff --git a/tag/znc.html b/tag/znc.html index c1ac430..3eeae31 100644 --- a/tag/znc.html +++ b/tag/znc.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #ZNC tag

    +

    Tag « ZNC »

    @@ -35,6 +35,9 @@
    +
    + +
    diff --git a/tag/zsh.html b/tag/zsh.html index 16a56fd..8a3b477 100644 --- a/tag/zsh.html +++ b/tag/zsh.html @@ -24,7 +24,7 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Posts with #zsh tag

    +

    Tag « zsh »

    @@ -40,6 +40,9 @@ discovered hatch

    +
    + +
    diff --git a/tags.html b/tags.html index 8d316e6..e5c1ef5 100644 --- a/tags.html +++ b/tags.html @@ -24,52 +24,57 @@ href="https://blog.notmyidea.org/lectures/">Lectures +

    Voici une liste de tous les tags utilisés sur ce site :

    +
    + +
    diff --git a/technologie/index.html b/technologie/index.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index10.html b/technologie/index10.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index10.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index11.html b/technologie/index11.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index11.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index12.html b/technologie/index12.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index12.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index13.html b/technologie/index13.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index13.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index14.html b/technologie/index14.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index14.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index15.html b/technologie/index15.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index15.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index16.html b/technologie/index16.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index16.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index17.html b/technologie/index17.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index17.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index18.html b/technologie/index18.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index18.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index2.html b/technologie/index2.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index2.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index3.html b/technologie/index3.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index3.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index4.html b/technologie/index4.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index4.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index5.html b/technologie/index5.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index5.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index6.html b/technologie/index6.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index6.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index7.html b/technologie/index7.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index7.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index8.html b/technologie/index8.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index8.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/technologie/index9.html b/technologie/index9.html deleted file mode 100644 index de497bd..0000000 --- a/technologie/index9.html +++ /dev/null @@ -1,197 +0,0 @@ - - - - - Alexis Métaireau - - - - - - - - - -

    technologie

    -
    - -
    - - -

    Installation de Mosquitto, InfluxDB, Telegraf et Grafana

    -

    Récemment, on a m’a demandé un petit coup de main pour aider à l’installation d’une pile logicielle qui permet de stocker des données temporelles et en faire des graphiques.

    -

    Voici donc quelques notes prises durant l’installation du système, concues pour que des personnes qui n’y …

    -
    - Administration Système
    -
    - - -

    Groupement d’achats & partage d’expérience

    - Quelques retours sur la création et l'organisation d'un groupement d'achat. -
    -
    -
    - - -

    Webnotes

    - Un outil pour prendre et partager des notes lors de ma navigation. -
    -
    -
    - - -

    Comment est-ce que vous générez vos formulaires ?

    - Présentation d'une solution pour gérer vos formulaires en gardant la main sur les données générées -
    -
    -
    - - -

    Avez vous confiance en SSL?

    - Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser. -
    -
    -
    - - -

    Retours sur un atelier ZeroNet

    - Comment contourner la censure grâce à un Web pair-à-pair ? -
    -
    -
    - - -

    Service de nuages : Garantir l’intégrité des données via des signatures

    -

    Comment garantir l’intégrité des données en utilisant les signatures.

    - -
    -
    -
    - - -

    Let’s Encrypt + HAProxy

    - Comment j'ai mis en place des certificats SSL avec Let's Encrypt derrière haproxy. -
    -
    -
    - - -

    Ateliers d’autodéfense numérique

    - J'ai récemment animé des ateliers d'autodéfense numérique. Voici quelques retours et pistes d'améliorations. -
    -
    -
    - - -

    Le mail doit-il mourir ?

    - Le mail est un protocole bien établi qui souffre de nombreux problèmes. Est-ce qu'il ne serait pas temps de préparer la suite ? -
    -
    - -
    - - - - \ No newline at end of file diff --git a/theme/css/main.css b/theme/css/main.css index e8b0de4..eebde4f 100644 --- a/theme/css/main.css +++ b/theme/css/main.css @@ -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; } \ No newline at end of file diff --git a/theme/rss.svg b/theme/rss.svg new file mode 100644 index 0000000..cea21e2 --- /dev/null +++ b/theme/rss.svg @@ -0,0 +1,38 @@ + + diff --git a/thoughts-about-a-form-generation-service-gis-enabled.html b/thoughts-about-a-form-generation-service-gis-enabled.html index 1caf174..a86eac9 100644 --- a/thoughts-about-a-form-generation-service-gis-enabled.html +++ b/thoughts-about-a-form-generation-service-gis-enabled.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -189,6 +189,9 @@ and edit it, that’s what it’s made for!

    Thanks to Arnaud and Fuzzmz for proof-reading and typo fixing.

    +
    + +
    diff --git a/tolerance-empathie-et-limites.html b/tolerance-empathie-et-limites.html index c4687cd..89896df 100644 --- a/tolerance-empathie-et-limites.html +++ b/tolerance-empathie-et-limites.html @@ -63,6 +63,9 @@ Se dire que j’aurais aimé l’entendre s’exprimer sur les retra #Limites, #Savoir-Être - Posté dans la catégorie journal

    +
    + +
    diff --git a/travail-et-creativite.html b/travail-et-creativite.html index 89b2985..56cc680 100644 --- a/travail-et-creativite.html +++ b/travail-et-creativite.html @@ -50,6 +50,9 @@ trouvent leur compte, mais il s’agit nécessairement de projets non pour être plus créatif.

    Soupa'Soups.

    +
    + +
    diff --git a/travail-passion-et-limites.html b/travail-passion-et-limites.html index 560e8e4..ef70fe9 100644 --- a/travail-passion-et-limites.html +++ b/travail-passion-et-limites.html @@ -38,6 +38,9 @@

    J’ai tendance à analyser ça sous l’angle du « travaillisme » : trouver une certaine forme de fierté au fait de travailler beaucoup (voire trop, selon ma conception personnelle)

    Je me rends compte que, de mon côté, je n’ai pas qu’une seule passion, mais plusieurs, et me pose la question de l’incidence de ces multiples passions sur ma volonté de créer un emploi qui me laisse du temps libre pour pouvoir les vivre toutes.

    +
    + +
    diff --git a/travailler-moins-pour-mieux-travailler.html b/travailler-moins-pour-mieux-travailler.html index a2a5de9..30b0493 100644 --- a/travailler-moins-pour-mieux-travailler.html +++ b/travailler-moins-pour-mieux-travailler.html @@ -80,6 +80,9 @@ s’y essayer !

    Peut être que vous pratiquez déjà le travail au 3/4 temps, que vous avez des retours d’expérience à faire : fausse bonne idée ? Vraie bonne idée ?

    +
    + +
    diff --git a/tricot.html b/tricot.html index 2312527..4172615 100644 --- a/tricot.html +++ b/tricot.html @@ -49,6 +49,9 @@ maman chérie™):

    La nana explique plutôt bien et assez lentement. En espérant que ça prenne.

    +
    + +
    diff --git a/un-an.html b/un-an.html index cb33218..5093499 100644 --- a/un-an.html +++ b/un-an.html @@ -88,9 +88,9 @@ L’avantage de ce matériel c’est que c’est la

    -

    Étiquette de Monstrueuse Normalité, une New England IPA

    -

    Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi

    +

    Étiquette de la Sobacha, une lager avec une infusion de sarrasin torréfié

    +

    Étiquette de Monstrueuse Normalité, une New England IPA

    +

    Étiquette de Chaînon Manquant, une Sour Pale Ale avec du Kiwi

    Ouverture au public, évènements et équilibre

    On a pris le parti d’ouvrir le magasin toutes les fins de semaine (le jeudi et vendredi de 17h à 19h) et on est hyper contents de faire visiter la brasserie aux personnes qui passent de temps à autre. Pour nous, ça fait partie des plaisirs du métier. Par contre, on avait clairement sous estimé le temps que ça nous prendrait. On accueille beaucoup et les gens sont curieux. La fabrication de bière reste encore aujourd’hui quelque chose de nouveau pour la plupart, et il faut satisfaire cette curiosité (il faut plus de brasseries !).

    Ce qui se passe en ce moment sur la scène brassicole est génial : beaucoup de nouvelles brasseries proposent des produits exceptionnels, et les évènements se multiplient aux quatre coins de la France. On adore partager, goûter, discuter, mais on ne pensait pas être autant sollicités par des évènements extérieurs, souvent sur des week-end, et parfois loin. On souhaite garder un équilibre entre notre vie personnelle et notre vie professionnelle. Aller aux évènements aussi par plaisir. Être partout est probablement un des maux de notre temps ;-) À force de voir des brasseurs exténués, il y a de quoi se poser des questions sur la pérennité sur le long terme d’un rythme aussi effréné.

    @@ -98,6 +98,9 @@ L’avantage de ce matériel c’est que c’est la Bref…

    …Voilà pour le petit tour d’horizon de cette année écoulée. Plein de super choses dans les mois à venir, on vous donne des nouvelles très bientôt !

    +
    + +
    diff --git a/un-club-des-brasseurs-amateurs-rennais.html b/un-club-des-brasseurs-amateurs-rennais.html index 9aa20fd..6a269f2 100644 --- a/un-club-des-brasseurs-amateurs-rennais.html +++ b/un-club-des-brasseurs-amateurs-rennais.html @@ -46,6 +46,9 @@

    Si tu es dans le coin et que tu souhaite nous rencontrer, n’hésite pas à rejoindre notre groupe de discussion Facebook et notre liste de diffusion mail.

    A bientôt ;)

    +
    + +
    diff --git a/un-coup-de-main-pour-mon-memoire.html b/un-coup-de-main-pour-mon-memoire.html index 9e7c153..84eadd7 100644 --- a/un-coup-de-main-pour-mon-memoire.html +++ b/un-coup-de-main-pour-mon-memoire.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -62,6 +62,9 @@ le plugin en question, et c’est tout!

    2 prochains mois pour ensuite les analyser correctement.

    Merci pour votre aide !

    +
    + +
    diff --git a/un-espace-des-communs-rennais.html b/un-espace-des-communs-rennais.html index f48f3ac..a680d8f 100644 --- a/un-espace-des-communs-rennais.html +++ b/un-espace-des-communs-rennais.html @@ -74,6 +74,9 @@

    Et donc ?

    Et donc c’était bien chouette de prendre un peu le temps de remettre le nez dans la vie libriste Rennaise ! Ravi de voir une dynamique prendre forme, on verra bien ou ça mène :-)

    +
    + +
    diff --git a/un-feminisme-decolonial.html b/un-feminisme-decolonial.html index f8de770..be551df 100644 --- a/un-feminisme-decolonial.html +++ b/un-feminisme-decolonial.html @@ -26,7 +26,10 @@
    -

    « Un féminisme décolonial » par Françoise Vergès

    +
    + +
    +

    Un féminisme décolonial
    par Françoise Vergès

    Un livre qui vient questionner la posture colonialiste dans le féminisme

    @@ -40,6 +43,9 @@ #sexisme, #racisme - Posté dans la catégorie lectures

    +
    + +
    diff --git a/use-restructured-text-rest-to-power-your-presentations.html b/use-restructured-text-rest-to-power-your-presentations.html index b650a97..68cf7a8 100644 --- a/use-restructured-text-rest-to-power-your-presentations.html +++ b/use-restructured-text-rest-to-power-your-presentations.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -67,6 +67,9 @@ and the command line to generate the PDF:

    rst2pdf couchdb.rst -b1 -s ../slides.style
     
    +
    + +
    diff --git a/using-dbpedia-to-get-languages-influences.html b/using-dbpedia-to-get-languages-influences.html index f457b45..517ac4a 100644 --- a/using-dbpedia-to-get-languages-influences.html +++ b/using-dbpedia-to-get-languages-influences.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -80,6 +80,9 @@ resulting graph would probably be way less readable.

    account. Feel free to adapt it for whatever you want if you feel hackish.

    +
    + +
    diff --git a/using-jpype-to-bridge-python-and-java.html b/using-jpype-to-bridge-python-and-java.html index 4c99b53..02202a7 100644 --- a/using-jpype-to-bridge-python-and-java.html +++ b/using-jpype-to-bridge-python-and-java.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -106,6 +106,9 @@ to extract text content from URLs and remove the boilerplate text easily for infuse (my master thesis project), without having to write java code, nice!

    +
    + +
    diff --git a/vaccination-et-risques.html b/vaccination-et-risques.html index e6a517a..611442f 100644 --- a/vaccination-et-risques.html +++ b/vaccination-et-risques.html @@ -207,6 +207,9 @@ #Santé, #Vaccination, #Covid - Posté dans la catégorie journal

    +
    + +
    diff --git a/velo.html b/velo.html index 294b350..dc5ce9b 100644 --- a/velo.html +++ b/velo.html @@ -35,6 +35,9 @@

    Depuis quelques semaines j’ai décidé d’utiliser le vélo pour aller au boulot. Pas forcement tous les jours, mais dès que les conditions le permettent je n’hésite pas.

    C’est un vrai plaisir de se déplacer en deux roues, en quasiment silence. Le trajet mets pas loin de 35mn et passe par un parc sur la fin, c’est un vrai moment de relaxation, et qui me permet de faire une jonction entre ma vie personnelle et le taf à la brasserie.

    +
    + +
    diff --git a/web-distribution-signing.html b/web-distribution-signing.html index 65044a2..3660b4b 100644 --- a/web-distribution-signing.html +++ b/web-distribution-signing.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -130,6 +130,9 @@ about this.

    A bit like User-Agents do for SSL, but for the actual signature of the files being viewed.

    +
    + +
    diff --git a/webnotes.html b/webnotes.html index 43bce82..89fe287 100644 --- a/webnotes.html +++ b/webnotes.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -46,6 +46,9 @@

    C’est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué !

    Mes notes sont disponibles sur notes.notmyidea.org, et voici le lien vers les sources, si ça vous intéresse de regarder comment ça fonctionne !

    +
    + +
    diff --git a/weeknotes/index.html b/weeknotes/index.html index 6fd40c0..2904b52 100644 --- a/weeknotes/index.html +++ b/weeknotes/index.html @@ -24,10 +24,19 @@ href="https://blog.notmyidea.org/lectures/">Lectures -

    Notes hebdo

    +

    Notes hebdo + +

    Chaque semaine, je fais un petit résumé de ce qui s'est passé. Cela m'aide à garder le fil de mes idées et de mes différents projets. Un bon moyen de faire un pause et d'observer la semaine sous un autre angle.

    +
    + + +

    2023, Semaine 39

    + Une semaine mi-statique, mi mobile. Difficile de trouver un rythme de travail qui me convienne. +
    +
    @@ -38,6 +47,9 @@
    +
    + +
    diff --git a/whats-hawk-and-how-to-use-it.html b/whats-hawk-and-how-to-use-it.html index 8059db2..03cedc7 100644 --- a/whats-hawk-and-how-to-use-it.html +++ b/whats-hawk-and-how-to-use-it.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -216,6 +216,9 @@ in case that helps you to integrate with your projects.

    the django rest framework +
    + +
    diff --git a/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html b/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html index 38fa2d6..90342e9 100644 --- a/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html +++ b/working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -186,6 +186,9 @@ its content.

    A sync takes about 20s + the upload time on my machine, which stay acceptable for all of my developments.

    +
    + +
    diff --git a/wrap-up-of-the-distutils2-paris-sprint.html b/wrap-up-of-the-distutils2-paris-sprint.html index a9057a6..e472b6d 100644 --- a/wrap-up-of-the-distutils2-paris-sprint.html +++ b/wrap-up-of-the-distutils2-paris-sprint.html @@ -16,7 +16,7 @@
  • Alexis Métaireau
  • Journal
  • -
  • Code, etc.
  • Notes hebdo
  • @@ -72,6 +72,9 @@ breakfast and bears^Wbeers.

    Again, a big thanks to all the people who gave me money to pay the transport, I really wasn’t expecting such thing to happen :-)

    +
    + +