From c7913636fd8cf971bc11480f72dc9de6dff03db7 Mon Sep 17 00:00:00 2001 From: Travis CI User Date: Tue, 2 Jul 2019 22:54:50 +0000 Subject: [PATCH] Update documentation --- .nojekyll | 0 2012-first-months.html | 192 + CNAME | 1 + a-distutils2-gsoc.html | 177 + afpy-computer-camp-october-20-21.html | 170 + amap-media-paniers-bio-a-5e-fr.html | 179 + ...-summer-of-code-working-on-distutils2.html | 289 + ...context-to-build-up-a-web-recommender.html | 327 + archives.html | 301 + astuces-ssh.html | 177 + ateliers-dautodefense-numerique.html | 269 + author/alexis-metaireau-mathieu-leplatre.html | 112 + author/alexis-metaireau.html | 206 + authors.html | 106 + avez-vous-confiance-en-ssl.html | 316 + bidouille-fr.html | 188 + biere-maison-fr.html | 246 + ...-du-vieux-singe-installation-en-cours.html | 173 + carto-forms-fr.html | 324 + carto-forms.html | 296 + categories.html | 116 + category/beer.html | 113 + category/biere.html | 113 + category/conferences.html | 112 + category/crypto.html | 123 + category/diy.html | 113 + category/journal.html | 113 + category/life.html | 113 + category/misc.html | 112 + category/musique.html | 113 + category/notes.html | 119 + category/pyconfr2015.html | 118 + category/tech.html | 145 + category/thoughts.html | 141 + cheese-code-wrap-up.html | 250 + chiffrement.html | 211 + circus-sprint-at-pyconfr.html | 215 + cloisonnement-des-activites.html | 177 + ...t-ce-que-vous-generez-vos-formulaires.html | 241 + confiance-fr.html | 236 + cross-origin-in-cornice.html | 352 + de-mozilla-a-la-brasserie-du-vieux-singe.html | 170 + des-carnets-desquisse-fr.html | 176 + djangocong-2012-fr.html | 199 + drafts/acceder-a-internet-hors-ligne.html | 214 + drafts/an-attempt-to-handle-mails-better.html | 248 + drafts/australie.html | 187 + drafts/carto-forms-first-steps.html | 309 + drafts/etre-le-meilleur.html | 154 + drafts/fermentation-en-futs.html | 153 + drafts/hype.html | 153 + drafts/le-mail-doit-il-mourir.html | 240 + drafts/loutil-roi.html | 196 + drafts/mozilla-the-sagrada-token-server.html | 222 + drafts/mozillas-weekly-update-1.html | 208 + drafts/selection-musicale.html | 166 + drafts/un-crieur-public-intergalactique.html | 165 + ...y-change-your-gnome-desktop-wallpaper.html | 189 + faire-moins.html | 158 + ...alexis-metaireau-mathieu-leplatre.atom.xml | 154 + .../alexis-metaireau-mathieu-leplatre.rss.xml | 6 + feeds/alexis-metaireau.atom.xml | 6906 ++++++++++++++++ feeds/alexis-metaireau.rss.xml | 455 ++ feeds/all-en.atom.xml | 5854 +++++++++++++ feeds/all-fr.atom.xml | 1387 ++++ feeds/all.atom.xml | 7239 +++++++++++++++++ feeds/beer.atom.xml | 174 + feeds/biere.atom.xml | 49 + feeds/conferences.atom.xml | 27 + feeds/crypto.atom.xml | 809 ++ feeds/diy.atom.xml | 121 + feeds/journal.atom.xml | 13 + feeds/life.atom.xml | 90 + feeds/misc.atom.xml | 43 + feeds/musique.atom.xml | 22 + feeds/notes.atom.xml | 354 + feeds/pyconfr2015.atom.xml | 676 ++ feeds/tech.atom.xml | 2937 +++++++ feeds/thoughts.atom.xml | 1767 ++++ first-week-working-on-distutils2.html | 217 + focusing-on-what-matters.html | 195 + ...or-how-the-social-coding-can-help-you.html | 247 + ...ecole-pour-la-societe-de-linformation.html | 170 + gnome-3-extensions.html | 179 + groovy.html | 153 + groupement-dachats-partage-dexperience.html | 212 + habitat-collectif.html | 159 + ...-to-go-to-the-distutils2-paris-sprint.html | 164 + ...are-you-handling-your-shared-expenses.html | 227 + how-to-install-nginx-php-53-on-freebsd.html | 193 + how-to-reboot-your-bebox-using-the-cli.html | 195 + images/abeilles.jpg | Bin 0 -> 71082 bytes images/carnet.jpg | Bin 0 -> 126253 bytes images/concassage.jpg | Bin 0 -> 106470 bytes images/concasse.jpg | Bin 0 -> 119379 bytes images/cors_flow.png | Bin 0 -> 20718 bytes images/daybed.jpg | Bin 0 -> 134507 bytes images/filtrage.jpg | Bin 0 -> 120392 bytes images/focus.jpg | Bin 0 -> 83682 bytes images/forms.jpg | Bin 0 -> 73913 bytes images/haze.jpg | Bin 0 -> 157247 bytes images/horizon.jpg | Bin 0 -> 105167 bytes images/ihatemoney-fr.png | Bin 0 -> 61513 bytes images/ihatemoney.png | Bin 0 -> 58140 bytes images/illusion.jpg | Bin 0 -> 69573 bytes images/less-is-more.jpg | Bin 0 -> 94105 bytes images/marmite.jpg | Bin 0 -> 49039 bytes images/privacy.jpeg | Bin 0 -> 153381 bytes images/refroidissement.jpg | Bin 0 -> 129668 bytes images/refroidisseur.jpg | Bin 0 -> 46515 bytes images/soupasoups.jpg | Bin 0 -> 146906 bytes images/status_board.png | Bin 0 -> 31205 bytes images/supercuve.jpg | Bin 0 -> 121937 bytes images/unison.png | Bin 0 -> 12100 bytes images/vieuxsinge.jpg | Bin 0 -> 106281 bytes index.html | 206 + introducing-cornice.html | 283 + ...oducing-the-distutils2-index-crawlers.html | 265 + ...aire-contre-le-mythe-de-labondance-fr.html | 167 + language.html | 180 + languages.html | 152 + ...du-trouble-ou-comment-faire-des-neipa.html | 188 + le-revenu-de-base.html | 309 + le-secret-du-bonheur.html | 172 + le-temps-des-graces-courrez-y-fr.html | 206 + les-dangers-du-livre-numerique-fr.html | 157 + les-problemes-de-pgp.html | 206 + lets-encrypt-haproxy.html | 248 + lhorizon.html | 194 + lifestyle-fr.html | 233 + motivation-benevolat-et-participation-fr.html | 211 + neipa-2.html | 226 + neipa-3.html | 230 + new-year-python-meme-2012.html | 209 + ...omie-libidinale-et-economie-politique.html | 174 + notre-dame-des-landes.html | 157 + ours.html | 153 + pages/about.html | 126 + pages/citations.html | 110 + pages/projets.html | 180 + pelican-9-months-later.html | 199 + ...imple-static-blog-generator-in-python.html | 207 + phrases-de-passe-et-bonnes-pratiques.html | 198 + pourquoi-mozilla-fr.html | 286 + pyconfr-2015-assemblee-generale.html | 181 + pyconfr-2015-cliquet.html | 253 + pyconfr-2015-geoalchemy.html | 256 + pyconfr-2015-hospital-des-tests-en-prod.html | 210 + pyconfr-2015-sql-alchemy.html | 191 + pyconfr-2015-table-ronde-diversite.html | 352 + pyconfr-2015-we-dont-need-your-loop.html | 187 + pypi-on-couchdb.html | 239 + python-go-fr.html | 247 + quel-metier-quelle-utilite.html | 235 + refactoring-cornice.html | 320 + rencontres-python-francophones-2015.html | 168 + retours-sur-deux-ans-a-mozilla.html | 400 + retours-sur-un-atelier-zeronet.html | 255 + roles.html | 274 + ...onnement-la-consommation-etudiante-fr.html | 186 + semences-paysannes.html | 155 + simplifier-les-preuves-didentites.html | 208 + sprinting-on-distutils2-in-tours.html | 227 + status-board-fr.html | 248 + tag/bidouille.html | 0 tag/browsers.html | 0 tag/budget-manager.html | 0 tag/cornice.html | 0 tag/dbpedia.html | 0 tag/diy.html | 0 tag/electronique.html | 0 tag/flask.html | 0 tag/focus.html | 0 tag/forms.html | 0 tag/freebsd.html | 0 tag/gis.html | 0 tag/hack.html | 0 tag/java.html | 0 tag/logiciel-libre.html | 0 tag/nice-story.html | 0 tag/note.html | 0 tag/open-source.html | 0 tag/pelican.html | 0 tag/python.html | 0 tag/recommendations.html | 0 tag/refactoring.html | 0 tag/sparql.html | 0 tag/time-management.html | 0 tag/unison.html | 0 tag/users.html | 0 tag/valeurs.html | 0 tags.html | 104 + theme/css/lanyon.css | 577 ++ theme/css/poole.css | 457 ++ theme/css/seigaiha.png | Bin 0 -> 39522 bytes theme/css/styles.css | 107 + theme/css/syntax.css | 65 + theme/img/2015-05-01.jpg | Bin 0 -> 101952 bytes theme/img/profile.png | Bin 0 -> 205569 bytes travail-et-creativite.html | 161 + ...ailler-moins-pour-mieux-travailler-fr.html | 189 + tricot.html | 160 + un-club-des-brasseurs-amateurs-rennais.html | 165 + un-coup-de-main-pour-mon-memoire-fr.html | 172 + un-espace-des-communs-rennais.html | 186 + usages-informatique-fr.html | 243 + ...text-rest-to-power-your-presentations.html | 173 + ...g-dbpedia-to-get-languages-influences.html | 188 + using-jpype-to-bridge-python-and-java.html | 218 + velotaf.html | 146 + web-distribution-signing.html | 249 + webnotes.html | 166 + whats-hawk-and-how-to-use-it.html | 300 + ...sync-your-dev-environment-with-unison.html | 299 + wrap-up-of-the-distutils2-paris-sprint.html | 183 + 215 files changed, 57428 insertions(+) create mode 100644 .nojekyll create mode 100644 2012-first-months.html create mode 100644 CNAME create mode 100644 a-distutils2-gsoc.html create mode 100644 afpy-computer-camp-october-20-21.html create mode 100644 amap-media-paniers-bio-a-5e-fr.html create mode 100644 an-amazing-summer-of-code-working-on-distutils2.html create mode 100644 analyse-users-browsing-context-to-build-up-a-web-recommender.html create mode 100644 archives.html create mode 100644 astuces-ssh.html create mode 100644 ateliers-dautodefense-numerique.html create mode 100644 author/alexis-metaireau-mathieu-leplatre.html create mode 100644 author/alexis-metaireau.html create mode 100644 authors.html create mode 100644 avez-vous-confiance-en-ssl.html create mode 100644 bidouille-fr.html create mode 100644 biere-maison-fr.html create mode 100644 brasserie-du-vieux-singe-installation-en-cours.html create mode 100644 carto-forms-fr.html create mode 100644 carto-forms.html create mode 100644 categories.html create mode 100644 category/beer.html create mode 100644 category/biere.html create mode 100644 category/conferences.html create mode 100644 category/crypto.html create mode 100644 category/diy.html create mode 100644 category/journal.html create mode 100644 category/life.html create mode 100644 category/misc.html create mode 100644 category/musique.html create mode 100644 category/notes.html create mode 100644 category/pyconfr2015.html create mode 100644 category/tech.html create mode 100644 category/thoughts.html create mode 100644 cheese-code-wrap-up.html create mode 100644 chiffrement.html create mode 100644 circus-sprint-at-pyconfr.html create mode 100644 cloisonnement-des-activites.html create mode 100644 comment-est-ce-que-vous-generez-vos-formulaires.html create mode 100644 confiance-fr.html create mode 100644 cross-origin-in-cornice.html create mode 100644 de-mozilla-a-la-brasserie-du-vieux-singe.html create mode 100644 des-carnets-desquisse-fr.html create mode 100644 djangocong-2012-fr.html create mode 100644 drafts/acceder-a-internet-hors-ligne.html create mode 100644 drafts/an-attempt-to-handle-mails-better.html create mode 100644 drafts/australie.html create mode 100644 drafts/carto-forms-first-steps.html create mode 100644 drafts/etre-le-meilleur.html create mode 100644 drafts/fermentation-en-futs.html create mode 100644 drafts/hype.html create mode 100644 drafts/le-mail-doit-il-mourir.html create mode 100644 drafts/loutil-roi.html create mode 100644 drafts/mozilla-the-sagrada-token-server.html create mode 100644 drafts/mozillas-weekly-update-1.html create mode 100644 drafts/selection-musicale.html create mode 100644 drafts/un-crieur-public-intergalactique.html create mode 100644 dynamically-change-your-gnome-desktop-wallpaper.html create mode 100644 faire-moins.html create mode 100644 feeds/alexis-metaireau-mathieu-leplatre.atom.xml create mode 100644 feeds/alexis-metaireau-mathieu-leplatre.rss.xml create mode 100644 feeds/alexis-metaireau.atom.xml create mode 100644 feeds/alexis-metaireau.rss.xml create mode 100644 feeds/all-en.atom.xml create mode 100644 feeds/all-fr.atom.xml create mode 100644 feeds/all.atom.xml create mode 100644 feeds/beer.atom.xml create mode 100644 feeds/biere.atom.xml create mode 100644 feeds/conferences.atom.xml create mode 100644 feeds/crypto.atom.xml create mode 100644 feeds/diy.atom.xml create mode 100644 feeds/journal.atom.xml create mode 100644 feeds/life.atom.xml create mode 100644 feeds/misc.atom.xml create mode 100644 feeds/musique.atom.xml create mode 100644 feeds/notes.atom.xml create mode 100644 feeds/pyconfr2015.atom.xml create mode 100644 feeds/tech.atom.xml create mode 100644 feeds/thoughts.atom.xml create mode 100644 first-week-working-on-distutils2.html create mode 100644 focusing-on-what-matters.html create mode 100644 fork-you-or-how-the-social-coding-can-help-you.html create mode 100644 francois-elie-quelle-ecole-pour-la-societe-de-linformation.html create mode 100644 gnome-3-extensions.html create mode 100644 groovy.html create mode 100644 groupement-dachats-partage-dexperience.html create mode 100644 habitat-collectif.html create mode 100644 help-me-to-go-to-the-distutils2-paris-sprint.html create mode 100644 how-are-you-handling-your-shared-expenses.html create mode 100644 how-to-install-nginx-php-53-on-freebsd.html create mode 100644 how-to-reboot-your-bebox-using-the-cli.html create mode 100644 images/abeilles.jpg create mode 100644 images/carnet.jpg create mode 100644 images/concassage.jpg create mode 100644 images/concasse.jpg create mode 100644 images/cors_flow.png create mode 100644 images/daybed.jpg create mode 100644 images/filtrage.jpg create mode 100644 images/focus.jpg create mode 100644 images/forms.jpg create mode 100644 images/haze.jpg create mode 100644 images/horizon.jpg create mode 100644 images/ihatemoney-fr.png create mode 100644 images/ihatemoney.png create mode 100644 images/illusion.jpg create mode 100644 images/less-is-more.jpg create mode 100644 images/marmite.jpg create mode 100644 images/privacy.jpeg create mode 100644 images/refroidissement.jpg create mode 100644 images/refroidisseur.jpg create mode 100644 images/soupasoups.jpg create mode 100644 images/status_board.png create mode 100644 images/supercuve.jpg create mode 100644 images/unison.png create mode 100644 images/vieuxsinge.jpg create mode 100644 index.html create mode 100644 introducing-cornice.html create mode 100644 introducing-the-distutils2-index-crawlers.html create mode 100644 la-simplicite-volontaire-contre-le-mythe-de-labondance-fr.html create mode 100644 language.html create mode 100644 languages.html create mode 100644 larrivee-du-trouble-ou-comment-faire-des-neipa.html create mode 100644 le-revenu-de-base.html create mode 100644 le-secret-du-bonheur.html create mode 100644 le-temps-des-graces-courrez-y-fr.html create mode 100644 les-dangers-du-livre-numerique-fr.html create mode 100644 les-problemes-de-pgp.html create mode 100644 lets-encrypt-haproxy.html create mode 100644 lhorizon.html create mode 100644 lifestyle-fr.html create mode 100644 motivation-benevolat-et-participation-fr.html create mode 100644 neipa-2.html create mode 100644 neipa-3.html create mode 100644 new-year-python-meme-2012.html create mode 100644 notes-economie-libidinale-et-economie-politique.html create mode 100644 notre-dame-des-landes.html create mode 100644 ours.html create mode 100644 pages/about.html create mode 100644 pages/citations.html create mode 100644 pages/projets.html create mode 100644 pelican-9-months-later.html create mode 100644 pelican-a-simple-static-blog-generator-in-python.html create mode 100644 phrases-de-passe-et-bonnes-pratiques.html create mode 100644 pourquoi-mozilla-fr.html create mode 100644 pyconfr-2015-assemblee-generale.html create mode 100644 pyconfr-2015-cliquet.html create mode 100644 pyconfr-2015-geoalchemy.html create mode 100644 pyconfr-2015-hospital-des-tests-en-prod.html create mode 100644 pyconfr-2015-sql-alchemy.html create mode 100644 pyconfr-2015-table-ronde-diversite.html create mode 100644 pyconfr-2015-we-dont-need-your-loop.html create mode 100644 pypi-on-couchdb.html create mode 100644 python-go-fr.html create mode 100644 quel-metier-quelle-utilite.html create mode 100644 refactoring-cornice.html create mode 100644 rencontres-python-francophones-2015.html create mode 100644 retours-sur-deux-ans-a-mozilla.html create mode 100644 retours-sur-un-atelier-zeronet.html create mode 100644 roles.html create mode 100644 semaine-de-lenvironnement-la-consommation-etudiante-fr.html create mode 100644 semences-paysannes.html create mode 100644 simplifier-les-preuves-didentites.html create mode 100644 sprinting-on-distutils2-in-tours.html create mode 100644 status-board-fr.html create mode 100644 tag/bidouille.html create mode 100644 tag/browsers.html create mode 100644 tag/budget-manager.html create mode 100644 tag/cornice.html create mode 100644 tag/dbpedia.html create mode 100644 tag/diy.html create mode 100644 tag/electronique.html create mode 100644 tag/flask.html create mode 100644 tag/focus.html create mode 100644 tag/forms.html create mode 100644 tag/freebsd.html create mode 100644 tag/gis.html create mode 100644 tag/hack.html create mode 100644 tag/java.html create mode 100644 tag/logiciel-libre.html create mode 100644 tag/nice-story.html create mode 100644 tag/note.html create mode 100644 tag/open-source.html create mode 100644 tag/pelican.html create mode 100644 tag/python.html create mode 100644 tag/recommendations.html create mode 100644 tag/refactoring.html create mode 100644 tag/sparql.html create mode 100644 tag/time-management.html create mode 100644 tag/unison.html create mode 100644 tag/users.html create mode 100644 tag/valeurs.html create mode 100644 tags.html create mode 100644 theme/css/lanyon.css create mode 100644 theme/css/poole.css create mode 100644 theme/css/seigaiha.png create mode 100644 theme/css/styles.css create mode 100644 theme/css/syntax.css create mode 100644 theme/img/2015-05-01.jpg create mode 100644 theme/img/profile.png create mode 100644 travail-et-creativite.html create mode 100644 travailler-moins-pour-mieux-travailler-fr.html create mode 100644 tricot.html create mode 100644 un-club-des-brasseurs-amateurs-rennais.html create mode 100644 un-coup-de-main-pour-mon-memoire-fr.html create mode 100644 un-espace-des-communs-rennais.html create mode 100644 usages-informatique-fr.html create mode 100644 use-restructured-text-rest-to-power-your-presentations.html create mode 100644 using-dbpedia-to-get-languages-influences.html create mode 100644 using-jpype-to-bridge-python-and-java.html create mode 100644 velotaf.html create mode 100644 web-distribution-signing.html create mode 100644 webnotes.html create mode 100644 whats-hawk-and-how-to-use-it.html create mode 100644 working-directly-on-your-server-how-to-backup-and-sync-your-dev-environment-with-unison.html create mode 100644 wrap-up-of-the-distutils2-paris-sprint.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/2012-first-months.html b/2012-first-months.html new file mode 100644 index 0000000..a27c521 --- /dev/null +++ b/2012-first-months.html @@ -0,0 +1,192 @@ + + + + + + + + + 2012, first months - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

2012, first months

+ + + +
+

🌟

+

A lot of changes in these last months. First of all, I've started to +work for Mozilla, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services able to scale out of +the box.

+

Our most visible and known project, so far, is Firefox Sync, which allows to synchronize +browsing data (tabs, passwords, history, etc.) among different instances of +Firefox. We are also building other things, such as a way to get metrics +easily, a web service based queue, etc. Our primary consumers are +people inside Mozilla, and we want to help them having a simple way to create, +deploy and scale their apps. The project is named "sagrada", and you +can find some more information about it on our public wiki

+

All of what we do, we do it in the open. So you can have a look at the +different pieces of code we wrote +and use them / contribute if you want to.

+

I will not dig in to all the details of what I have been doing, but so far, this have been +a pretty amazing experience. Part of this is explainable by the fact that the +team is made of amazing folks, all with a strong experience in different +topics, so I'm learning things™.

+

I am currently practicing a bit my C++ to do crypto related things (I may or +may not talk about this later on this web-logs) and it's great (well, it +remembers me why I love python for so many things, but it makes me think closer +to the metal ;)). I love this job.

+

Second, I moved to Paris. Yes, Paris. Some of you who know me a bit may find +it unexpected, and that's the case. I'm usually not a big fan of big cities and +am a fairly strong defender of having and creating activities in the country side, +to face the rural exodus problem, into other thingS.

+

I didn't changed my opinion about that. However, I don't want to start by +working remote, especially when working with a remote team. Having offices kind +of help me to have a differentiation between my working place and home, which I +find to be important.

+

And, to be honest, I don't like Paris for unknown reasons: I +haven't been there, so it's a big over-generalisation to say that it's not +good for me. The reality is that I have no idea of what Paris is, and if I'll +like it or not.

+

I found a really nice house (yeah, a house!) in Paris and am sharing it with 3 +other persons. We have room, all like good food and… +they are not geeks, which is a big win for me: work is work and home is home.

+

So far, Paris had been really nice. A lot of things are going on in here, and I +kind of like the way it is possible to find alternative related things in here. +I found a CSA, +some people interested by agriculture related problems and I like where things +seems to be going.

+

So, new job, new house, new city, things are going forward and that's great.

+

Oh, and I will try to post some more technical articles soon, +I'm missing them :)

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/CNAME b/CNAME new file mode 100644 index 0000000..d2a6942 --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +blog.notmyidea.org diff --git a/a-distutils2-gsoc.html b/a-distutils2-gsoc.html new file mode 100644 index 0000000..c8cada8 --- /dev/null +++ b/a-distutils2-gsoc.html @@ -0,0 +1,177 @@ + + + + + + + + + A Distutils2 GSoC - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

A Distutils2 GSoC

+ + + +
+

🌟

+

WOW. I've been accepted to be a part of the +Google Summer Of Code +program, and will work on python +distutils2, with +a +lot of +(intersting!) people.

+
+So, it's about building the successor of Distutils2, ie. "the +python package manager". 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 PEP 376.
+

In more details, I'm going to work on the Installer / Uninstaller +features of Distutils2, and on a PyPI XML-RPC client for distutils2. +Here are the already defined tasks:

+
    +
  • Implement Distutils2 APIs described in PEP 376.
  • +
  • Add the uninstall command.
  • +
  • think about a basic installer / uninstaller script. (with deps) +-- similar to pip/easy_install
  • +
  • in a pypi subpackage;
  • +
  • Integrate a module similar to setuptools' package_index'
  • +
  • PyPI XML-RPC client for distutils 2: +http://bugs.python.org/issue8190
  • +
+

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.

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/afpy-computer-camp-october-20-21.html b/afpy-computer-camp-october-20-21.html new file mode 100644 index 0000000..c818c62 --- /dev/null +++ b/afpy-computer-camp-october-20-21.html @@ -0,0 +1,170 @@ + + + + + + + + + Cheese & Code party: October 20-21 - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Cheese & Code party: October 20-21

+ + + +
+

🌟

+

At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.

+

The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing something related with the Afpy Computer +Camps at his house each year, I've been there twice and it really was a nice +experience.

+

At Djangocong 2012, in Montpellier (south of France), Mathieu Leplatre and myself started to work on a model +validation and storage service, named Daybed.

+

I've talked about this project to some persons this week-end (I've even done a +lightning talk about it) +and it gathered some interest from people in the python community, so we +thought about sprinting on this.

+
+

20 and 21 October - A Computer Camp !

+

Add to this a few beers, and the sprint turns magically into a camp. We'll be +sprinting at the end of October (the 20 and 21) near Angers, on daybed.

+

We plan to have great food and wine, so if you feel like it and if you want to +come and work on some python-related things, you're invited!

+

Although, I can host a limited number of persons, so you'll need to contact me +before :), that's alexis at notmyidea dot org.

+

I've setup a wiki page to organize a bit everything (knowing how many people will +come by will allow me to handle things better), please put information there:

+

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

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/amap-media-paniers-bio-a-5e-fr.html b/amap-media-paniers-bio-a-5e-fr.html new file mode 100644 index 0000000..6b4a27f --- /dev/null +++ b/amap-media-paniers-bio-a-5e-fr.html @@ -0,0 +1,179 @@ + + + + + + + + + AMAP + Média = Paniers bio à 5e ?! - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

AMAP + Média = Paniers bio à 5e ?!

+ + + +
+

🌟

+

Le raccourci me semble un peu rapide. Et pourtant, il est emprunté +bien trop souvent. La dernière mes-utilisation que j'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(voir la vidéo), +ou on parles de +l'AMAP étudiante Zest.

+

Malgré tout le temps passé à expliquer que justement, l'AMAP c'est +avant tout, pour nous, une notion de solidarité envers les +agriculteurs, malgré le fait que le message soit plus profond que +simplement aller acheter du bio (ça, c'est possible aussi en +supermarché), malgré le fait qu'il s'agisse en fait d'une remise en +cause plus profonde de la société, les journalistes n'ont choisi de +prendre que les quelques secondes qui leurs convenaient, celles qui +ne faisaient pas tache, celle ou je dis que "l'AMAP permet aux +étudiants de réapprendre à cuisiner, plutôt que de manger des +nouilles et de se faire des plats réchauffés". Bien sur, je l'ai +dit et je le pense d'ailleurs, là n'est pas le problème, mais mon +message n'était pas celui là.

+

Jamais, dans les quelques minutes du reportage, on ne dit ce que +AMAP signifie: Association de Maintien d'une Agriculture +Paysanne. On ne parles même pas des agriculteurs ! C'est +simplement plus facile pour les étudiants de venir récupérer leurs +paniers, puisque les points de distribution sont sur les facs, et +en plus ça ne coute que 5 euros ! ...

+

Alors je crois bon de rappeler que L'AMAP n'est pas seulement un +service, c'est un engagement. Sur 5 mois, un engagement solidaire, +c'est la donnée principale de l'équation, celle sans quoi ça ne +peut fonctionner. Par le biais de cette AMAP, on essaye de montrer +que d'autres agricultures sont possibles, que la solidarité c'est +bien réel, et qu'il est possible de sortir du +tout, tout de suite.

+

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

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/an-amazing-summer-of-code-working-on-distutils2.html b/an-amazing-summer-of-code-working-on-distutils2.html new file mode 100644 index 0000000..4070832 --- /dev/null +++ b/an-amazing-summer-of-code-working-on-distutils2.html @@ -0,0 +1,289 @@ + + + + + + + + + An amazing summer of code working on distutils2 - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

An amazing summer of code working on distutils2

+ + + +
+

🌟

+

The Google Summer of Code I've +spent working on distutils2 +is over. It was a really amazing experience, for many reasons.

+

First of all, we had a very good team, we were 5 students working +on distutils2: Zubin, +Éric, +Josip, +Konrad and me. In addition, +Mouad have worked on the PyPI +testing infrastructure. You could find what each person have done +on +the wiki page of distutils2.

+

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

+

Then, I'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've been introducing myself to +python in the late 2009.

+

I'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've traveled +since I wrote it.

+

This summer was awesome because I've learned about python good +practices, now having some strong +mercurial knowledge, and I've +seen a little how the python community works.

+

Then, I would like to say a big thanks to all the mentors that have +hanged around while needed, on IRC or via mail, and especially my +mentor for this summer, Tarek Ziadé.

+

Thanks a lot for your motivation, your leadership and your +cheerfulness, even with a new-born and a new work!

+
+

Why ?

+

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

+

Now, we have PEPs that describes some format we agreed on (see PEP +345), and we wanted to have a tool on which users can base their +code on, that's distutils2.

+
+
+

My job

+

I had to provide a way to crawl the PyPI indexes in a simple way, +and do some installation / uninstallation scripts.

+

All the work done is available in +my bitbucket repository.

+
+

Crawling the PyPI indexes

+

There are two ways of requesting informations from the indexes: +using the "simple" index, that is a kind of REST index, and using +XML-RPC.

+

I've done the two implementations, and a high level API to query +those twos. Basically, this supports the mirroring infrastructure +defined in PEP 381. So far, the work I've done is gonna be used in +pip (they've basically copy/paste the code, but this will change as +soon as we get something completely stable for distutils2), and +that's a good news, as it was the main reason for what I've done +that.

+

I've tried to have an unified API for the clients, to switch from +one to another implementation easily. I'm already thinking of +adding others crawlers to this stuff, and it was made to be +extensible.

+

If you want to get more informations about the crawlers/PyPI +clients, please refer to the distutils2 documentation, especially +the pages about indexes.

+

You can find the changes I made about this in the +distutils2 source code .

+
+
+

Installation / Uninstallation scripts

+

Next step was to think about an installation script, and an +uninstaller. I've not done the uninstaller part, and it's a smart +part, as it's basically removing some files from the system, so +I'll probably do it in a near future.

+

distutils2 provides a way to +install distributions, and to handle dependencies between releases. +For now, this support is only about the last version of the +METADATA (1.2) (See, the PEP 345), but I'm working on a +compatibility layer for the old metadata, and for the informations +provided via PIP requires.txt, for instance.

+
+
+

Extra work

+

Also, I've done some extra work. this includes:

+
    +
  • working on the PEP 345, and having some discussion about it +(about the names of some fields).
  • +
  • writing a PyPI server mock, useful for tests. you can find more +information about it on the +documentation.
  • +
+
+
+
+

Futures plans

+

As I said, I've enjoyed working on distutils2, and the people I've +met here are really pleasant to work with. So I want 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 usable.

+

I'm not plainly satisfied by the work I've done, so I'll probably +tweak it a bit: the installer part is not yet completely finished, +and I want to add support for a real +REST +index in the future.

+

We'll talk again of this in the next months, probably, but we +definitely need a real +REST +API for PyPI, as the "simple" index +is an ugly hack, in my opinion. I'll work on a serious +proposition about this, maybe involving +CouchDB, as it seems to be a good option +for what we want here.

+
+
+

Issues

+

I've encountered some issues during this summer. The main one is +that'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 emails.

+

I've finally managed to work in an office, so good point for +home/office separation.

+

I'd not planned there will be so a high number of emails to read, +in order to follow what'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 !).

+
+
+

Thanks !

+

A big thanks to Graine Libre and +Makina Corpus, 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're a student, if you're +interested about FOSS, dont hesitate any second, it's a really good +opportunity to work on interesting projects!

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file 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 new file mode 100644 index 0000000..7a70068 --- /dev/null +++ b/analyse-users-browsing-context-to-build-up-a-web-recommender.html @@ -0,0 +1,327 @@ + + + + + + + + + Analyse users' browsing context to build up a web recommender - Carnets Web + + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Analyse users' browsing context to build up a web recommender

+ + + +
+

🌟

+

No, this is not an april's fool ;)

+

Wow, it'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'll be working full time on my dissertation topic.

+

When I learned we'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's the good time to learn.

+

Since a long time, I'm being impressed by the last.fm +recommender system. They're scrobbling the music I listen to since something +like 5 years now and the recommendations they're doing are really nice and +accurate (I discovered a lot of great artists listening to the +"neighbour radio".) (by the way, here is +my lastfm account)

+

So I decided to work on recommender systems, to better understand what is it +about.

+

Recommender systems are usually used to increase the sales of products +(like Amazon.com does) which is not really what I'm looking for (The one who +know me a bit know I'm kind of sick about all this consumerism going on).

+

Actually, the most simple thing I thought of was the web: I'm browsing it quite +every day and each time new content appears. I've stopped to follow my feed +reader because of the +information overload, and reduced drastically the number of people I follow on +twitter.

+

Too much information kills the information.

+

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're probably not interested by the same topics at different +times of the day, or depending on the computer you're using. We can also +probably make good use of the way you browse to create groups into the content +you're browsing (or even use the great firefox4 tab group feature).

+

There is a large part of concerns to have about user's privacy as well.

+

Here is my proposal (copy/pasted from the one I had to do for my master)

+
+

Introduction and rationale

+

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

+

A lot of people share the same interest to various topics, and the quantity of +information is such than it'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 perspective.

+

Machine learning is a branch of Artificial Intelligence (AI) 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 made.

+

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'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 else.

+

Page contents are also interesting to analyse, because that'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 etc.)

+

The goal of this dissertation is to create a recommender system for web links, +including this context information.

+

At the end of the dissertation, different pieces of software will be provided, +from raw data collection from the browser to a recommendation system.

+
+
+

Background Review

+

This dissertation is mainly about data extraction, analysis and recommendation +systems. Two different research area can be isolated: Data preprocessing and +Information filtering.

+

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's +browsers.

+
+

Data preparation and extraction

+

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

+

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, 2004).

+

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, 2010).

+

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 HTML pages so there is a need of tools to recognise them.

+

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 "liked" a resource, and +determine a mark for it, which can be used by information filtering a later +step (T. Segaran, 2007).

+

At this stage, structuring the data is required. Storing this kind of +information in RDBMS 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 querying.

+
+
+

Information filtering

+

To filter the information, three techniques can be used (Balabanovic et +Al, 1997):

+
    +
  • 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's about +establishing a profile for the user and compare new items against it.
  • +
  • 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 to.
  • +
  • the hybrid approach, which appeared recently combine both of the previous +approaches, giving recommendations when items score high regarding user's +profile, or if a similar user already liked it.
  • +
+

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, 2007).

+

References:

+
    +
  • Balabanović, M., & Shoham, Y. (1997). Fab: content-based, collaborative +recommendation. Communications of the ACM, 40(3), 66–72. ACM. +Retrieved March 1, 2011, from http://portal.acm.org/citation.cfm?id=245108.245124&.
  • +
  • Berners-Lee, T., Hendler, J., & Lassila, O. (2001). +The semantic web: Scientific american. Scientific American, 284(5), 34–43. +Retrieved November 21, 2010, from http://www.citeulike.org/group/222/article/1176986.
  • +
  • Castellano, G., Fanelli, A., & Torsello, M. (2007). +LODAP: a LOg DAta Preprocessor for mining Web browsing patterns. Proceedings of the 6th Conference on 6th WSEAS Int. Conf. on Artificial Intelligence, Knowledge Engineering and Data Bases-Volume 6 (p. 12–17). World Scientific and Engineering Academy and Society (WSEAS). Retrieved March 8, 2011, from http://portal.acm.org/citation.cfm?id=1348485.1348488.
  • +
  • Kohlschutter, C., Fankhauser, P., & Nejdl, W. (2010). Boilerplate detection using shallow text features. Proceedings of the third ACM international conference on Web search and data mining (p. 441–450). ACM. Retrieved March 8, 2011, from http://portal.acm.org/citation.cfm?id=1718542.
  • +
  • Myatt, G. J. (2007). Making Sense of Data: A Practical Guide to Exploratory +Data Analysis and Data Mining.
  • +
  • Segaran, T. (2007). Collective Intelligence.
  • +
+
+
+
+

Privacy

+

The first thing that's come to people minds when it comes to process their +browsing data is privacy. People don't want to be stalked. That's perfectly +right, and I don't either.

+

But such a system don't have to deal with people identities. It's completely +possible to process completely anonymous data, and that's probably what I'm +gonna do.

+

By the way, if you have interesting thoughts about that, if you do know +projects that do seems related, fire the comments !

+
+
+

What's the plan ?

+

There is a lot of different things to explore, especially because I'm +a complete novice in that field.

+
    +
  • 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 raw browsing data, and then to transform it and to +store it in the better possible way.
  • +
  • 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 db?
  • +
  • Process the data using well known recommendation algorithms. Compare the +results and criticize their value.
  • +
+

There is plenty of stuff I want to try during this experimentation:

+
    +
  • I want to try using Geshi to visualize the connexion between the links, +and the contexts
  • +
  • Try using graph databases such as Neo4j
  • +
  • Having a deeper look at tools such as scikit.learn (a machine learning +toolkit in python)
  • +
  • Analyse web pages in order to categorize them. Processing their +contents as well, to do some keyword based classification will be done.
  • +
+

Lot of work on its way, yay !

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/archives.html b/archives.html new file mode 100644 index 0000000..91ade92 --- /dev/null +++ b/archives.html @@ -0,0 +1,301 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+

Archives for Carnets Web

+ +
+
03 juillet 2019
+
Ours
+
27 juin 2019
+
velotaf
+
26 juin 2019
+
Un espace des communs Rennais ?
+
27 mai 2018
+
De Mozilla à la Brasserie du Vieux Singe
+
03 mars 2018
+
Groupement d'achats & partage d'expérience
+
25 février 2018
+
Webnotes
+
19 février 2018
+
Faire moins
+
29 décembre 2017
+
NEIPA #3
+
18 décembre 2017
+
NEIPA #2
+
06 novembre 2017
+
Un club des brasseurs amateurs Rennais
+
17 octobre 2017
+
L'arrivée du trouble (ou comment faire des NEIPA ?)
+
26 juin 2017
+
Brasserie du Vieux Singe — Installation en cours.
+
31 mai 2016
+
Comment est-ce que vous générez vos formulaires ?
+
29 mai 2016
+
Cloisonnement des activités ?
+
25 mars 2016
+
Avez vous confiance en SSL?
+
17 mars 2016
+
Focusing on what matters
+
17 mars 2016
+
Retours sur un atelier ZeroNet
+
02 mars 2016
+
L'horizon
+
11 février 2016
+
Let's Encrypt + HAProxy
+
14 janvier 2016
+
Ateliers d'autodéfense numérique
+
02 novembre 2015
+
Rencontres python francophones, 2015
+
18 octobre 2015
+
PyconFR 2015 — Assemblée générale
+
18 octobre 2015
+
PyconFR 2015 — Hospital - des tests en prod
+
18 octobre 2015
+
PyconFR 2015 — We don't need your loop
+
17 octobre 2015
+
PyconFR 2015 — Cliquet
+
17 octobre 2015
+
PyconFR 2015 — Geoalchemy
+
17 octobre 2015
+
PyconFR 2015 — SQL Alchemy
+
17 octobre 2015
+
PyconFR 2015 — Table ronde diversité
+
12 octobre 2015
+
Web distribution signing
+
29 juin 2015
+
Rôles
+
25 mai 2015
+
Les problèmes de PGP
+
21 mai 2015
+
Travail et créativité
+
11 mai 2015
+
Simplifier les preuves d'identités
+
09 mai 2015
+
Phrases de passe et bonnes pratiques
+
08 mai 2015
+
Chiffrement
+
01 mai 2015
+
Language
+
20 novembre 2014
+
Le secret du bonheur
+
31 juillet 2014
+
What's Hawk and how to use it?
+
29 juillet 2014
+
Quel métier, quelle utilité ?
+
29 juillet 2014
+
Retours sur deux ans à Mozilla
+
03 octobre 2013
+
Le revenu de base
+
16 août 2013
+
Des carnets d'esquisse
+
06 juillet 2013
+
Notes: Économie libidinale et économie politique
+
01 juillet 2013
+
New year python meme, 2012
+
14 juin 2013
+
François Elie : Quelle école pour la société de l’information ?
+
02 avril 2013
+
Des profils de confiance partout et pour tout ?
+
02 avril 2013
+
Implementing CORS in Cornice
+
29 décembre 2012
+
Status board
+
28 décembre 2012
+
Habitat collectif
+
28 décembre 2012
+
Languages
+
28 décembre 2012
+
Tricot
+
27 décembre 2012
+
Astuces SSH
+
27 décembre 2012
+
Gnome 3, extensions
+
27 décembre 2012
+
"Groovy"
+
27 décembre 2012
+
Notre dame des landes
+
20 décembre 2012
+
Semences paysannes
+
05 novembre 2012
+
Lifestyle
+
22 octobre 2012
+
Cheese & code - Wrap-up
+
20 septembre 2012
+
Cheese & Code party: October 20-21
+
17 septembre 2012
+
Circus sprint at PyconFR
+
16 juillet 2012
+
Pourquoi Mozilla?
+
14 mai 2012
+
Refactoring Cornice
+
30 avril 2012
+
Bidouille
+
16 avril 2012
+
Djangocong 2012
+
10 avril 2012
+
Bière maison !
+
10 avril 2012
+
Motivation, bénévolat et participation
+
04 février 2012
+
Thoughts about a form generation service, GIS enabled
+
23 janvier 2012
+
Les dangers du livre numérique
+
21 janvier 2012
+
2012, first months
+
06 novembre 2011
+
Using JPype to bridge python and Java
+
15 octobre 2011
+
How are you handling your shared expenses?
+
14 octobre 2011
+
La simplicité volontaire contre le mythe de l'abondance
+
16 août 2011
+
Using dbpedia to get languages influences
+
25 juillet 2011
+
Pelican, 9 months later
+
12 juillet 2011
+
Introducing Cornice
+
25 mai 2011
+
Un coup de main pour mon mémoire!
+
19 mai 2011
+
Travailler moins pour mieux travailler ?
+
01 avril 2011
+
Analyse users' browsing context to build up a web recommender
+
16 mars 2011
+
Working directly on your server? How to backup and sync your dev environment with unison
+
08 février 2011
+
Wrap up of the distutils2 paris' sprint
+
20 janvier 2011
+
PyPI on CouchDB
+
15 janvier 2011
+
Help me to go to the distutils2 paris' sprint
+
12 janvier 2011
+
Quels usages pour l'informatique ?
+
05 novembre 2010
+
Fork you ! or how the social coding can help you
+
21 octobre 2010
+
How to reboot your bebox using the CLI
+
11 octobre 2010
+
Dynamically change your gnome desktop wallpaper
+
10 octobre 2010
+
How to install NGINX + PHP 5.3 on FreeBSD.
+
06 octobre 2010
+
Pelican, a simple static blog generator in python
+
16 août 2010
+
An amazing summer of code working on distutils2
+
06 juillet 2010
+
Introducing the distutils2 index crawlers
+
06 juillet 2010
+
Sprinting on distutils2 in Tours
+
25 juin 2010
+
Use Restructured Text (ReST) to power your presentations
+
04 juin 2010
+
first week working on distutils2
+
01 mai 2010
+
A Distutils2 GSoC
+
28 mars 2010
+
Le temps des grâces, courrez-y !
+
24 février 2010
+
Semaine de l’environnement: La consommation étudiante
+
17 décembre 2009
+
Python ? go !
+
11 novembre 2009
+
AMAP + Média = Paniers bio à 5e ?!
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/astuces-ssh.html b/astuces-ssh.html new file mode 100644 index 0000000..e1d5de3 --- /dev/null +++ b/astuces-ssh.html @@ -0,0 +1,177 @@ + + + + + + + + + Astuces SSH - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Astuces SSH

+ + + +
+

🌟

+
+

Tunelling

+

Parce que je m'en rapelle jamais (tête de linote):

+
+$ ssh -f hote -L local:lolnet.org:destination -N
+
+
+
+

.ssh/config

+

(merci gaston !)

+

La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des "+"

+
+Host *+*
+        ProxyCommand ssh $(echo %h | sed
+'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /')
+PATH=.:\$PATH nc -w1 $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /')
+
+

On peut donc spécifier des "sauts" ssh du style:

+
+ssh root@91.25.25.25+192.168.1.1
+
+

Ensuite on peut essayer de rajouter:

+
+Host <label_pour_mon_serveur_privé>
+    user <monuser(root)>
+    IdentityFile  <chemin vers ma clé ssh pour le serveur publique>
+    hostname ip_serveur_publique+ip_serveur_privé
+
+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/ateliers-dautodefense-numerique.html b/ateliers-dautodefense-numerique.html new file mode 100644 index 0000000..958dceb --- /dev/null +++ b/ateliers-dautodefense-numerique.html @@ -0,0 +1,269 @@ + + + + + + + + + Ateliers d'autodéfense numérique - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

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.

+

🌟

+

Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.

+
+

Je compte donc:

+
    +
  • Organiser des ateliers de sensibilisation aux outils de communication, +envers mes proches;
  • +
  • Utiliser la communication chiffrée le plus souvent possible, au moins +pour rendre le déchiffrement des messages plus longue, "noyer le +poisson".
  • +
+

Chiffrement

+
+

J'ai mis un peu de temps à mettre le pied à l'étrier, mais je ressors +finalement du premier atelier que j'ai co-animé avec geb, auprès d'un public de +journalistes.

+

Pour cette première édition l'idée était à la fois d'aller à la rencontre d'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'autodéfense numérique.

+

L'objectif pour ce premier atelier était de:

+
    +
  1. Échanger autour des besoins et faire ressortir des histoires ou le manque +d'outillage / connaissances à posé problème, dans des situations concrètes;
  2. +
  3. Se rendre compte des "conduites à risque", faire peur aux personnes formées +pour qu'elles se rendent compte de l'état actuel des choses;
  4. +
  5. Proposer des solutions concrètes aux problèmes soulevés, ainsi que le +minimum de connaissance théorique pour les appréhender.
  6. +
+
+

1. Faire ressortir les problèmes

+

Afin de faire ressortir les problèmes, nous avons choisi de constituer des +petits groupes de discussion, afin de faire des "Groupes d'Interview Mutuels", +ou "GIM":

+
+

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é vécu.

+

—«Pour s'écouter», SCOP Le Pavé.

+
+

De ces GIMs nous avons pu ressortir quelques histoires, gravitant autour de:

+
    +
  • La protection des sources (d'information): Comment faire pour aider +quelqu'un à faire "fuiter" des données depuis l'intérieur d'une entreprise ?
  • +
  • Le chiffrement de ses données: Comment éviter de faire "fuiter" des données +importantes lors d'une perquisition de matériel ?
  • +
+
+
+

2. Faire peur

+

Un des premiers objectifs est de faire peur, afin que tout le monde se rende +compte à quel point il est facile d'accéder à certaines données. Grégoire m'avait conseillé quelques petites accroches +qui ont ma foi bien marché:

+

J'ai demandé aux présent.e.s de:

+
    +
  • donner leur mot de passe à voix haute devant les autres: a priori personne ne +le fera;
  • +
  • venir se connecter à leur compte email depuis mon ordinateur. J'ai piégé une +personne, qui est venu pour taper son mot de passe.
  • +
+

Cela à été un bon moyen de parler de l'importance des traces que l'on peut +laisser sur un ordinateur, et de la confiance qu'il faut avoir dans le matériel +que l'on utilise, à fortiori si ce ne sont pas les vôtres.

+

Pour continuer à leur faire peur, après une brève explication de ce qu'est SSL +nous avons montré comment il était facile de scruter le réseau à la recherche +de mots de passe en clair.

+
+
+

3. Proposer des solutions concrêtes

+

Une fois que tout le monde avait pleinement pris sonscience des problématiques +et n'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 attentes:

+
    +
  • On a expliqué ce qu'était Tails, et comment +l'utiliser et le dupliquer.
  • +
  • On a pu faire un tour des outils existants sur Tails, notamment autour de +l'anonymisation de fichiers et la suppression effective de contenus.
  • +
  • Certaines personnes ont pu créer une clé tails avec la persistance de +configurée.
  • +
  • Nous nous sommes connectés au réseau Tor et testé +que nos adresses IP changeaient bien à la demande.
  • +
  • Nous avons utilisé CryptoCat par dessus Tor, afin de +voir comment avoir une conversation confidentielle dans laquelle il est +possible d'échanger des fichiers.
  • +
+
+
+

Retours

+

D'une manière générale, pour une formation de trois heures et demi, je suis +assez content de l'exercice, et de l'ensemble des sujets que nous avons pu +couvrir. Il y a beaucoup de place pour l'amélioration, notamment en amont (j'avais +par exemple oublié d'amener avec moi suffisamment de clés USB pour utiliser +Tails).

+

La plupart des retours qu'on a pu avoir jusqu'à maintenant sont positifs, et il +y a l'envie d'aller plus loin sur l'ensemble de ces sujets.

+
+
+

La suite

+

Il y a beaucoup de sujets que nous n'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'après-midi par +exemple).

+

J'ai choisi volontairement de ne pas aborder le chiffrement des messages via +PGP parce que je pense que la protection que ce média propose n'est pas +suffisante, mais je suis en train de +revenir sur ma décision: il pourrait être utile de présenter l'outil, à minima, +en insistant sur certaines de ses faiblesses.

+

Un compte twitter à été créé recemment autour des crypto-party à Rennes, si +vous êtes interessés, allez jeter un coup d'œil!

+

Je n'ai pas trouvé de ressources disponibles par rapport à des plans de +formation sur le sujet, j'ai donc décidé de publier les nôtres, afin de +co-construire avec d'autres des plans de formation.

+

Ils sont pour l'instant disponibles sur Read The Docs. Tous les retours +sont évidemment les bienvenus !

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/author/alexis-metaireau-mathieu-leplatre.html b/author/alexis-metaireau-mathieu-leplatre.html new file mode 100644 index 0000000..ba4b151 --- /dev/null +++ b/author/alexis-metaireau-mathieu-leplatre.html @@ -0,0 +1,112 @@ + + + + + + + + + Carnets Web - Articles by Alexis Métaireau, Mathieu Leplatre + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Articles by Alexis Métaireau, Mathieu Leplatre

+ + +
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/author/alexis-metaireau.html b/author/alexis-metaireau.html new file mode 100644 index 0000000..2b2f44e --- /dev/null +++ b/author/alexis-metaireau.html @@ -0,0 +1,206 @@ + + + + + + + + + Carnets Web - Articles by Alexis Métaireau + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Articles by Alexis Métaireau

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/authors.html b/authors.html new file mode 100644 index 0000000..842845d --- /dev/null +++ b/authors.html @@ -0,0 +1,106 @@ + + + + + + + + + Carnets Web - Authors + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+

Authors on Carnets Web

+ + +
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/avez-vous-confiance-en-ssl.html b/avez-vous-confiance-en-ssl.html new file mode 100644 index 0000000..e54ef99 --- /dev/null +++ b/avez-vous-confiance-en-ssl.html @@ -0,0 +1,316 @@ + + + + + + + + + Avez vous confiance en SSL? - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Avez vous confiance en SSL?

+ + + +
+

Tour d'horizon du fonctionnement de SSL et des solutions pour le sécuriser.

+

🌟

+

Dans le cadre des ateliers d'autodéfense numérique, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +absolument pas suffisant.

+

Allez hop, c'est parti pour:

+
    +
  • un tour d'horizon du fonctionnement de SSl
  • +
  • quelques moyens contourner cette "protection" en faisant une attaque en pratique
  • +
  • un tour des solutions existantes actuellement et de pourquoi je ne les trouve + pas vraiment satisfaisantes.
  • +
+

Comment fonctionne SSL?

+

Pour expliquer les problèmes de SSL, j'ai d'abord besoin d'expliquer comment +tout ça fonctionne.

+

SSL repose sur l'utilisation de certificats, qui sont générés par des autorités +de certification (Certificate Authority que je nomme CA dans la suite de +l'article).

+

Les certificats SSL permettent deux choses:

+
    +
  • 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 même.
  • +
  • De garantir que le site sur lequel vous vous connectez est bien celui que + vous imaginez.
  • +
+

Le navigateur, lors d'une visite d'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 CA en qui il a confiance.

+

Imaginons maintenant qu'une des CA essaye de savoir ce qui s'échange entre +mon navigateur et le site de ma banque (protégé par SSL). Comment cela se +passerait il ?

+

N'importe quel CA peut donc générer des certificats pour n'importe quel site, +et le navigateur vérifierait, lui, que le certificat a bien été généré par une +CA.

+

Tout cela ne poserait pas de soucis si les CA étaient gérés de manière fiable, +mais il s'agit d'un travail compliqué, et certains CA ont par le passé montré +des faiblesses.

+

Par exemple, DigiNotar (un CA des Pays-Bas) +a été compromise et les attaquant.e.s ont pu générer des certificats SSL +frauduleux, ce qui leur a permis d'attaquer des sites tels que Facebook ou GMail.

+

Vous pouvez retrouver une liste des risques et menaces autour des CA sur le +wiki de CACert.

+

Attaque de l'homme du milieu avec SSL

+

A force de dire que c'était très facile à faire, j'ai eu envie d'essayer +d'espionner des connections protégées par SSL, et effectivement c'est +carrément flippant tellement c'est simple.

+

En l'espace de quelques minutes, il est possible de faire une attaque de +l'homme du milieu en utilisant par exemple un outil nommé mitm-proxy.

+

Pour déchiffrer l'ensemble du trafic SSL, j'ai simplement eu à lancer quelques +commandes et avoir un CA dans lequel le navigateur de la victime a confiance. +Je l'ai ajouté dans le navigateur cible pour simuler que je l'avais déjà +(c'est le cas si un des 1200 CA se fait pirater, ce qui me semble une surface +d'attaque assez large).

+

Je les colle ici si ça vous intéresse:

+
$ sudo aptitude install mitmproxy
+$ mitm-proxy -T --host
+
+ + +

Il faut faire croire à votre victime que vous êtes la passerelle vers +l'extérieur et à la passerelle que vous êtes la victime:

+
arpspoof -i wlan0 -t victime gateway
+arpspoof -i wlan0 -t gateway victime
+
+ + +

Puis dire à notre fausse passerelle de rediriger le trafic des ports 80 et 443 +vers notre proxy:

+
sudo sysctl -w net.ipv4.ip_forward=1
+sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 443 -j REDIRECT --to-port 4443
+sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport 80 -j REDIRECT --to-port 4443
+
+ + +

Et paf, on voit tout ce qui passe entre la machine et le serveur SSL. On peut +d'ailleurs même imaginer faire tourner ces quelques commandes sur un +raspberry pi, pour aller encore plus vite…

+

Key-pinning dans les navigateurs

+

Actuellement, n'importe quel CA peut générer des certificats pour +n'importe quel site, et c'est en grande partie ce qui pose souci. Une des +manières de faire évoluer la situation est d'épingler les certificats de +certains sites directement dans les navigateurs.

+

Cette approche a le mérite de fonctionner très bien pour un petit nombre de +sites critiques (Google, Facebook, etc).

+

HTTP Public Key Pinning (HPKP)

+

HTTP Public Key Pinning +est également une solution de pinning qui permet d'établir une confiance lors +de la première connexion avec le site. C'est ce qu'on appelle du Trust on First +Use ou TOFU.

+

Le navigateur va alors mettre ces informations dans un cache et vérifiera que +les certificats correspondent bien lors des prochaines visites.

+

HPKP est disponible dans Firefox depuis Janvier 2015 et dans Chrome +depuis Octobre 2015.

+

Certificate transparency: des journaux auditables

+

Une autre approche est celle proposée par certificate transparency:

+
+

Certificate Transparency aims to remedy these certificate-based threats by +making the issuance and existence of SSL certificates open to scrutiny by +domain owners, CAs, and domain users.

+

-- Certificate Transparency

+
+

Autrement dit, avec ce système les CA doivent rendre public le fait qu'ils +aient signé de nouveaux certificats intermédiaires. La signature est ajoutée à +un journal sur lequel il n'est possible que d'écrire.

+

Les navigateurs vont alors vérifier que les certificats utilisés sont bien des +certificats qui ont été ajoutés au journal.

+

Ici, toute l'intelligence est dans la vérification de ces journaux, qui +permettent donc de valider/invalider des certificats racines ou intermédiaires.

+

Il me semble donc qu'il serait possible d'ajouter un certificat frauduleux le +temps d'une attaque (et celui ci serait détecté et supprimé ensuite).

+

Certificate-Transparency n'est donc pas une solution contre une écoute +globale mise en place par les gouvernements par exemple.

+

Si vous lisez bien l'anglais, je vous invite à aller lire +cette description du problème et de la solution +que je trouve très bien écrite.

+

DANE + DNSSEC

+
+

The DANE working group has developed a framework for securely +retrieving keying information from the DNS [RFC6698]. This +framework allows secure storing and looking up server public key +information in the DNS. 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 service.

+

-- Dane WG

+
+

Une autre solution est appelée "DANE" et repose par dessus le protocole +DNSSEC.

+

Je connais assez mal DNSSEC donc j'ai passé un peu de temps à lire des +documents. L'impression finale que ça me laisse est que le problème est +exactement le même que pour SSL: 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 confiance.

+
+

Secure DNS (DNSSEC) uses cryptographic digital signatures signed with a +trusted public key certificate to determine the authenticity of data. +-- https://en.wikipedia.org/wiki/DNS_spoofing

+
+

Et aussi:

+
+

It is widely believed[1] that securing the DNS is critically important for +securing the Internet as a whole, but deployment of DNSSEC specifically has +been hampered (As of 22 January 2010) by several difficulties:

+
    +
  • The need to design a backward-compatible standard that can scale to the + size of the Internet
  • +
  • Prevention of "zone enumeration" (see below) where desired
  • +
  • Deployment of DNSSEC implementations across a wide variety of DNS servers + and resolvers (clients)
  • +
  • Disagreement among implementers over who should own the top-level domain + root keys Overcoming the perceived complexity of DNSSEC and DNSSEC + deployment
  • +
+
+

Solutions basées sur la blockchain

+

Une dernière piste semble être l'utilisation de la blockchain pour distribuer +des clés par site.

+

La solution DNSChain me paraissait tout d'abord un bon point de départ mais +la lecture de quelques critiques +et interventions du développeur du projet m'ont fait changer d'avis.

+

Reste encore la piste de Namecoin Control que je n'ai pas encore creusée. +Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la +bienvenue sur ces sujets!

+ L'image d'illustration utilisée est un travail de Tinou Bao proposé sous license CC BY 2.0. Merci ! + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/bidouille-fr.html b/bidouille-fr.html new file mode 100644 index 0000000..40bf093 --- /dev/null +++ b/bidouille-fr.html @@ -0,0 +1,188 @@ + + + + + + + + + Bidouille - Carnets Web + + + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Bidouille

+ + + +
+

🌟

+

Bidouille bidouille bidouille.

+

Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …

+

Et cette bidouille, cette envie de comprendre comment les choses fonctionnent, +et depuis peu cette envie de mettre en pratique ces connaissances dépasse la +bidouille logicielle. J'ai passé une grosse partie de mon week-end à Main +d'Œuvre, où l'association Under Construction faisait se rencontrer le milieu de +l'éducation populaire et le milieu de la bidouille.

+

Forcement, ni une ni deux, je saute dans le bateau en marche et, n'étant ni un +très grand bidouilleur ni un très grand animateur, j'en ressort enrichi de +toutes ces rencontres, de tous ces préjugés qui tombent, et de quelques +découvertes bluffantes, des idées plein la tête.

+

J'avais entendu parler des "rep-raps", des +imprimantes en 3 dimensions capables de produire des pièces en plastique +mais je n'avais jamais eu l'occasion de voir le bousin en vrai. Et +c'est impressionnant. Vraiment. ("Bienvenue dans le 21ème siècle !")

+

Ça laisse énormément à penser autour des questions d'émancipation +technologique, et de non dépendance envers les constructeurs, dans le milieu de +l'électro-ménager, par exemple. "Ah tiens, cette pièce est cassée, je vais +aller utiliser la rep-rap du coin pour me la fabriquer". Et hop, on mets fin à +tout un cycle d'obsolescence programmée…

+

Mais au delà du défi technique et technologique, j'ai pu refaire un petit peu +d'électronique, et découvrir que j'y prends vraiment gout rapidement. Il y a +bien évidemment un coté très ludique (la led s'allume quand on la branche), +mais il y a surtout cette notion de DIY (Do It Yourself) sous jacente: une fois +que je sais comment ça fonctionne, je peux vraiment faire des choses utiles de +mes 10 doigts, réparer des petits objets, bidouiller ceux existants etc.

+

De la récupération de composants on essaye de voir ce qu'on peut faire, on a +terminé par faire un "vibro-bot", un vibreur de téléphone portable monté sur +une tête de brosse à dents, faisant donc avancer cette dernière.

+

C'est pour s'amuser, c'est pas sérieux ! Pour autant, les concepts de +l'électricité sont appris et je me retrouve avec cette envie de comprendre un +peu plus ce monde de l'électronique qui, je m'en rends compte, m'échappe encore +complètement. De l'éducation à la bidouille !

+

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

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/biere-maison-fr.html b/biere-maison-fr.html new file mode 100644 index 0000000..f4c912f --- /dev/null +++ b/biere-maison-fr.html @@ -0,0 +1,246 @@ + + + + + + + + + Bière maison ! - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Bière maison !

+ + + +
+

🌟

+

Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si pire comme on dit !

+

Cette fois-çi, on s'est penché sur la confection d'une IPA (Indian Pale Ale, une +bière un peu plus amère que celle qu'on à l'habitude de trouver en France).

+

Elle est plus amère car elle comporte plus de houblon que les autres, et +(dans notre cas en tout cas) parce qu'on fait la première fermentation en +présence de houblon.

+
+

Comment qu'on fait de la bière ?

+

Machine arrière; n'allons pas trop vite: comment est-ce qu'on fait de la bière, +d'abord ?

+

En fin de compte, les quelques étapes nécessaire à la confection de la bière ne +sont pas bien sorcières; concassage de l'orge maltée, cuisson (libération de +l'amidon dans l'eau), infusion du houblon, refroidissement, première +fermentation, embouteillage et seconde fermentation.

+

L'idée principale est transformer l'amidon d'orge maltée en sucre, pour le +"donner à manger" à des levures. Vous ajoutez un peu de houblon au milieu pour +donner un petit goût amer et le tour est joué. Enfin presque.

+
+
+

Étape par étape

+

Première étape: le concassage. On avait 6kg d'orge maltée à concasser (plus +exactement 6kg de malt pâle 7EDC et 500g de malt cara 50EDC).

+Image de concassage. +

Attention, pas trop fin dis donc ! On ne veut pas de la poudre, on veut +simplement permettre à l'amidon de se dissoudre dans l'eau. Si on concasse le +malt trop fin, on se retrouve avec un dépôt dégeulasse au fond de toutes les +bouteilles (c'est l'expérience qui parle, notre première bière avait plus goût +de céréale que de bière…)

+

Contrairement aux fois précédentes où nous avions utilisé la technique du +marteau et du torchon (oui, comme vous pouvez l'imaginer, c'est assez long et +fastidieux), On a utilisé… un moulin à malt ! Qui nous à permis de concasser les +6kg en 30 minutes (heureusement qu'on était trois pour se relayer sur le +moulin, parce que nos petits muscles fatiguaient assez vite; vous pouvez +envisager de faire ça tout seul si vous êtes un tennisman).

+C'est dur ! +

La seconde étape, l'empatage. Il s'agit de faire chauffer notre orge maltée +à différentes températures. Les fois précédentes, on avait utilisé plusieurs +paliers de température, mais il semble que ça ne soit pas si nécessaire que ça, +selon les informations de l'ami Fred. On à donc tenté de faire chauffer notre +malt directement à 50°C. Une petite erreur sur la route, on à eu peur de la +contamination bactérienne et on à décidé de faire bouillir nos 26L d'eau pour +être sur que les bactéries s'enfuient en courant. Je dis erreur parce que ça +nous à pris pas loin de 3h30, inertie quand tu nous tiens!

+

On se rends compte de la taille de la marmite un peu là:

+Une grosse marmite +

Une fois l'eau à température (54°C), il faut ajouter le malt et le laisser +durant 30mn à cette température, puis augmenter jusqu'à 65°C durant 1h.

+

La troisième étape, c'est le rinçage, l'idée est de récupérer l'amidon qui +s'est dissout dans l'eau et de mettre de côté l'orge maltée (la partie solide). +Pour ça, il faut faire chauffer de l'eau de rinçage. On a utilisé 10L d'eau de +rinçage qu'on a fait chauffer à 78°C, en comptant sur le fait qu'elle perdra de sa +température (20°C à peu près) en étant utilisée. On a filtré deux fois pour +être sûr de ne rien perdre.

+Filtrage filtrage... +

L'étape d'après (la quatrième, vous suivez), c'est le houblonnage. +On va faire infuser notre "solution aqueuse" (wouah, on dirait de la chimie !) +avec du houblon. Il faut porter l'eau à ébullition et laisser faire durant 1h.

+

Dernière étape: le refroidissement. On dirait que c'est tranquilou comme +ça, mais en fait ça ne l'est pas tant que ça: il faut réussir à passer notre +liquide qui était en ébullition à 54°C en un temps acceptable. Pour ça, on +a utilisé un serpentin confectionné main.

+Notre refroidisseur fait main par Fred. +

Ça nous a permis de passer de 100°C à 54°C en… 35 minutes quand même ! (Nous avions essayé les fois précédentes +de gérer ça à coup de baignoire et de glaçons, les temps n'étaient absolument +pas au rendez-vous).

+Décidement pas. +

Je disais dernière étape, mais il ne faut pas oublier de rajouter les +levures, qui elles vont faire tout le travail et transformer tout ça en… alcool +! Dans notre cas, on ajoute aussi dans la cuve de fermentation du houblon +question de donner l'amertume dont on a envie.

+

On à mesuré une densité de 1046, ce qui veut dire 6° d'alcool. La cuve est +maintenant en train de buller tranquillement (les levures produisent du gaz qui +est évacué), et ça doit durer 15 jours approximativement.

+
+
+

Mise en bouteille

+

Une fois ces deux semaines passées, il faut mettre en bouteille. Dans notre cas +nous avons récupéré des bouteilles à bouchon mécanique (vous savez, les +bouteilles de limonades) qu'on à bien rincé et nettoyé.

+

On s'équipe d'un siphon (pensez à prendre un tuyau avec un diamètre assez +important, le notre était petit et c'était assez long) et après avoir ajouté du +sucre dans le mélange (pour réactiver les levures), on remplit les bouteilles +! Il s'agit de la seconde fermentation, celle qui va faire les bulles (la +première fermentation se charge de l'alcool, la seconde des bulles).

+

Et voilà ! Il ne reste plus qu'à mettre les bouteilles de coté durant deux +semaines de plus et… à déguster le moment venu.

+

On a donc pu tester notre bière la semaine dernière et, ma foi, elle est pas +mal du tout. Elle ne mousse pas trop et à un goût un peu amer. Malheureusement +pas assez à mon goût, mais ça viendra. En comparaison à nos précédents essais, +c'est plutôt positif: la première était ratée puisque trop de pression et trop +de dépôt (et donc un fort goût de levures) alors que la seconde (on avait tenté +d'ajouter de la lavande) avait un goût de lavande amère, pour ne pas dire de +savon.

+

Cette dernière bière a un goût de… de bière ! Il nous reste encore à 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 !

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/brasserie-du-vieux-singe-installation-en-cours.html b/brasserie-du-vieux-singe-installation-en-cours.html new file mode 100644 index 0000000..f973d70 --- /dev/null +++ b/brasserie-du-vieux-singe-installation-en-cours.html @@ -0,0 +1,173 @@ + + + + + + + + + Brasserie du Vieux Singe — Installation en cours. - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Brasserie du Vieux Singe — Installation en cours.

+ + + +
+

Retours sur ces quelques mois consacrés à la création de la brasserie du Vieux Singe.

+

🌟

+

Ça fait maintenant quelques mois que j'ai décidé de changer de métier. Choix à la fois difficile et excitant. Une rupture qui laisse place à quelques étoiles dans les yeux. Enfin, je retrouve l'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour être à portée de main.

+

La chose la plus frappante, c'est la vitesse à laquelle passent les journées: j'ai vraiment l'impression d'avoir quitté Mozilla hier. Si les collègues me +manquent, je ne ferais machine arrière pour rien au monde: je trouve finalement ce sens qui me manquait cruellement.

+

Après quelques hésitations au départ, j'ai décidé de mettre de côté mes activités liées à l'informatique: difficile à assumer quand on croise les copin.e.s avec qui on avait l'habitude de discuter énormement de ces sujets, mais ça permet de laisser plus de place pour l'humain. Plus de place pour les «Au fait, comment ça va toi ?» quand j'ai l'occasion de les recroiser, ce qui n'est pas plus désagréable :)

+

Les journées sont donc organisées autour de la brasserie: beaucoup plus de planification que ce que j'imaginais au départ. Peut-être que c'est aussi du au fait que nous soyons tous les deux des ex-informaticiens un peu perfectionnistes sur les bords. On se voit très souvent pour avancer sur des sujets de fond tout comme sur du pratico-pratique. Pour vous donner un ordre d'idée des questionnements: Quelle taille d'entreprise ? Quelles valeurs communes ? Quelles bières ? Quelle image donner ? Quelle place donner au confort ? Comment éviter la compétitivité ? Comment réussir à impacter les producteurs (houblon / malt) de manière positive ? Quels salaires se donner ?

+

Un peu de production quand même (pour les amis) mais on se garde la grosse partie pour le lancement.

+

Apprentissage

+

Je profite de ces quelques mois pour apprendre: autour de la fabrication et de la dégustation de bière bien sûr (encore un milieu en constante évolution !), mais pas que. J'ai maintenant quelques bases de gestion d'entreprise, en comptabilité, en biologie et en chimie. J'ai bien dit quelques bases, mais qu'est-ce que c'est agréable !

+

C'est assez agréable de se remettre dans une posture d'apprenant, et d'avoir le temps pour cet apprentissage.

+

Questionner la posture de «Chef d'entreprise» et son rapport au temps

+

Décider de créer sa boîte, c'est aussi se poser la question de comment organiser son temps: combien de temps travailler ? Quel temps donner aux loisirs ?

+

Je trouve rassurant de voir ces interrogations abordées avant-même le démarrage de l'entreprise. La plupart des personnes qui nous suivent et nous guident partent du postulat qu'il faudra bosser énormement, là ou nous essayons de trouver un modèle qui soit viable dans le temps, notre souhait est de bosser à 80% (4 jours par semaine).

+

Certes, il faut travailler pour que ça tourne, mais il faut aussi s'accorder des temps de respiration pour être d'autant plus efficace quand on bosse. C'est d'autant plus intéressant de prévoir ces aspects lors de la phase de design de l'activité: on organise le temps autrement ! Ceux qui me lisent de temps à autre savent que c'est une constante de mes réflexions, on verra si ça fonctionne dans les faits.

+

Les projets collectifs

+

Un autre point important est la place que le collectif prends dans cette nouvelle expérience. Au départ, quand j'imaginais le projet sur le court-terme, je mettais la composante collective au second plan dans l'immédiat (au delà des intéractions avec Fred, mon associé). L'occasion de travailler à la construction d'un espace collectif s'est présentée, et on y travaille actuellement.

+

C'est à la fois riche (en partage de points de vue, en entre-aide) et à la fois difficile (beaucoup d'heures de réunions, il faut apprendre à communiquer de manière efficace, il faut parfois faire face à des conflits). Dans l'ensemble, je ne regrette pas ce choix même si il est important de ne pas perdre de vue les objectifs de la brasserie dans l'histoire.

+

Et puis la collaboration ne s'arrête pas qu'au collectif d'activité: le milieu brassicole est en mutation, et les valeurs de partage font bel et bien partie du lot de changements. Les rencontre avec les brasseurs du coin de Rennes le montrent bien: l'esprit est plus à l'entraide qu'à la concurrence, au vu de la demande qui est toujours croissante. Tant mieux, on a autre chose à faire qu'à se tirer dans les pâtes ;)

+

Besoin de concret

+

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 ?

+ Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/carto-forms-fr.html b/carto-forms-fr.html new file mode 100644 index 0000000..4cae21f --- /dev/null +++ b/carto-forms-fr.html @@ -0,0 +1,324 @@ + + + + + + + + + Génération de formulaires, geolocalisés ? - Carnets Web + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Génération de formulaires, geolocalisés ?

+ + + +
+

🌟

+

On a un plan. Un "truc de ouf".

+

À plusieurs reprises, des amis m'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 l'information.

+

L'idée fait son bout de chemin, et je commence à penser qu'on peut même avoir +quelque chose de vraiment flexible et utile. J'ai nommé le projet carto-forms +pour l'instant (mais c'est uniquement un nom de code).

+

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 plus?

+

Si vous ne connaissez pas Google forms, il s'agit d'une interface simple +d'utilisation pour générer des formulaires et récupérer des informations depuis +ces derniers.

+

Google forms est un super outil mais à mon avis manque deux choses importantes: +premièrement, il s'agit d'un outil propriétaire (oui, on peut aussi dire +privateur) et il n'est donc pas possible de le hacker un peu pour le faire +devenir ce qu'on souhaite, ni l'installer sur notre propre serveur. +Deuxièmement, il ne sait pas vraiment fonctionner avec des informations +géographiques, et il n'y à pas d'autre moyen de filtrer les informations que +l'utilisation de leur système de feuilles de calcul.

+

Après avoir réfléchi un petit peu à ça, j'ai contacté Mathieu et les anciens +collègues de chez Makina Corpus, puisque les projets libres à base de carto +sont à même de les intéresser.

+

Imaginez le cas suivant:

+
    +
  1. Dans une "mapping party", on choisit un sujet particulier à cartographier et +on design un formulaire (liste des champs (tags) a remplir + description + +le type d'information) ;
  2. +
  3. Sur place, les utilisateurs remplissent les champs du formulaire avec ce +qu'ils voient. Les champs géolocalisés peuvent être remplis automatiquement +avec la géolocalisation du téléphone ;
  4. +
  5. À la fin de la journée, il est possible de voir une carte des contributions, +avec le formulaire choisi ;
  6. +
  7. Un script peut importer les résultats et les publier vers OpenStreetMap.
  8. +
+
+

Quelques cas d'utilisation

+

J'arrive à imaginer différents cas d'utilisation pour cet outil. Le premier est +celui que j'ai approximativement décrit plus haut: la génération de cartes de +manière collaborative, avec des filtres à facettes. Voici un flux d'utilisation +général:

+
    +
  • Un "administrateur" se rend sur le site web et crée un nouveau formulaire +pour l'ensemble des évènements alternatifs. Il crée les champs suivants:

    +
      +
    • Nom: le champ qui contient le nom de l'évènement.
    • +
    • Catégorie: la catégorie de l'évènement (marche, concert, manifestation…). +Il peut s'agir d'un champ à multiples occurrences.
    • +
    • Le lieu de l'évènement. Celui-ci peut être donné soit par une adresse soit +en sélectionnant un point sur une carte.
    • +
    • Date: la date de l'évènement (un "date picker" peut permettre cela +facilement)
    • +
    +

    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, +etc.)

    +
  • +
  • Une fois terminé, le formulaire est généré et une URL permet d'y accéder. +(par exemple http://forms.notmyidea.org/alternatives).

    +
  • +
  • Une API REST permet à d'autres applications d'accéder aux informations et d'en +ajouter / modifier de nouvelles.

    +
  • +
  • Il est maintenant possible de donner l'URL à qui voudra en faire bon usage. +N'importe qui peut ajouter des informations. On peut également imaginer une +manière de modérer les modifications si besoin est.

    +
  • +
  • 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 +API REST, soit via une jolie carte et quelques contrôles bien placés, dans le +navigateur.

    +
  • +
+

Vous avez dû remarquer que le processus de création d'un formulaire est +volontairement très simple. L'idée est que n'importe qui puisse créer des +cartes facilement, en quelques clics. Si une API bien pensée suit, on peut +imaginer faire de la validation coté serveur et même faire des applications +pour téléphone assez simplement.

+

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 +génériques.

+

On imagine pas mal d'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'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'affichage publicitaires, participation citoyenne +(graffitis, nids de poule, voir http://fixmystreet.ca), geocaching, +trajectoires (randonnées, coureurs, cyclistes)…

+

Voici quelques exemples où ce projet pourrait être utile (la liste n'est pas +exhaustive):

+
+

Un backend SIG simple à utiliser

+

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 SIG! +Vous avez besoin de Carto-Forms! Une API simple vous aide à penser vos +modèles et vos formulaires, et cette même API vous permet d'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 gérées.

+

En d'autres termes, vous faites une distinction entre le stockage des +informations et leur affichage.

+

Si vous êtes un développeur django, plomino, drupal etc. vous pouvez développer +un module pour "plugger" vos modèles et votre interface utilisateur avec celle +de Carto-Forms. De cette manière, il est possible d'exposer les formulaires +aux utilisateurs de vos backoffices. De la même manière, il est possible +d'écrire des widgets qui consomment des données et les affichent (en utilisant +par exemple une bibliothèque javascript de webmapping).

+
+
+

Un outil de visualisation

+

Puisque les données peuvent être proposées de manière automatisée en utilisant +l'API, vous pouvez utiliser la page de résultat de Carto-forms comme un outil +de visualisation.

+

Il est possible d'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'impressoin d'être en face +d'un système d'aide à la décision !

+

Évidemment, il est possible de télécharger les données brutes (geojson, xml). +Idéalement, le mieux serait d'obtenir ces données filtrées directement depuis +une API Web, et un lien permet de partager la page avec l'état des filtres et +le niveau de zoom / la localisation de la carte.

+
+
+

Un service générique pour gérer les formulaires

+

Si vous souhaitez générer un fichier de configuration (ou ce que vous voulez, +messages emails, …) vous aurez besoin d'un formulaire et d'un template pour +injecter les données proposées par les utilisateurs et récupérer un résultat.

+

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 "nettoyées" et +"validées".

+

On peut imaginer par exemple l'utilisation d'un système de templates externe +reposant sur carto-forms. Celui-ci "parserait" le contenu des templates et +pourrait le lier aux informations ajoutées par les utilisateurs via un formulaire.

+

Pour ce cas particulier, il n'y a pas besoin d'informations géographiques +(SIG). Il s'agit quasiment du service proposé actuellement par Google forms.

+
+
+
+

Ça n'existe pas déjà tout ça ?

+

Bien sur, il y a Google forms, qui vous permet de faire ce genre de choses, +mais comme je l'ai précisé plus haut, il ne s'agit pas exactement de la même +chose.

+

Nous avons découvert https://webform.com qui permet de créer des formulaires +avec un système de drag'n'drop. J'adorerais reproduire quelque chose de +similaire pour l'interface utilisateur. Par contre ce projet ne gère pas les +appels via API et les informations de géolocalisation …

+

L'idée de http://thoth.io est également assez sympathique: une api très +simple pour stocker et récupérer des données. En plus de ça, carto-forms +proposerait de la validation de données et proposerait un support des points +SIG (point, ligne, polygone).

+

http://mapbox.com fait également un superbe travail autour de la cartographie, +mais ne prends pas en compte le coté auto-génération de formulaires…

+
+
+

On est parti ?!

+

Comme vous avez pu vous en rendre compte, il ne s'agit pas d'un problème +outrageusement complexe. On a pas mal discuté avec Mathieu, à propos de ce +qu'on souhaite faire et du comment. Il se trouve qu'on peut sûrement s'en +sortir avec une solution élégante sans trop de problèmes. Mathieu est habitué à +travailler autour des projets de SIG (ce qui est parfait parce que ce n'est pas +mon cas) et connaît son sujet. Une bonne opportunité d'apprendre!

+

On sera tous les deux à Djangocong le 14 et 15 Avril, et on prévoit une +session de tempête de cerveau 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'hésitez pas!

+

On ne sait pas encore si on utilisera django ou quelque chose d'autre. On a +pensé un peu à CouchDB, son système de couchapps et geocouch, mais rien n'est +encore gravé dans le marbre ! N'hésitez pas à proposer vos solutions ou +suggestions.

+

Voici le document etherpad sur lequel on a travaillé jusqu'à maintenant: +http://framapad.org/carto-forms. N'hésitez pas à l'éditer et à ajouter vos +commentaires, c'est son objectif!

+

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

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/carto-forms.html b/carto-forms.html new file mode 100644 index 0000000..0a6716d --- /dev/null +++ b/carto-forms.html @@ -0,0 +1,296 @@ + + + + + + + + + Thoughts about a form generation service, GIS enabled - Carnets Web + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Thoughts about a form generation service, GIS enabled

+ + + +
+

🌟

+

We have a plan. A "fucking good" one.

+

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't +explicitly ask that but that's the gist of it.

+

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've named it +carto-forms for now, but that's only the "codename".

+

To put it shortly: what if we had a way to build forms, ala Google forms, but +with geographic information in them?

+

If you don't know Google forms, it means having an user-friendly way to build +forms and to use them to gather information from different users.

+

In my opinion, Google forms is missing two important things: first, it's not +open-source, so it's not possible to hack it or even to run it on your own +server. Second, it doesn't really know how to deal with geographic data, and +there is no way to filter the information more than in a spreadsheet.

+

I knew that Mathieu and some folks at Makina Corpus would be interested +in this, so I started a discussion with him on IRC and we refined the details +of the project and its objectives.

+

Imagine the following:

+
    +
  1. 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) ;
  2. +
  3. In situ, users fill the form fields with what they see. Geo fields can be +pre-populated using device geolocation ;
  4. +
  5. At the end of the day, we can see a map with all user contributions seized +through this particular form ;
  6. +
  7. If relevant, a script could eventually import the resulting dataset and +publish/merge with OpenStreetMap.
  8. +
+
+

Some use cases

+

I can see some use cases for this. The first one is a collaborative map, with +facet filtering. Let's draw a potential user flow:

+
    +
  • An "administrator" goes to the website and creates a form to list all the +alternative-related events. He creates the following fields:

    +
      +
    • Name: a plain text field containing the name of the event.
    • +
    • Category: the category of the event. Can be a finite list.
    • +
    • Location: The location of the event. It could be provided by selecting a +point on a map or by typing an address.
    • +
    • Date: the date of the event (a datepicker could do the trick)
    • +
    +

    Each field in the form has semantic information associated with it (yes/no, +multiple selection, date-time, geocoding carto, carto selection etc)

    +
  • +
  • Once finished, the form is generated and the user gets an url (say +http://forms.notmyidea.org/alternatives) for it.

    +
  • +
  • REST APIs allow third parties to get the form description and to +push/edit/get information from there.

    +
  • +
  • He can communicate the address in any way he wants to his community so they +can go to the page and add information to it.

    +
  • +
  • Then, it is possible to filter the results per location / date or category. +This can be done via API calls (useful for third parties) or via a nice +interface in the browser.

    +
  • +
+

So, as you may have noticed, this would allow us to create interactive maps really +easily. It's almost just a matter of some clicks to the users. If we also come +up with a nice Web API for this, we could do server-side validation and build +even phone applications easily.

+

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

+

As mentioned before, the idea of a simple tool to support collaborative mapping +fullfils a recurring necessity !

+

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'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 http://fixmystreet.ca), +geocaching, trajectories (e.g hiking, runners, cyclists)...

+

Here are some other examples of where carto-forms could be useful:

+
+

Simple GIS storage backend

+

Let's say you are a mobile developer, you don't want to bother with PostGIS +nor write a custom and insecure code to insert and retrieve your GIS data! You +need carto-forms! A simple API helps you design your models/forms and the +same API allows you to CRUD and query your data. Thus, you only need to focus +on your application, not on how GIS data will be handled.

+

We make a distinction between storage and widgets.

+

Besides, if you are a django / drupal / plomino... maintainer : you +can develop a module to "plug" your models (content types) and UI to carto-forms! +Carto forms are then exposed to your backoffice users (ex: drupal admin UI, django +adminsite), and likewise you can write your own HTML widgets that consume datasets +in frontend views (facets in JSON/XML, and map data in GeoJSON).

+
+
+

Visualization tool

+

Since data submission can be done programmatically using the API, you could use Carto-forms +results page as a visualization tool.

+

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're in +front of a decision support system!

+

Of course, filtered raw data can be downloaded (GeoJSON, XML) and a permalink allows to +share the page with the state of the filters and the zoom/location of the map.

+
+
+

Generic forms service

+

If you want to generate a configuration file (or whatever, email messages, ...), +you will need a form and a template to inlay user submitted values and get the result.

+

A form service would be really useful to create forms programmatically and retrieve +cleaned and validated input values.

+

You could run a dedicated template service based on carto-forms! Parsing a template +content, this external service could create a form dynamically and bind them together. +The output of the form service (fields => values) would be bound to the input of a template +engine (variables => final result).

+

Note that for this use-case, there is no specific need of GIS data nor storage of records +for further retrieval.

+
+
+
+

What's out in the wild already?

+

Of course, there is Google forms, which allows you to do these kind of things, +but it's closed and not exactly what we are describing here.

+

We've discovered the interesting https://webform.com/ 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't handle APIs and +geolocation information.

+

The idea of http://thoth.io is very attractive : an extremely simple web API to store +and retrieve data. In addition, carto-forms would do datatype validation and have +basic GIS fields (point, line, polygon).

+

http://mapbox.com also did an awesome work on cartography, but didn't take into +account the form aspect we're leveraging here.

+
+
+

So… Let's get it real!

+

As you may have understood, this isn't a really complicated problem. We have +been sometimes chatting about that with Mathieu about what we would need and +how we could achieve this.

+

We can probably come with an elegant solution without too much pain. Mathieu is +used to work with GIS systems (which is really cool because I'm not at all) and +knows his subject, so that's an opportunity to learn ;-)

+

We will be at Djangocong 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 join!

+

We don'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 welcome!

+

Here is the etherpad document we worked on so far: +http://framapad.org/carto-forms. Don't hesitate to add your thoughts and edit +it, that's what it's made for!

+

Thanks to Arnaud and Fuzzmz for proof-reading and typo fixing.

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/categories.html b/categories.html new file mode 100644 index 0000000..d19e254 --- /dev/null +++ b/categories.html @@ -0,0 +1,116 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/beer.html b/category/beer.html new file mode 100644 index 0000000..f084d19 --- /dev/null +++ b/category/beer.html @@ -0,0 +1,113 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

beer category

+ +
+
    +
  • NEIPA #3New England IPA - Collab avec Heiko.
  • +
  • NEIPA #2Petit test de New England IPA.
  • +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/biere.html b/category/biere.html new file mode 100644 index 0000000..5a8bfe0 --- /dev/null +++ b/category/biere.html @@ -0,0 +1,113 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

biere category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/conferences.html b/category/conferences.html new file mode 100644 index 0000000..640f74c --- /dev/null +++ b/category/conferences.html @@ -0,0 +1,112 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

conferences category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/crypto.html b/category/crypto.html new file mode 100644 index 0000000..50076eb --- /dev/null +++ b/category/crypto.html @@ -0,0 +1,123 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

crypto category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/diy.html b/category/diy.html new file mode 100644 index 0000000..c623009 --- /dev/null +++ b/category/diy.html @@ -0,0 +1,113 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

diy category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/journal.html b/category/journal.html new file mode 100644 index 0000000..bc497fa --- /dev/null +++ b/category/journal.html @@ -0,0 +1,113 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

journal category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/life.html b/category/life.html new file mode 100644 index 0000000..43db56a --- /dev/null +++ b/category/life.html @@ -0,0 +1,113 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

life category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/misc.html b/category/misc.html new file mode 100644 index 0000000..f1b7129 --- /dev/null +++ b/category/misc.html @@ -0,0 +1,112 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

misc category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/musique.html b/category/musique.html new file mode 100644 index 0000000..e2c9261 --- /dev/null +++ b/category/musique.html @@ -0,0 +1,113 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

musique category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/notes.html b/category/notes.html new file mode 100644 index 0000000..1530945 --- /dev/null +++ b/category/notes.html @@ -0,0 +1,119 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

notes category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/pyconfr2015.html b/category/pyconfr2015.html new file mode 100644 index 0000000..521f902 --- /dev/null +++ b/category/pyconfr2015.html @@ -0,0 +1,118 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

pyconfr2015 category

+ + +
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/tech.html b/category/tech.html new file mode 100644 index 0000000..55747e9 --- /dev/null +++ b/category/tech.html @@ -0,0 +1,145 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

tech category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/category/thoughts.html b/category/thoughts.html new file mode 100644 index 0000000..0c962c3 --- /dev/null +++ b/category/thoughts.html @@ -0,0 +1,141 @@ + + + + + + + + + Carnets Web + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

thoughts category

+ +
+ +
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/cheese-code-wrap-up.html b/cheese-code-wrap-up.html new file mode 100644 index 0000000..5525c91 --- /dev/null +++ b/cheese-code-wrap-up.html @@ -0,0 +1,250 @@ + + + + + + + + + Cheese & code - Wrap-up - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Cheese & code - Wrap-up

+ + + +
+

🌟

+

This week-end I hosted a cheese & code session in the country-side of Angers, +France.

+

We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. Bad.

+

We were not enough to get rid of all the cheese and the awesome meals, but +well, we finally managed it pretty well.

+

Here is a summary of what we worked on:

+
+

Daybed

+

Daybed started some time ago, and intend to be a replacement to google forms, +in term of features, but backed as a REST web service, in python, and open +source.

+

In case you wonder, daybed is effectively the name of a couch. We chose this +name because of the similarities (in the sound) with db, and because +we're using CouchDB as a backend.

+Daybed is a big couch! +

We mainly hacked on daybed and are pretty close to the release of the first +version, meaning that we have something working.

+

The code is available on github, +and we also wrote a small documentation for it.

+

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'm pretty confidend that we now have really good basis for this project.

+

Also, we will have a nice todolist application, with the backend and the +frontend, in javascript / html / css, you'll know more when it'll be ready :-)

+

Once we have something good enough, we'll release the first version and I'll +host it somewhere so that people can play with it.

+
+
+

Cornice

+

Daybed is built on top of Cornice, a framework to +ease the creation of web-services.

+

At Pycon France, we had the opportunity to attend a good presentation about SPORE. SPORE is a way to describe your +REST web services, as WSDL is for WS-* services. This allows to ease the +creation of generic SPORE clients, which are able to consume any REST API with +a SPORE endpoint.

+

Here is how you can let cornice describe your web service for you

+
from cornice.ext.spore import generate_spore_description
+from cornice.service import Service, get_services
+
+spore = Service('spore', path='/spore', renderer='jsonp')
+@spore.get
+def get_spore(request):
+    services = get_services()
+    return generate_spore_description(services, 'Service name',
+                                      request.application_url, '1.0')
+
+

And you'll get a definition of your service, in SPORE, available at /spore.

+

Of course, you can use it to do other things, like generating the file locally +and exporting it wherever it makes sense to you, etc.

+

I released today Cornice 0.11, which adds +into other things the support for SPORE, plus some other fixes we found on our +way.

+
+
+

Respire

+

Once you have the description of the service, you can do generic clients +consuming them!

+

We first wanted to contribute to spyre but +it was written in a way that wasn't supporting to POST data, and they +were using their own stack to handle HTTP. A lot of code that already exists in +other libraries.

+

While waiting the train with Rémy, we hacked +something together, named "Respire", a thin layer on top of the awesome +Requests library.

+

We have a first version, feel free to have a look at it and provide +enhancements if you feel like it. We're still hacking on it so it may break +(for the better), but that had been working pretty well for us so far.

+

You can find the project on github, but here is how to use it, really +quickly (these examples are how to interact with daybed)

+
>>> from respire import client_from_url
+
+>>> # create the client from the SPORE definition
+>>> cl = client_from_url('http://localhost:8000/spore')
+
+>>> # in daybed, create a new definition
+>>> todo_def = {
+...    "title": "todo",
+...    "description": "A list of my stuff to do",
+...    "fields": [
+...        {
+...            "name": "item",
+...            "type": "string",
+...            "description": "The item"
+...        },
+...        {
+...            "name": "status",
+...            "type": "enum",
+...            "choices": [
+...                "done",
+...                "todo"
+...            ],
+...            "description": "is it done or not"
+...        }
+...    ]}
+>>> cl.put_definition(model_name='todo', data=todo_def)
+>>> cl.post_data(model_name='todo', data=dict(item='make it work', status='todo'))
+{u'id': u'9f2c90c0529a442cfdc03c191b022cf7'}
+>>> cl.get_data(model_name='todo')
+
+

Finally, we were out of cheese so everyone headed back to their respective +houses and cities.

+

Until next time?

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/chiffrement.html b/chiffrement.html new file mode 100644 index 0000000..a5f7388 --- /dev/null +++ b/chiffrement.html @@ -0,0 +1,211 @@ + + + + + + + + + Chiffrement - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Chiffrement

+ + + +
+

Face a la surveillance généralisée, une seule solution, le +chiffrement de nos données et communications.

+

🌟

+
+

En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.

+

le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :

+
    +
  • Élargissement des finalités du renseignement, permettant une potentielle +mise sous surveillance de pans entiers de la vie politique, syndicale, +militante, mais aussi économique, scientifique, etc. ;
  • +
  • Légalisation massive de pratiques illégales des services de +renseignement et introduction de techniques de surveillance de masse +des communications électroniques ;
  • +
  • Absence de contrôle réel et indépendant a priori par la future +CNCTR, et recours des citoyens illusoires ;
  • +
+

La Quadrature du Net - L'Assemblée nationale vote la surveillance de +masse des citoyens français !

+
+

Je m'étonne que les révélations d'Edward Snowden — qui +ont démontré que la plupart des communications électroniques et téléphoniques +pouvaient être scrutés par la NSA, l'agence de sécurité Américaine) — ne +fassent pas plus de remous que ça.

+

À peine deux années après ces révélations, la France fait passer une loi qui +légitime cette surveillance de masse, à plus de 77% des voies. Pour moi c'est +un signal fort de la perte de valeurs de notre démocratie, et à fortiori de ma +perte de foi en notre forme de démocratie.

+

Notre liberté d'expression se voit bien évidemment amputée de par la +surveillance généralisée. Sans avoir nécessairement à cacher mes échanges, ce +qui est de la sphère privée devrait pouvoir le rester.

+

De toute manière, l'email comme on l'utilise traditionnellement est une +hérésie: toutes les parties qui traitent le message peuvent le lire, +(destinataire, auteur et corps du message entre autres). Il est grand temps de +rendre les outils de chiffrement plus simples et ergonomiques.

+

Je compte donc:

+
    +
  • Organiser des ateliers de sensibilisation aux outils de communication, envers +mes proches;
  • +
  • Utiliser la communication chiffrée le plus souvent possible, au moins pour +rendre le déchiffrement des messages plus longue, "noyer le poisson".
  • +
+

Si vous êtes intéressé(e)s, faites moi signe, je me ferais un plaisir de vous +expliquer ce qui n'est pas si complexe et vise à laisser dans la sphère privée +ce qui devrait l'être à priori.

+

Une manière simple de se protéger est d'installer Thunderbird avec 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 autour (Electronic +Fronteer Fondation, Tails, La quadrature +du net en france ou d'autres…)

+ + + + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/circus-sprint-at-pyconfr.html b/circus-sprint-at-pyconfr.html new file mode 100644 index 0000000..baef801 --- /dev/null +++ b/circus-sprint-at-pyconfr.html @@ -0,0 +1,215 @@ + + + + + + + + + Circus sprint at PyconFR - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Circus sprint at PyconFR

+ + + +
+

🌟

+

Last Thursday to Sunday, Pycon France took place, in +Paris. It was the opportunity to meet a lot of people and to talk about python +awesomness in general.

+

We had three tracks this year, plus sprints the two first days. We sprinted on +Circus, the process and socket manager we're using +at Mozilla for some of our setups.

+

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

+

Having people wanting to sprint on our projects is exciting because that's +when making things in the open unleashes its full potential. You can't imagine +how happy I was to have some friends come and work on this with us :)

+

Here is a wrap-up of the sprint:

+
+

Autocompletion on the command-line

+

Remy Hubscher worked on the command-line +autocompletion. Now we have a fancy command-line interface which is able to +aucomplete if you're using bash. It seems that not that much work is needed to +make it happen on zsh as well :)

+

Have a look at the feature

+

On the same topic, we now have a cool shell for Circus. If you start the +circusctl command without any option, you'll end-up with a cool shell. Thanks +Jonathan Dorival for the work on this! You can +have a look at the pull request.

+
+
+

Future changes to the web ui

+

Rachid Belaid 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'm glad of this. +Currently, it's done with bottle.py and we want to switch to pyramid.

+

He fixed some issues that were in the tracker, so we now can have the age of +watchers in the webui, for instance.

+
+
+

Bug and doc fixing

+

While reading the source code, we found some inconsistencies and fixed them, +with Mathieu Agopian. We also tried to +improve the documentation at different levels.

+

Documentation still needs a lot of love, and I'm planning to spend some time on +this shortly. I've gathered a bunch of feedback on this

+
+
+

Circus clustering capabilities

+

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

+

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

+

Remy wrote a good summary about our brainstorming so I'll not do +it again here, but feel free to contact us if you have ideas on this, they're +very welcome!

+
+
+

Project management

+

We've had some inquiries telling us that's not as easy as it should to get +started with the Circus project. Some of the reasons are that we don't +have any release schedule, and that the documentation is hairy enough to lost +people, at some point :)

+

That's something we'll try to fix soon :)

+

PyconFR was a very enjoyable event. I'm looking forward to meet the community +again and discuss how Circus can evolve in ways that are interesting to +everyone.

+

Tarek and me are going to Pycon ireland, feel +free to reach us if you're going there, we'll be happy to meet and enjoy beers!

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/cloisonnement-des-activites.html b/cloisonnement-des-activites.html new file mode 100644 index 0000000..e62a621 --- /dev/null +++ b/cloisonnement-des-activites.html @@ -0,0 +1,177 @@ + + + + + + + + + Cloisonnement des activités ? - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Cloisonnement des activités ?

+ + + +
+

En revenant de SudWeb

+

🌟

+

Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de SudWeb. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en faire +un plaisir. Oh, et des fois on parle un peu de technique aussi.

+

Alors, brasserie ou code ?

+

Ces quelques jours ont été fort inspirants. Alors que je suis en train de +changer de métier (vers celui de brasseur) c'était un moyen de me rendre compte +que bien que je ne souhaite plus faire du Web mon métier la, tout de suite, +maintenant, je reste un passionné par la chose.

+

En partant de Rennes, je ne savais pas trop quoi penser de cette situation. +Prendre un week-end pour échanger avec les gens sur quelque chose dont je +m'éloigne ? C'est pas une perte de temps ?

+

Si je passe du temps à écrire des bouts de code, des logiciels, à reflechir +à comment solutionner certains problemes, ce n'est pas parce que je suis payé +pour le faire, mais bel et bien parce que je me sens bien lorsque je le fais, +parce que j'y trouve un équilibre et une utilité.

+

Alors que je ne trouvais plus cet équilibre dans mon travail, j'ai choisi d'en +changer, mais il n'empèche que je continue à avoir des rèves d'un +monde meilleur, dans lequel l'informatique a sa place. Juste à voir les +discussions (ux, sécurité informatique, décentralisation, architecture +logicielle) que j'ai pu avoir ce weekend, il n'y a pas l'ombre d'un doute !

+

Jusqu'ici je me suis dit que je devais choisir. J'ai pensé naivement +que je ne pouvais pas être et un brasseur et un developpeur, mais la +réalité c'est que c'est exactement ce que je suis: les deux.

+

Je ne suis pas pour autant dupe sur le temps necessaire à lancer une activité +brassicole, il va falloir fournir de l'énergie et avancer sur le projet, mais +il n'empèche que même si je décide de faire de la bière mon metier, mes +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 ?

+ Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ 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 new file mode 100644 index 0000000..5355481 --- /dev/null +++ b/comment-est-ce-que-vous-generez-vos-formulaires.html @@ -0,0 +1,241 @@ + + + + + + + + + Comment est-ce que vous générez vos formulaires ? - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

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

+

🌟

+

TL; DR: Je viens à peine de releaser la première version d'un service de génération de formulaires. +Allez jeter un coup d'œil sur https://www.fourmilieres.net

+

En février 2012, je parlais ici d'un service de génération de formulaires. +Depuis, pas mal d'eau à coulé sous les ponts, on est passé par pas mal d'étapes pour +finalement arriver à une première version de ce service de génération de +formulaires (à la google forms).

+

En tant qu'organisateurs d'é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 Google Forms, +mais celle ci à plusieurs problèmes, à commencer par le fait que le code n'est +pas libre et que les données sont stockées chez Google.

+

La plupart du temps, le besoin est assez simple: je veux spécifier quelques +questions, et donner un lien à mes amis pour qu'ils puissent y répondre. +Je reviens ensuite plus tard pour voir la liste des réponses apportées.

+

Capture de l'interface de création du formulaire

+

Fonctionnalités

+

Il existe pas mal de solutions techniques qui essayent de répondre à la même +problématique, mais la plupart d'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 à +déployer.

+

Je voulais donc quelque chose de simple à utiliser et pour les créateurs de +formulaires et pour les utilisateurs finaux. Pas de chichis, juste quelques +vues, et des URLs à sauvegarder une fois l'opération terminée.

+

Capture de l'écran avec les URLs générées +Capture d'écran d'un exemple de formulaire

+

Pas de compte

+

Vous n'avez pas besoin d'avoir un compte sur le site pour commencer à l'utiliser. +Vous créez simplement un nouveau formulaire puis envoyez le lien à vos amis pour +qu'eux puissent à leur tour le remplir.

+

Capture de la page d'accueil, ou aucun compte n'est requis

+

Gardez la main sur vos données

+

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

+

Capture de la page de resultats, il est possible de télécharger en CSV.

+

API

+

L'ensemble des données sont en fait stockées dans Kinto +qui est interrogeable très facilement en HTTP. Ce qui fait qu'il est très facile de +réutiliser les formulaires que vous avez construits (ou leurs réponses) depuis +d'autres outils.

+

Auto-hébergeable

+

Un des objectifs de ce projet est de vous redonner la main sur vos données. +Bien sur, vous pouvez utiliser l'instance qui est mise à votre disposition sur +wwww.fourmilieres.net, mais vous pouvez +également l'héberger vous même très +simplement, et vous êtes d'ailleurs fortement encouragés à le faire ! Notre +objectif n'est pas de stocker l'ensemble des formulaires du monde, mais de +(re)donner le contrôle aux utilisateurs !

+

On commence petit…

+

Cette release n'est (bien sur) pas parfaite, et il reste encore pas mal de +travail sur cet outil, mais je pense qu'il s'agit d'une base de travail +intéressante pour un futur où Google n'a pas la main sur toutes nos données.

+

La liste des champs supportés est pour l'instant assez faible (Texte court, +Texte long, Oui/Non, choix dans une liste) mais elle à vocation à s'étendre, en +fonction des besoins de chacun.

+

J'ai d'ailleurs créé un formulaire pour que vous puissiez me faire part de vos +retours, n'hésitez pas !

+

Et, euh, comment ça marche ?

+

Le formbuilder, comme j'aime l'appeler se compose en fin de compte de deux +parties distinctes:

+
    +
  • Kinto, un service qui stocke + des données coté serveur et qui les expose via des APIs HTTP
  • +
  • Le formbuilder, une application + JavaScript qui ne tourne que coté client (dans votre navigateur) qui permet + de construire les formulaires et d'envoyer les données sur les APIs coté + serveur.
  • +
+

Au niveau de la stack technique, le formbuilder est codé en ReactJS. Un +des points techniques intéressants du projet est qu'il génère en fin de compte du +JSON Schema, un format de validation de données JSON.

+

Donc, reprenons! Vous arrivez sur la page d'accueil puis cliquez sur +"Create a new form", puis vous vous retrouvez face à une interface ou vous pouvez +ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez sur +"Create the form".

+
    +
  • Le JSON Schema est alors envoyé au serveur Kinto, qui l'utilisera pour valider + les données qu'il recevra par la suite.
  • +
  • Ce JSON Schema sera aussi utilisé lors de l'affichage du formulaire aux + personnes qui le remplissent.
  • +
  • Un jeton d'accès est généré et ajouté à l'URL, il s'agit de l'identifiant du + formulaire.
  • +
  • Un second jeton d'accès administrateur et généré, il vous faut le garder de + coté pour avoir accès aux réponses.
  • +
+

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

+ L'image d'illustration utilisée est un travail de Kurt Faler proposé sous license CC BY-NC-ND 2.0. Merci ! + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/confiance-fr.html b/confiance-fr.html new file mode 100644 index 0000000..2b2c1f1 --- /dev/null +++ b/confiance-fr.html @@ -0,0 +1,236 @@ + + + + + + + + + Des profils de confiance partout et pour tout ? - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Des profils de confiance partout et pour tout ?

+ + + +
+

🌟

+

Depuis un petit moment déjà, le site covoiturage.fr est passé "payant". Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.

+

Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site et de les appeler soi même, chose maintenant automatisée.

+

Dès que cette décision à été prise, il y a eu des émules. Le site Covoiturage +Libre à été d'ailleurs créé pour faire en sorte +de garder "l'esprit" du covoiturage. Bref ça jasait dans les chaumières.

+

Il y à peu, j'ai reçu un couriel contenant un lien vers une vidéo d'une +conférence animée par le fondateur de covoiturage.fr.

+

Ils semblent vouloir parler de confiance, alors ça m'intrigue, d'autant que la +présentation en question est donnée lors d'un évènement TEDx, auquel j'accorde +un certain crédit.

+
+

Un "capital de confiance"

+

Cette vidéo parle entre autres du capital de confiance que nous pouvons +nous accorder les uns aux autres; et notamment du fait que ce capital de +confiance n'est malheureusement pas partagé au dela d'un cercle de +connaissances assez limité. Il reste dans notre cercle de connaissances proche, les +amis des amis.

+

C'est donc une chose regrettable, parce que ça nous fait perdre du temps (et +donc, ohmygod de l'argent) à tous pour construire cette confiance. Temps qui +pourrait être mieux employé.

+

La solution proposée, attention les yeux, est de faire appel un maximum aux +profils en ligne, une manière de "prouver au monde" que nous sommes des +personnes de confiance. Selon les termes de la présentation, nous pourrions +alors tous devenir des "super héros du trust", des "trustman".

+

Grâce à des profils en ligne ou monsieur et madame tout le monde pourraient +aller voter et donner leur avis sur les personnes qu'ils ont rencontré.

+
+
+

L'avènement du paiement en ligne

+

On nous dit maintenant que le paiement en ligne est une révolution, un moyen de +tracer le fait qu'il y à effectivement eu une transaction entre deux personnes; +et que donc il en deviendrait un outil pour vérifier que la confiance est bien +légitime, et non pas créée de toute pièce sur le profil de la personne en +question.

+

Plu

+

Plus exactement, ce qui est dit est que le paiement en ligne permet de +justifier qu'il y a bien eu transaction entre deux personnes, et que donc les +commentaires et "notations" effectuées sont donc légitimes.

+
+
+

Ce n'est pas un problème de confiance !

+

Bien que j'arrive à suivre le raisonnement, il soulève certaines questions :

+

Si j'accorde de la confiance à quelqu'un dans mon cercle de connaissances, +c'est justement parce qu'il fait partie de ce cercle de connaissances. Pas +parce qu'une personne que je ne connait pas me dit qu'il s'agit d'une personne +de confiance. En d'autres termes, pourquoi ne garderions nous pas ces +relations privilégiées de personne à personne ?

+

Dans le cadre du covoiturage, j'arrive à comprendre le raisonnement du paiement +à l'avance, pour avoir souvent entendu parler de désistements à la dernière +minute de la part des voyageurs. Le paiement à l'avance permet d'éviter ce +genre de désagréments.

+

Mais cela n'as rien à voir avec la confiance, il s'agit d'engagement de la part +des deux parties.

+

Et c'est bien ce qui semble poser problème: lorsqu'on s'attend à partager le +prix d'un trajet avec quelqu'un, c'est bien d'avoir quelque chose qui nous +y engage. J'aime beaucoup l'idée de payer une fois dans la voiture, de garder +cette transaction manuelle; et de laisser peu de place au paiements en ligne +dans cette histoire, mais je n'ai pas d'autre solution miracle.

+

En tout cas, la question n'est pas la question de savoir avec qui on embarque, +mais bel et bien la question de l'engagement des deux parties.

+

Nous sommes malheureusement dans une société qui est dirigée par la peur. On +à peur de se faire agresser par le gars qui tends le pouce sur le bord de la +route, peur de se faire envoyer un produit qui ne fonctionne pas via Amazon, +etc.

+

En poussant l'idée dans ses retranchements, j'aurais bientôt peur de mes +voisins alors je ne leur parlerais plus, parce qu'ils n'ont pas leur profil +disponible en ligne ou parce que quelqu'un à eu une mauvaise expérience avec +eux ?

+

Exposer des choses qui relèvent de ma vie privée en ligne de la sorte me +pose des problèmes éthiques: d'abord parce que je ne veux pas juger les gens +a priori, ensuite parce que l'expérience d'une personne n'est peut-être pas +représentative, tout simplement.

+

Donc non, ce n'est pas un problème de confiance, il s'agit d'un problème +d'engagement, dans le cadre du covoiturage, et les profils en ligne n'ont rien +à faire la dedans. Le principe du paiement à l'avance me semble intéressant, +mais il n'est à mon avis pas lié au profils en ligne.

+

La vidéo termine sur un "libérez la valeur de la confiance". Oui, mais la +libérer pour qui ? Quels sont les problèmes liés à cette confiance rendue +nécessaire partout et pour tout ? Cela ne nous ferait-il pas évoluer uniquement +dans des cercles fermés ? Quelle place laisser à l'inconnu, à la surprise ?

+

Cette volonté de "confiance partout" semble découler tout droit des délires +sécuritaires que l'on nous sert à toutes les sauces. Et 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.

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/cross-origin-in-cornice.html b/cross-origin-in-cornice.html new file mode 100644 index 0000000..9b57ef2 --- /dev/null +++ b/cross-origin-in-cornice.html @@ -0,0 +1,352 @@ + + + + + + + + + Implementing CORS in Cornice - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Implementing CORS in Cornice

+ + + +
+

🌟

+
+

Note

+

I'm cross-posting on the mozilla services weblog. Since this is the +first time we'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.

+
+

For security reasons, it'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 notmyidea.org.

+

Well, it's possible, using tricks and techniques like JSONP, but that doesn't work all the time (see +the section below). I remember myself +doing some simple proxies on my domain server to be able to query other's API.

+

Thankfully, there is a nicer way to do this, namely, "Cross Origin +Resource-Sharing", or CORS.

+
+

You want an icecream? Go ask your dad first.

+

If you want to use CORS, you need the API you're querying to support it; on the +server side.

+

The HTTP server need to answer to the OPTIONS verb, and with the appropriate +response headers.

+

OPTIONS is sent as what the authors of the spec call a "preflight request"; +just before doing a request to the API, the User-Agent (the browser most of +the time) asks the permission to the resource, with an OPTIONS call.

+

The server answers, and tell what is available and what isn't:

+The CORS flow (from the HTML5 CORS tutorial) +
    +
  • 1a. The User-Agent, rather than doing the call directly, asks the server, the +API, the permission to do the request. It does so with the following headers:
      +
    • Access-Control-Request-Headers, contains the headers the User-Agent +want to access.
    • +
    • Access-Control-Request-Method contains the method the User-Agent want +to access.
    • +
    +
  • +
  • 1b. The API answers what is authorized:
      +
    • Access-Control-Allow-Origin the origin that's accepted. Can be * or +the domain name.
    • +
    • Access-Control-Allow-Methods a list 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 methods.
    • +
    • Access-Allow-Headers a list of allowed headers, for all of the +methods, since this can be cached as well.
    • +
    +
  • +
    1. +
    2. The User-Agent can do the "normal" request.
    3. +
    +
  • +
+

So, if you want to access the /icecream resource, and do a PUT there, you'll +have the following flow:

+
+> OPTIONS /icecream
+> Access-Control-Request-Methods = PUT
+> Origin: notmyidea.org
+< Access-Control-Allow-Origin = notmyidea.org
+< Access-Control-Allow-Methods = PUT,GET,DELETE
+200 OK
+
+

You can see that we have an Origin Header in the request, as well as +a Access-Control-Request-Methods. We're here asking if we have the right, as +notmyidea.org, to do a PUT request on /icecream.

+

And the server tells us that we can do that, as well as GET and DELETE.

+

I'll not cover all the details of the CORS specification here, but bear in mind +than with CORS, you can control what are the authorized methods, headers, +origins, and if the client is allowed to send authentication information or +not.

+
+
+

A word about security

+

CORS 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 CORS, so you'll need to +write a proxy yourself, to provide this.

+

Secondly, if misunderstood, CORS 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're authorizing.

+

An incorrectly secured CORS 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 VPN 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 want.

+
+
+

How this is different from JSONP?

+

You may know the JSONP protocol. JSONP +allows cross origin, but for a particular use case, and does have some +drawbacks (for instance, it's not possible to do DELETEs or PUTs with JSONP).

+

JSONP exploits the fact that it is possible to get information from another domain +when you are asking for javascript code, using the <script> element.

+
+Exploiting the open policy for <script> elements, some pages use them to +retrieve JavaScript code that operates on dynamically generated +JSON-formatted data from other origins. This usage pattern is known as +JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. +They are evaluated by the JavaScript interpreter, not parsed by a JSON +parser.
+
+
+

Using CORS in Cornice

+

Okay, things are hopefully clearer about CORS, let's see how we +implemented it on the server-side.

+

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 CORS support as +well.

+

In Cornice, you define a service like this:

+
from cornice import Service
+
+foobar = Service(name="foobar", path="/foobar")
+
+# and then you do something with it
+@foobar.get()
+def get_foobar(request):
+    # do something with the request.
+
+

To add CORS support to this resource, you can go this way, with the +cors_origins parameter:

+
foobar = Service(name='foobar', path='/foobar', cors_origins=('*',))
+
+

Ta-da! You have enabled CORS for your service. Be aware that you're +authorizing anyone to query your server, that may not be what you want.

+

Of course, you can specify a list of origins you trust, and you don't need +to stick with *, which means "authorize everyone".

+
+

Headers

+

You can define the headers you want to expose for the service:

+
foobar = Service(name='foobar', path='/foobar', cors_origins=('*',))
+
+@foobar.get(cors_headers=('X-My-Header', 'Content-Type'))
+def get_foobars_please(request):
+    return "some foobar for you"
+
+

I've done some testing and it wasn't working on Chrome because I wasn'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 developing.

+

So I introduced an expose_all_headers flag, which is set to True by +default, if the service supports CORS.

+
+
+

Cookies / Credentials

+

By default, the requests you do to your API endpoint don'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 basis.

+
+
+

Caching

+

When you do a preflight request, the information returned by the server can be +cached by the User-Agent so that it's not redone before each actual call.

+

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

+
+
+

Simplifying the API

+

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 CORS-policy for your services, that +can be a bit tedious to pass these to your services all the time.

+

I introduced another way to pass the CORS policy, so you can do something like +that:

+
policy = dict(enabled=False,
+              headers=('X-My-Header', 'Content-Type'),
+              origins=('*.notmyidea.org'),
+              credentials=True,
+              max_age=42)
+
+foobar = Service(name='foobar', path='/foobar', cors_policy=policy)
+
+
+
+
+

Comparison with other implementations

+

I was curious to have a look at other implementations of CORS, in +django for instance, and I found a gist about it.

+

Basically, this adds a middleware that adds the "rights" headers to the answer, +depending on the request.

+

While this approach works, it's not implementing the specification completely. +You need to add support for all the resources at once.

+

We can think about a nice way to implement this specifying a definition of what's +supposed to be exposed via CORS and what shouldn't directly in your settings. +In my opinion, CORS support should be handled at the service definition level, +except for the list of authorized hosts. +Otherwise, you don't know exactly what's going on when you look at the definition of the service.

+
+
+

Resources

+

There are a number of good resources that can be useful to you if you want to +either understand how CORS works, or if you want to implement it yourself.

+ +

Of course, the W3C specification is the best resource to rely on. This +specification isn't hard to read, so you may want to go through it. Especially +the "resource processing model" section

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/de-mozilla-a-la-brasserie-du-vieux-singe.html b/de-mozilla-a-la-brasserie-du-vieux-singe.html new file mode 100644 index 0000000..b22a080 --- /dev/null +++ b/de-mozilla-a-la-brasserie-du-vieux-singe.html @@ -0,0 +1,170 @@ + + + + + + + + + De Mozilla à la Brasserie du Vieux Singe - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

De Mozilla à la Brasserie du Vieux Singe

+ + + +
+

Comment un passionné de Logiciels libres choisit de créer une petite brasserie artisanale.

+

🌟

+

Ce weekend avait lieu SudWeb « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.

+

Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que d'autres ont pris plus de place que prévu. J'avais donc envie de reprendre mes notes pour les transformer en billet de blog, question d'élaborer sur le sujet.

+
+

J'ai toujours été motivé par mes passions. Quand j'ai commencé à travailler professionnellement, je me suis rendu compte que même si je faisais quasiment la même chose qu'auparavant, ça n'avait plus le même goût. J'étais maintenant obligé de le faire, et je n'en tirais pas le même plaisir.

+

Quand j'étais plus jeune au lycée j'écrivais des programmes en Visual Basic que je partageais en ligne sur mon site en .free.fr. Programmes que probablement personne n'a lu, mais l'intention était bel et bien celle de partager mes créations, et d'échanger à leur propos.

+

Cette culture du partage — celle du logiciel libre — est celle qui m'anime.

+

Quelques années plus tard, je découvre le langage de programmation Python, et avec lui toute une communauté, mue par ces mêmes valeurs de partage et d'amélioration de nos pratiques. Puis je rencontre le Logiciel Libre, avec l'écriture d'un programme (pelican) qui reste encore largement utilisé aujourd'hui. Autant dire que c'est une bonne claque que de voir des inconnus contribuer à un bout de code qu'eux aussi jugent utile.

+

À la fin de mes études, alors que je reste passionné par le développement logiciel, je ne veux ni travailler pour l'industrie, ni pour la finance. Je songe même déjà à cette époque à changer de métier (avant même d'avoir commencé !). Coup de bol, une structure qui m'est chère cherche des développeurs Python: Mozilla. Sans trop y croire, je passe une série d'entretiens qui se déroulent bien (!) et je commence quelques mois plus tard à travailler pour cette organisation incroyable, porteuse d'espoir et de toute une symbolique pour moi.

+

Je bosse sur du Logiciel Libre, en Python, en télétravail parfois, avec une bonne paie, sans parler du côté prestigieux. Grisant.

+

Mais au fur et à mesure je découvre l'envers du décors: une méritocratie ancrée et assumée, une hiérarchie de plus en plus importante, menant à une lourdeur administrative assez présente. À ajouter à la barrière de la langue, et aux différences culturelles. Finalement tout n'est pas rose ici.

+

Je décide alors de (je pense) faire un de mes meilleurs choix de vie à ce jour: passer aux 4/5èmes. Je récupère tous mes vendredis. Des weekends de 3 jours, toutes les semaines. Un espace précieux pour me reposer, et pour rêver un peu.

+

C'est à ce moment que Fred, un ami de longue date, en revenant du Québec (ou les brasseries sont légion), me propose de faire de la bière avec lui. Moi qui ne savais même pas qu'il était possible de faire de la bière. On tente donc l'expérience, et nos premières expériences sont des journées bien funky, à faire toutes les erreurs possibles.

+

Peu à peu, on découvre un nouveau monde: celui des brasseurs amateurs. De nouvelles compétences sont nécessaires, de la physique à la biochimie. On se met à rencontrer des professionnels, des passionnés, à échanger sur les forums. On se forme, petit à petit. Tout comme il y a la communauté des gens qui font du Python, il y a la communauté des gens qui font de la bière. Pas encore autant fédérés, ça semble balbutiant alors mais la passion elle est bien présente.

+

Tout comme le monde du Logiciel Libre est constitué autour d'un ennemi commun (les GAFA), le monde de la bière artisanale à la sien: les brasseries industrielles, qui uniformisent les goûts et les processus.

+

Je continue en parallèle mon travail chez Mozilla, pendant 4 années. Et puis un jour, une annonce d'arrêt d'un projet sur lequel je travaillais me fait réaliser que cette situation m'épuise. La fameuse goutte de trop.

+

Je décide alors de partir, de faire une pause, sans trop savoir ce que l'avenir me réserve. Une petite période de blanc de deux mois. Le regard des autres est parfois culpabilisant. Mes parents me demandent si « je ne veux pas attendre encore un peu ». La transition me fait peur, mais je choisis quand même de troquer mon confort matériel pour de la cohérence.

+

Petit à petit, l'idée de monter ce qui est maintenant devenu La Brasserie du Vieux Singe se pose en évidence. Mais monter une brasserie ce n'est pas uniquement faire de la bière: c'est se mettre d'accord sur des valeurs, trouver comment les défendre, monter un projet pour, et tenir le cap.

+

Quelques mois après mon départ, on se retrouve donc à parler de ces valeurs de partage, de documentation, de goût. De gouvernance et de collaboration aussi. +Dans nos pratiques courantes, on décide d'intégrer du temps pour documenter la vie de la brasserie.

+

À titre d'exemple, nos étiquettes contiennent l'ensemble des ingrédients que l'on utilise de la manière la plus détaillée possible. On travaille aussi sur un projet de laveuse de fûts, qui sera publié sous licence libre, avec l'idée de pouvoir, petit à petit, constituer un ensemble d'outils utiles à tous les brasseurs, et peut être même réussir à favoriser les échanges entre toutes ces personnes.

+

Nous sommes deux brasseurs, deux chefs d'entreprise, mais aussi deux développeurs. Nos compétences de développeurs nous sont utiles quotidiennement: pour notre laveuse de fûts, pour nos créations de recettes (j'ai découvert la puissance des tableurs !), pour notre site de préventes, notre site Web, nos outils du quotidien. On se rend compte qu'il s'agit de compétences précieuses.

+

Mais monter une entreprise, c'est aussi assumer une partie administrative. Vous vous rappelez cette histoire de réactions face aux activités subordonnées ? Et bien quand je fais mes déclarations aux douanes, ce n'est pas de gaîté de cœur. Je sais par contre pourquoi je le fais: ce sont les règles du jeu. Des obligations, mais peut-être moins de coercition. J'y trouve plus de sens.

+

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.

+ Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/des-carnets-desquisse-fr.html b/des-carnets-desquisse-fr.html new file mode 100644 index 0000000..05d45df --- /dev/null +++ b/des-carnets-desquisse-fr.html @@ -0,0 +1,176 @@ + + + + + + + + + Des carnets d'esquisse - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Des carnets d'esquisse

+ + + +
+

🌟

+

Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.

+

Des fois j'ai cette envie d'ouvrir un "carnet" et d'y jeter juste quelques +notes. Pas grand chose: mes quelques pensées ou alors des liens 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.

+

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

+
+

Le retour des commentaires

+

Au passage, je ne me rappelle plus quand exactement, mais j'avais décidé de +supprimer les commentaires de cet espace. Paf, apu. Comme ça, sans prévenir.

+

Les raisons en étaient à la fois techniques (je ne souhaitait pas avoir recours +à disqus qui est un silo propriétaire de plus) et parce que je considérais que +les commentaires n'avaient que peu d'intérêt. Ceci dit, le manque d'échange me +manque; j'aimerais bien savoir ce que vous pensez de ce que j'écris des fois, +et avoir des débats si nos opinions divergent.

+

Et puis bon, partager dans un seul sens, c'est un peu dommage !

+

Il est maintenant possible, avec talka.tv d'héberger soi +même ses commentaires. J'ai dans l'idée d'héberger une instance de 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 !)

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/djangocong-2012-fr.html b/djangocong-2012-fr.html new file mode 100644 index 0000000..73cb22b --- /dev/null +++ b/djangocong-2012-fr.html @@ -0,0 +1,199 @@ + + + + + + + + + Djangocong 2012 - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Djangocong 2012

+ + + +
+

🌟

+

Ce week-end, c'était djangocong, une conférence autour de django, +de python et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.

+

J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des nerds, j'y ai trouvé une qualité d'é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 :)

+

En tant que hackers, 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'ai eu l'occasion de discuter de projets tournant autour de +l'entraide, que ça soit pour mettre en lien des associations d'économie sociale +et solidaire (ESS) ou simplement pour que les populations non tech puissent +utiliser toute la puissance de l'outil qu'est le web.

+

Au niveau du format des conférences, je ne savais pas trop à quoi m'attendre, +au vu des échos de l'an dernier, mais c'était adapté: des mini-confs de 12mn le +samedi matin + début d'aprem, en mode no-wifi pour récupérer une qualité +d'écoute. Et contrairement à mes attentes, ce n'est pas trop court. Pas mal de +retours d'expérience pour le coup, et une matinée pas vraiment techniques, mais +ça pose le décor et permet de savoir qui fait quoi.

+

Parmi l'ensemble des conférences du matin, je retiens principalement +celle de Mathieu Leplatre, "des cartes d'un autre monde", qui m'a réellement +bluffée quand à la facilité de créer des cartes avec TileMill, et qui me pousse à reconsidérer le fait que "la +carto, c'est compliqué". La vidéo est (déja !) disponible en ligne, je vous invite à la regarder +(c'est une 15aine de minutes) pour vous faire un avis ;)

+

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 "notre" projet "carto +forms", qui à finalement pu se +redéfinir un peu plus et donner naissance à un README. On en +à profité pour lui choisir un nouveau nom: "daybed", en référence à couchdb.

+

Ça devrait se transformer en code d'ici peu. La curiosité aidant, on a pu +discuter du projet avec d'autres personnes et affiner les attentes de chacun +pour finalement arriver à quelque chose d'assez sympathique.

+

J'ai aussi pu me rendre compte que pas mal de monde utilise pelican, le bout de code que j'ai codé pour générer ce +blog, et avoir des retours utiles ! Probablement des réflexions à venir +sur comment éviter qu'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 contributeurs.

+

Bien évidemment, c'était aussi l'occaz de rencontrer des gens qu'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 chouette.

+

Entres autres faits notoires, JMad a perdu au baby-foot face à Exirel, même +en m'ayant à ses cotés pour le déconcentrer (et je suis un joueur d'un autre +monde - en d'autres termes, je suis nul), David`bgk ne s'est pas levé pour +aller courir le dimanche matin (il avait dit 5 heures!), Les suisses ont essayé +de me convertir à coup d'abricotine, j'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'ils mentent avec leur soit disant +soleil).

+

Et c'est sans parler de la brasucade

+

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

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/acceder-a-internet-hors-ligne.html b/drafts/acceder-a-internet-hors-ligne.html new file mode 100644 index 0000000..e383f4e --- /dev/null +++ b/drafts/acceder-a-internet-hors-ligne.html @@ -0,0 +1,214 @@ + + + + + + + + + Accéder à internet hors-ligne - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Accéder à internet hors-ligne

+ + + +
+

🌟

+

J'ai eu la chance de passer quelques semaines de vacances en Australie +dernièrement. Dans mes déplacements j'ai beaucoup utilisé le train et +n'avais que peu souvent accès à une connexion internet.

+

Et rapidement je souhaitais faire des recherches sur un tas de choses: +Que ce soit la culture Aborigène locale, les +oiseaux qu'on croisait, les insectes, les lieux, etc.

+

Les ressources papier existent bien évidemment et mon dos avait le plaisir de +transporter un guide assez complet. Ceci dit, il n'est pas réellement +imaginable de se trimballer avec une encyclopédie sur le dos.

+

À moins que…

+
+

Mise en garde

+

Loin de moi l'idée de vouloir utiliser du numérique partout et pour tout

+

La plupart du temps le moyen que je préfère est de tout simplement discuter +avec les gens autour de moi. Mais des fois il n'y à personne autour, ou alors +les questions tomberaient comme un cheveu sur la soupe.

+

Avoir recours à des outils d'habitude uniquement disponibles en ligne alors que +vous n'avez pas accès à internet peut donc s'avérer réellement utile.

+

Je ne pense pas que j'aurais par exemple pu trouver un spécialiste des termites à l'endroit où j'en avais besoin :-)

+
+
+

Une encyclopédie

+

Ma première stratégie à donc été d'enregistrer des pages web pour les consulter +plus tard (Wikipedia, Wikitravel, etc, autour des sujets qui m' intéressaient. +Ça fonctionne d'ailleurs assez bien. Le problème étant qu'il faut être +pro-actif et savoir à l'avance ce qu'on va faire dans les jours qui viennent.

+

Et puis je me suis rappelé qu'il était possible de récupérer l'encyclopédie +Wikipedia hors ligne. J'avoue que je n'y croyais pas trop, pensant qu'il me +faudrait beaucoup plus de place que ce que mon disque dur pouvait encaisser.

+

Pas tant, en fin de compte: il faut 16Gb pour la version française. Il il est possible de la récupérer en bittorrent, qui permet de récupérer tout ça assez rapidement.

+

Et paf, vous voila avec un logiciel nommé "kiwix" qui vous permet de lire +wikipedia tranquillement depuis votre ordinateur, sans connexion à internet.

+

C'est impressionnant ce qu'on peut trouver comme informations dans ce bijou, +à fortiori lorsqu'on n'est pas interrompu par internet tout le temps.

+
+
+

Cartes

+

Pour ce qui est des cartes, j'avoue que mon option préférée est tout simplement +d'avoir des cartes, des vraies, celles qu'on peut déplier. Je peux passer un +temps dingue juste à regarder une carte, je trouve ça passionnant.

+

Open street map est un projet de cartographie collaborative: chacun peut modifier la carte globale pour l'enrichir avec des détails qui lui semblent utile. Et les données récoltées sont reversées sous une licence libre.

+

Les données existent donc, sur les serveurs d'OSM, il ne reste "juste" qu'à les +récupérer pour une utilisation hors-ligne.

+

XXX

+
+
+

Petits sites ressources

+

Et puis il y à plein d'autres sites qui contiennent une information précieuse, +auxquels vous souhaitez avoir accès hors-ligne. Le blog de votre grand mère +avec ses recettes de flan au Maroual, etc.

+

Sous linux, il existe un outil génial qui s'appelle wget. Il s'agit d'un +couteau suisse du téléchargement. Très simplement, wget permet de récupérer +hors ligne une page web, pour la consulter plus tard.

+

Cet outil est aussi capable de transformer les liens entre pages pour que la +navigation soit possible sur votre copie du site, etc. Pour cela il faut lui +passer quelques options:

+
+wget -r -k -np http://blog.notmyidea.org
+
+

Et vous avez accès à un site hors-ligne, sur votre ordinateur. +"Très bien", me direz vous, mais moi j'ai pas ton machin, "linux", là.

+

Je me suis amusé à faire un site rapide qui permet de récupérer d'autres sites +hors-ligne, sous forme d'archives .zip. Vous entrez l'adresse du site, votre +adresse email et ça s'occupe du reste pour vous !

+

Le site est ici: http://offline.notmyidea.org et le code ici +https://github.com/ametaireau/offline

+

Au cas ou ça vous serve.

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/an-attempt-to-handle-mails-better.html b/drafts/an-attempt-to-handle-mails-better.html new file mode 100644 index 0000000..418b7e0 --- /dev/null +++ b/drafts/an-attempt-to-handle-mails-better.html @@ -0,0 +1,248 @@ + + + + + + + + + An attempt to handle mails better - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

An attempt to handle mails better

+ + + +
+

🌟

+

Those of you who wrote me emails know it, I'm really bad at handling them. This +is because I don't have any flow in place. Recently, I surprised myself +not even reading all these emails. And this means frustration for me and for +the people who expect me to read them.

+

So here is an attempt to solve this.

+

When I first gave some thoughts to this, I directly thought about "how to +automatically improve my inbox", or "how to let the machine do the work rather +than myself.

+

When reading emails, you then need to take actions. Some can be automated +/ short, some cannot.

+
+

Tooling

+

I currently have a folder for each "project" I'm involved in. This means +a lot of projects, and a lot of folders. For instance, when I get a mail from +marketplace-devs@mozilla.org, it goes to the marketplace folder.

+

Let's try to list from where I receive emails and what I should do with +them.

+
    +
  • low-involvement mailling-lists
  • +
  • high-involvement mailing-lists
  • +
  • work-related bugmails
  • +
  • non-work-related bugmails
  • +
  • personal mails
  • +
  • work-related mails
  • +
+
+

Low-involvement mailing-lists

+

These are probably the easiest to get rid of. I subscribed to a bunch of +technical discussion groups, for instance django-dev, pyramid-dev, catalog-sig, +distutils-sig, python-dev and others.

+

Since you can find most of these public mailing-lists online, my last move was +to just unsubscribe from them, telling myself I'll read them there.

+

Obviously, this isn't true because I never read them online until someone +points me to an interesting discussion there, but it seems that the really +interesting topics pops up on twitter / IRC from time to time, and the spare +time it creates is really worth some good information less.

+
+
+

High-involvement mailing-list

+

In this category, I put the mailing lists you have to read, think once, think +again and answer. Answering to emails isn't always something I do +straight-away. Sometimes I'm not good-enough technically to answer really +quickly, and it needs some research from me. Sometimes it just needs some time +for my brain to pick everything up before answering.

+

I currently keep these emails "unread" in their folder, and try to get back to +it later. Which I usually don't do. And everything ends up in limbo.

+

I actually created a second mailbox for myself where I send all the tasks +I need to take time to do. That's a TODO list, but I can actually send it +emails.

+

Every day, I try to find some time to take one of these tasks and have an +answer for these mails. So far it's working well, but I'm wondering what will +happen if I get too much mails in there.

+
+ +
+

Directed mails

+

Once I've setup the rules I described, the remaining mails I receive are +directed personal mails. Hopefully, for me that means not too much mails, and +I'm able to answer them in an acceptable time-frame. I usually try to answer +them straight ahead if I can, also, or convert the ones that ask me for +something special into a GTG task.

+
+
+
+

Discipline

+

That would be foolish to think everything only takes tools. It also takes some +discipline.

+

I'm trying something: I'm spending a little 30mn to an hour reading mails in +the morning, eventually answering if the answer is short; plus another hour in +the afternoon to answer to the longer mails that would had need some more +thinking for me.

+
+
+

Pelican

+

I receive a lot of mails about pelican, and to be honnest I don't read most of +them by now because I know it means I'll have to read text, code, and +eventually make comments on these.

+

And whenever I read these mails, I usually don't have time to handle them right +away. Most of these mails come from github pull requests. This means I got +a mail each time someone open, comment or close on a bug or issue.

+

Okay, so what do I do with that? Currently, these mails end-up in a "folder" on +my email, so they don't languish on my inbox, which is a first good step, but +I would need

+
+
+

Mozilla

+

At mozilla, most of the interesting emails are discussions, but I currently +don't separate the bugmails from the other emails, so in the same box, without +a lot of distinction I receive all the discussions for the different lists I'm +on, and for the code review / issues that are done on either bugzilla or +github.

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/australie.html b/drafts/australie.html new file mode 100644 index 0000000..c3985fe --- /dev/null +++ b/drafts/australie.html @@ -0,0 +1,187 @@ + + + + + + + + + Australie - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Australie

+ + + +
+

🌟

+

Ah, quelques 5 semaines de vacances, de off. Mine de rien ça remets les choses +à leur place. Premièrement, déconnecter un peu avec cet ordinateur et cette +vie que je trouve souvent trop connectée.

+

Et puis, surtout, voyager, me ballader, vivre avec le soleil et (re)découvrir +la nature, les longues randonnées… Retrouver ce lien qui dès fois se perd, +sans trop savoir pourquoi.

+

Bref, en visitant l'australie on à trouvé quelques bijoux, que je m'empresse de +partager, au cas ou ça puisse servir à certains ! (et quelques décéptions +aussi)

+
+

Kangaroo Valley (NSW)

+

La valée des kangourous est au sud de sydney, pas très loin de Nowra. C'est +accessible en train quasiment, mais vous aurez besoin d'une voiture pour faire +quelque chose la bas ensuite.

+

C'est assez petit, mais quelques bushwalks sont possibles. Le petit village au +centre peut vous permettre de faire un peu de canoë

+
+
+

Mungo national park

+

Pas très loin de mildura, un peu perdu au milieu de rien, il y à le mungo +national park. Il faut conduire sur des routes en terre pour à peu près 2h +avant d'arriver sur place, mais ça en vaut l'effort.

+

Il s'agit d'un ancien lac salé, au milieu du desert maintenant. Géologiquement, +l'accumulation de sable et d'argile sont assez ahurissantes puisque on arrive +à retrouver des ossements des premiers aborigènes (dont j'ai oublié le nom).

+

Ce parc national est vriament chouette parce que peu de personnes le +connaissent et donc (contrairement à d'autres endroits ou c'est difficilement +vivable) il y à peu de touristes.

+

Par contre les mouches sont au rendez-vous ! +Au programme, on à eu des superbes couchers de soleil, un silence quasi total +(j'avais jamais pu voir ça avant) et un ciel ahurissant.

+
+
+

The great Ocean road

+

Tiens, en parlant de trucs touristiques ! En paratant de Melbourne, on à décidé +d'aller fair eun tour sur cette route qui semble assez connue. C'est assez +beau, quelques points de vue sur l'océan avec des vagues qui se fracassent sur +la roche, mais dans l'ensemble c'est un peu étrang ede voir tout le monde faire +cette route dans sa voiture et s'arrêter pour prendre des photos.

+

On à déniché un super petit camping gratuit à sur la pointe

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/carto-forms-first-steps.html b/drafts/carto-forms-first-steps.html new file mode 100644 index 0000000..ea4fcf3 --- /dev/null +++ b/drafts/carto-forms-first-steps.html @@ -0,0 +1,309 @@ + + + + + + + + + Carto Forms - First steps - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Carto Forms - First steps

+ + + +
+

🌟

+

For an introduction on carto forms, please see this blog post: +https://blog.notmyidea.org/carto-forms.html (and its variant in french if you +prefer: https://blog.notmyidea.org/carto-forms-fr.html)

+

So, let's not talk too much about what we want to do, and rather explain how we +will do it instead ;)

+

Writing this article turned out to dump my thinking while bootstraping the +project, so I'm really explaining how I'm getting from here to there ;)

+
+

First step: defining a way to describe forms

+

What we want is a generic way to describe forms. I'm not sure if such a thing +exist. And, because I'm on a train atm, let's suppose there isn't anything like +this already (which is probably a wrong assumption, but, let's stick with that +for now).

+

What do we want? A way to associate titles, descriptions to a field. We also +want to be able to describe what's in the field (the type of content), and if +it is a repeatable field or not. In the case of a selection, we might also want +to have a list of possibilities somewhere. Let's take a simple example:

+

Title: Ads spots +Description: Describe all the ads spots in Paris +Fields:

+
    +
  • location (geoloc/address/lat-long)
  • +
  • size the size of the ad (choice list: small/medium/big/huge)
  • +
  • light is there light on it? (boolean)
  • +
+

Okay, so what we have here is in the form: name description (type of field). +In some way, we need to separate the widget that will be displayed to the user +from the type of data. What we need here is the type of data, the widget thing +should be decided at a different layer. So, let's refine the "location" field +to "location (SIG point)".

+

Okay, we now know what we want to save. Yet, we need to define the format. +At this point, I'm wondering if I should use XML, YAML or JSON to describe this +data. To be able to choose, listing the potential consumers / providers of data +can help. The first consumer of this data will be a REST API, and the first +producer will be, probably javascript (or whatever techno is used on the +client). Of course, we can provide lots of format on the REST API and depend +on the "Content-Types" header to know how to talk to it, but well, do we really +want or need to do that? Let's assume no for now and stick with JSON, because +it's now easily validable and I can't think of a language without a lib for it +(apart COBOL, of course).

+

Hey-hi, JSON. How does our data look with you? Let's dump a python structure +and dump it with json.dumps:

+
+data = {
+'title': 'Ads spots',
+'description': 'All the ads spots in paris',
+'fields': (
+ {'name': 'location', 'type': 'SIG point'},
+ {'name': 'size', 'type': 'choice', 'description': 'the size of the ad',
+  'choices': ('small', 'medium', 'big', 'huge')},
+ {'name': 'light', 'desciption': 'is there light on it?', 'type': 'bool'},
+)}
+import json
+json.dumps(data)
+
+

… and the result is (ran with python data.py | python -m json.tool) …:

+
+{
+    "title": "Ads spots"
+    "description": "All the ads spots in paris",
+    "fields": [
+        {
+            "name": "location",
+            "type": "SIG point"
+        },
+        {
+            "choices": [
+                "small",
+                "medium",
+                "big",
+                "huge"
+            ],
+            "description": "the size of the ad",
+            "name": "size",
+            "type": "choice"
+        },
+        {
+            "desciption": "is there light on it?",
+            "name": "light",
+            "type": "bool"
+        }
+    ],
+}
+
+
+
+

Validating the form definition

+

JSON is nice to us, JSON schema now exists and there are tools to work with it. +Quickly, it's the same kind of things than what's provided by XML Schema: you +create a schema, pass it some data and it's able to tell you if the data +complies with the schema. If not, it gives you a nice list of wrong fields.

+

The second option, in python, is a tool named colander, which approximately +does the same thing, but with its own syntax.

+

FIXME need to dig on json schema here and do an approx schema for this.

+
+
+

Creating the forms

+

The next step is to actually create a form from this. Python, and django in +particular, have nice APIs to do that in python. However, I don't know how +they internally work, but you can pass to it some data provided by an HTTP POST +request and it will tell you if it validate or no.

+

The problem with django is that you're tied to it, and it's not possible (well, +as far as I know) to get only the validation bits out of it. On the other hand, +the form framework already comes with nice geolocation facilities. It could be +nice to have a tool able to parse the format we defined and to generate django +models out of it.

+

We need to be careful here: what I'm talking about is to generate code… Well, +there are two approches to do that: either we generate a python file and parse +it, or either we can read the json data and programatically create a form out +of it, at runtime. We might want to cache this at some point to avoid doing it +each time, but let's consider it's another problem we will tackle later.

+

So, django internals!

+

Let's loop on the fields provided by our format and generate the form. We will +care about how to store this / retrieve it later :)

+

Oh, but wait. I'm talking about forms but I should be talking about models! +Validation is one thing, but what we want to do is to describe the data we will +be handling. Forms will just be the user facing thing and what will to the +validation!

+

Django, no django? Let's think about this one more time. There is another +competitor on this field, because we are talking about storing information that +are changing all the time and to base validation on them: CouchDB! And there +also is GeoCouch, which brings interesting SIG features to Couch. And it's +talking JSON!

+

Creating a new form should be as easy as this:

+
+$ curl -X POST localhost:5984/cartoforms/ -d "`python test.py`" -H "Content-Type: application/json"
+{"ok":true,"id":"2d58ef2b02eae639b3f94e357a000d26","rev":"1-0462d0827e7cdad20b5703a923249220"}
+
+

Hmm, wait, this is cool but we got this hideous hash. Let's change this to a +PUT instead:

+
+$  curl -X PUT localhost:5984/cartoforms/paris-ads -d "`python test.py`" -H "Content-Type: application/json"
+{"ok":true,"id":"paris-ads","rev":"1-0462d0827e7cdad20b5703a923249220"}
+
+

Of course, we can already retrieve this with a GET:

+
+curl -X GET localhost:5984/cartoforms/paris-ads -d "`python test.py`"
+{"_id":"paris-ads","_rev":"1-0462d0827e7cdad20b5703a923249220","fields":[{"type":"SIG
+point","name":"location"},{"choices":["small","medium","big","huge"],"type":"choice","name":"size","description":"the
+size of the ad"},{"type":"bool","desciption":"is there light on
+it?","name":"light"}],"description":"All the ads spots in
+paris","title":"Ads spots"}
+
+

Validation? Yes, you're completely right: we need validation for this. Because +in this current state, anyone can just insert whatever data they want into this +system, which could become a problem at some point.

+

Let's say we don't care who is able to publish to the DB, until we know that +what's being posted complies with a certain format. And, guess what's cool? +CouchDB provides validators. Yeah, I agree, it's somewhat exhausting to realize +that we have all this for free, but, heh, that's open source, dude!

+
+
+

Adding validation!

+

So, we described our format already, what we need to do is to create a couchdb +validator which is able to filter this.

+

Hmm, I don't remember how they are named (will find out in the couch +documentation), but if I remember correctly, you can hook up some javascript +functions to each POST / PUT, to check that the data inserted is correct, and +output appropriate error messages when it's not what you expected.

+

Yeah, this means writing javascript, which is cool because I wanted to re-learn +how to do javascript!

+

… train arrives to station, see you next :)

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/etre-le-meilleur.html b/drafts/etre-le-meilleur.html new file mode 100644 index 0000000..db45a17 --- /dev/null +++ b/drafts/etre-le-meilleur.html @@ -0,0 +1,154 @@ + + + + + + + + + Être (le) meilleur ? - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Être (le) meilleur ?

+ + + +
+

Quelques réfléxions sur l'élitisme et l'apprentissage.

+

🌟

+

Au fur et à mesure de mes apprentissages, il y a quelque chose que j'ai du mal à déconstruire: le mythe du meilleur. Moi qui pense qu'ensemble on va plus loin, et que la compétition n'a pas de bons jours devant elle, je me retrouve parfois dans des situations où j'ai une envie de montrer que je suis meilleur, que je sais mieux que mon voisin. Notamment lors de l'apprentissage via mes pairs.

+

Dans les domaines dans lesquels je me spécialise (fabrication de bière, informatique et programmation) je me rends compte qu'une certaine forme d'élistisme existe parfois, contrairement aux apparences de surface. Avoir une position de sage flatte mon égo.

+

Bonnes pratiques et élitisme

+

Il ne faut sûrement pas confondre les bonnes pratiques avec l'élitisme, mais parfois la frontière se fait ténue. En guise d'exemple, dans le domaine du brassage, on va critiquer les personnes qui ne contrôlent pas la température de leurs fermentations alors qu'il s'agit probablement de leur apprentissage personnel. Contrôler cette température est une bonne pratique, qui constitue deux groupes: ceux qui savent et ceux qui ne savent pas.

+

Ceux qui savent vont alors expliquer à ceux qui apprennent, et ceux qui apprennent vont être contents d'apprendre. Il est à mon avis important de garder une posture d'apprenant alors même qu'on a des choses à transmettre. Que faut-il alors faire ? Dois-je garder du recul sur mes avis, ou dois-je les formuler comme étant des avis personnels, a prendre avec des pincettes ?

+

Connaître ses limites

+

Rester dans une position de sachant semble nous pousser à des comportements de fermeture d'esprit. Ce qui caractérise la sagesse est la facultée à se remettre en question. Mais quid des fausses véritées et des avis de surface, de ce que l'on croit connaître ?

+

Peut-être que la solution est de connaître ses limites, ou en tout cas de les rechercher et de reconnaître les zones de flou. Personne n'est un expert de tout !

+ Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/fermentation-en-futs.html b/drafts/fermentation-en-futs.html new file mode 100644 index 0000000..dd6088e --- /dev/null +++ b/drafts/fermentation-en-futs.html @@ -0,0 +1,153 @@ + + + + + + + + + Fermentation en fûts - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Fermentation en fûts

+ + + +
+

🌟

+

Ça fait quelques temps que je brasse, et je lis de plus en plus de ressources sur le sujet. Je pense commencer à maîtriser quelques concepts clés derrière la fabrication de bière, mais je me trouve assez mauvais pour ce qui est de mettre en pratique de manière simple et concise ces apprentissages.

+

Récemment, j'ai fait le choix de faire une petite brasserie de 6-7L. L'idée est de pouvoir brasser des petits batchs, dans ma cuisine, sans prendre trop de risques en terme d'ingrédients. Je me suis donc équipé de petites dame-jeanne de 5.5L. Elles rentrent dans mon frigo et servent à faire la fermentation. Le verre est simple à nettoyer. C'est parfait.

+

Je me disais que c'était l'occasion de faire un petit retour sur cet équipement, et sur ce procédé.

+
    +
  • La tête est assez petite, et il est donc assez difficile de faire rentrer des sacs de houblons par exemple. +je trouve que l'embouteillage est souvent difficile,
  • +
+

e me retrouve souvent avec des

+ Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/hype.html b/drafts/hype.html new file mode 100644 index 0000000..fa30718 --- /dev/null +++ b/drafts/hype.html @@ -0,0 +1,153 @@ + + + + + + + + + Hype - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Hype

+ + + +
+

Hype et Marketing

+

🌟

+

Pendant longtemps, j'ai refusé d'avoir un compte Facebook. +Pour des raisons éthiques de propriété des données, parce que l'idée d'avoir une entreprise géante qui fait de nos inter-relations un profit me fait blêmir.

+

Depuis, ce sont toujours des pratiques qui me débectent mais j'ai mis un peu de poison dans mon élixir, tant et si bien que j'ai depuis quelques mois un compte au grand F bleu.

+

Je suis surpris de voir tout ce qui s'y passe. J'ai l'impression de découvrir le dessous de l'iceberg: beaucoup de communautées utilisent ce média pour communiquer, et j'y trouve beaucoup d'informations que j'avais de la peine à trouver ailleurs.

+

Je loupais alors toute une partie de la problématique: ce qui fait qu'un réseau social est ce qu'il est. Le fait que Facebook semble être un terreau propice au marketing. De plus en plus d'entreprises l'utilisent pour faire parler de leurs produits. On mélange alors la partie personnelle avec la partie entrepreneuriale.

+

Dans le milieu de la fabrication de bière, je me suis retrouvé à toujours voir ce que font mes collègues, tout ce qu'ils font de plus génial les uns que les autres. Franchement, ça me renvoie pas mal l'impression que je suis un gros naze.

+

Le souci, c'est que je me retrouve coincé dans une position qui nécessite de moi que je fasse parler de mon entreprise, que je cherche à

+ Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/le-mail-doit-il-mourir.html b/drafts/le-mail-doit-il-mourir.html new file mode 100644 index 0000000..2463166 --- /dev/null +++ b/drafts/le-mail-doit-il-mourir.html @@ -0,0 +1,240 @@ + + + + + + + + + Le mail doit-il mourir ? - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

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 ?

+

🌟

+

J'utilise quotidiennent le protocole email, tant bien que mal, tout en sachant +que l'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 +messages.

+

Et même si j'arrive à convaincre certains de mes proches à installer PGP, 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 tous.

+

Ce problème est lié directement au protocole email: il est necessaire de +faire fuiter les metadonnées (au moins le destinataire) pour avoir un protocole +mail fonctionnel.

+

Le mail réponds à un besoin de communication asynchrone qui permet des +conversations plus réfléchies qu'un simple chat (miaou). Il est tout à fait +possible d'utiliser certaines technologies existantes afin de constuire le +futur de l'email, pour lequel:

+
    +
  • Les méta-données seraient chiffrées — Il n'est pas possible de savoir qui +communique avec qui, et quand;
  • +
  • Le chiffrement serait fort et protégé d'une phrase de passe;
  • +
  • La fuite d'une clé de chiffrement utilisée dans un échange ne permette pas de +déchiffrer l'ensemble des échanges (forward secrecy);
  • +
  • Il ne soit pas possible de réutiliser les données comme preuve pour +incriminer l'emmeteur du message (deniability);
  • +
+

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 demonstration du concept en question.

+

Voici un tableau de certaines des solutions existantes. Je n'ai volontairement +pas repris l'ensemble des outils existants, et indiqué quelques points de +comparaisons qui me semblaient utiles (Nombre de developeurs, date du dernier +commit).

+ ++++++ + + + + + + + + + + + + + + + + + + + + + + + + +
ProjectPondSignalPGP
Forward secrecy   
Meta-data encryption   
Deniability   
+
+

Axolotl v2

+

Un des champions actuels (depuis quelques années déjà) dans +Hi,

+

As a prelude, let me say that I've been following this mailing-list since over +a year now and I've learned a bunch of interesting things, so thanks to you +all.

+

If I understand correctly, the email protocol is badly broken, even if used +with PGP on top of it, mainly because metadata are leaking, by design (at least +for the emitters and recipients of the messages) and that it doesn't propose +forward secrecy.

+

I'm looking for a protocol that allows:

+
    +
  • Asynchronous messaging;
  • +
  • Backup-able messages;
  • +
  • Forward secrecy;
  • +
  • Hiding of traffic information;
  • +
+

This looks a lot like Pond [0], with the twist that messages are expiring in +Pond (and I would like them not to). But, I could leave with expiration of +messages, if only Pond was maintained and still worked on actively.

+

So here are multiple questions:

+
    +
  • The ideas behind Pond looks great. Do you have any
  • +
+

[0] https://pond.imperialviolet.org/

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/loutil-roi.html b/drafts/loutil-roi.html new file mode 100644 index 0000000..9cf6b57 --- /dev/null +++ b/drafts/loutil-roi.html @@ -0,0 +1,196 @@ + + + + + + + + + L'outil roi - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

L'outil roi

+ + + +
+

🌟

+

Clochix publie de temps en temps de bons billets sur son carnet, un de ceux là +parle de nos outils, et de la relation que l'on entretien avec eux.

+

Ça fait longtemps que j'ai ce billet en cours de rédaction, et que ma réfléxion +sur le sujet n'est pas aboutie. J'ai écris un billet il y à un an et demi sur +le sujet sans jamais le publier.

+

Je me rends compte que je n'ai pas vraiment la même utilisation des outils +informatiques que des outils autres. Sur mon ordinateur, je souhaite toujours +avoir le "petit truc" qui fait que je vais plus vite. Je suis friand de ces +astuces. J'utilise "vim" pour rédiger mes notes, j'ai en tête bon nombres de +raccourcis qui me permettent d'aller plus vite, etc.

+

Au final, ce n'est pas un mal, mais à toujours vouloir faire plus, je me +retrouve à ne plus savoir ou donner de la tête.

+

Pour être honête, travailler à distance est assez compliqué. compliqué parce +qu'il faut à la fois être présent sur les canaux de discussion et etre capable +de travailler sur les projets qui nous interessent. Un vrai mythe.

+

Parce qu'en pratique, je n'arrive que peu à faire deux choses en même temps. +J'ai essayé à plusieurs reprises la technique du pomodoro, qui oblige à être +concentré sur une tache durant 25 minutes, en évitant les distractions; mais +cette découpe en tranches de 25 minutes me perturbe et souvent casse mon +rythme. En fait, ça convient à certains types de taches et pas à d'autres. Par +exemple ça ne convient pas du tout (en mon sens) pour un travail de +documentation (lecture), alors que ça convient plus pour un travail d'écriture.

+

Au final, je tente de

+

Mes outils me grignottent. J'essaye d'avoir toujours l'outil le plus performant +pour la tache. Que ça soit un outil informatique, ou un outil

+

Essayons d'avoir des outils toujours plus +performants, pour être efficace

+

le dernier en +date parle de l'homme et de ses outils. Il y parle de vim, un éditeur de texte, +mais il est possible d'étendre cette reflexion à bon nombre d'outils que nous +utilisons.

+

Des outils qui nous permettent d'aller plus vite, d'être plus efficaces, +performants, productifs.

+

J'utilise aussi vim; et je passe un temps considérable à apprendre (d'une +manière générale) comment mes outils fonctionnent, et comment faire en sorte +qu'ils correspondent à mes usages au mieux possible.

+

Premièrement, parce que c'est interessant. Intellectuellement parlant cela +releve de l'apprentissage, et par curiosité, j'aime comprendre comment les +choses marchent. Mais, remettant en perspective ces outils, on peux se poser +la question de leur legitimité: Je sais parfaitement me servir d'un ordinateur. +Pas que j'en connaisse tous les recoins, mais qu'importe. Quel est l'intérêt de +ces outils ? À quoi bon savoir se servir de ses 10 doigts sur un clavier si +c'est pour ne faire que des outils qui font progresser "l'état de la science" +? C'est certes fort interessant, mais il n'en reste pas moins peu utile in +fine.

+

Ce que j'attende d'un outil, c'est qu'il me permette de résoudre des problèmes +le plus rapidement et le plus facilement possible. Je ne veux pas défendre

+

J'ai envie de dire "peu importe" l'outil (pourvu qu'on ait la réalisation)

+

Et hop, on retombe sur cette séparation du faire et du penser, sans même +sans rendre compte.

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/mozilla-the-sagrada-token-server.html b/drafts/mozilla-the-sagrada-token-server.html new file mode 100644 index 0000000..ffb5e0c --- /dev/null +++ b/drafts/mozilla-the-sagrada-token-server.html @@ -0,0 +1,222 @@ + + + + + + + + + Mozilla - The sagrada token server - Carnets Web + + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Mozilla - The sagrada token server

+ + + +
+

🌟

+

Since I started, back in december, we started a new project on the services +team, which aims to bring a central authentication point on our server side. +This had been motivated by the fact that we are switching our services +authentication mechanism from basic HTTP auth to browserid (this was basically +for sync in the first place, and now for AITC, a.k.a Market Place APIs).

+
    +
  • A Token Server ?
  • +
  • Services architecture (server / nodes)
  • +
  • MAC auth
  • +
  • Crypto / Signing +- HKDF +- Signing the tokens +- Parsing browserid assertions
  • +
  • Resources
  • +
+
+

A token server ?

+

So, we don't want to be tied to any authentication mean on our platform. The +best way to accomplish this is to chose one and to provide a way to map all the +potential authentication means to the chosen one.

+

In addition to trade a browserid assertion for another authentication token, +the mission of the token server is to retrieve the node allocation of a +particular user, and eventually assign it to a node.

+

To resume, we take any authentication scheme (browserid for now) and +trade it for another one we can use for all of our services. This has several +advantages:

+
    +
  • We don't need to check the browserid assertion at each request. This avoids +doing crypto at each request.
  • +
  • As said, we are able to deal with different authentication schemes. If we +want to use openid, we just need to add support for it on one location
  • +
  • The node allocation is done anyways (the user need to know wich node it is +assigned to) so it doesn't add an extra call for this.
  • +
+
+
+

Our architecture

+

I'm talking about nodes, users and services. Let's clarifiy a bit all this. +Because at the services team, we mostly care about being able to scale our +infrastructures without (too much) pain, we try to avoid SPOFs (Single Point Of +Failure) of any sort. For this purpose we expose at the authentication layer +information about the node that need to be retrieved by the clients.

+

What? clients? Okay, here is what the authentication looks like:

+
+User-Agent              Token Server                Node
+    |                        |                       |
+    |     <bid assertion>    |                       |
+    |----------------------->|                       |
+    |                        |                       |
+    |<token + userid + node> |                       |
+    |<-----------------------|                       |
+    |                        |                       |
+    |                <service-data + token>          |
+    |----------------------------------------------->|
+
+

In HTTP terms, looks like this, the user agent (client) gives a browserid +assertion and receives back information about the service it should deal with

+
+> HTTP POST http://token.services.mozilla.org/1.0/<app>/<app-version>
+> Data: # some authentication information (browserid assertion in our case)
+< Header: 200 OK
+< Data: "{'id': token, 'key': secret, 'uid': uid, 'api_endpoint': api_endpoint}"
+
+

(This is an hand crafted request/response flow)

+

We don't bother about the signing and crypto details in here as it is explained +in a later section, but basically, we asked for a node, with a specific +browserid assertions and now we have an api_endpoint to send our requests +against, along with the token.

+
+
+

Crypto details

+

All the flow is explained in our documentation, for the token server

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/mozillas-weekly-update-1.html b/drafts/mozillas-weekly-update-1.html new file mode 100644 index 0000000..dcf3f13 --- /dev/null +++ b/drafts/mozillas-weekly-update-1.html @@ -0,0 +1,208 @@ + + + + + + + + + Mozilla's weekly update #1 - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Mozilla's weekly update #1

+ + + +
+

🌟

+

My day-to-day work is changing a lot these days, as I'm working on different +tools and working across different teams. I thought it could be useful to have +a place to put updates weekly about what's going-on. This can be extra useful +for folks that are not on the same timezone I am (I'm looking at you, +California), so let's try this.

+

I'm not used to post regularly, but I will try to update the blog with an entry +each week, if there is something interesting to say.

+
+

Circus

+

As you may know, last week we had a sprint about Circus at PyconFR, we now have +a bunch of folks interested by the project now, and some activity on our irc +channel (#mozilla-circus on freenode).

+

I've written a more comprehensive wrap-up about this sprint, so have a look at +it if you're interested!

+
+
+

Vaurien

+

Vaurien is a TCP proxy which can be useful for our load-testing. its goal is to +sometimes let the traffic go trough, sometimes play a bit with it (add delays, +timeouts, close the socket etc) to check how the stack is behaving when under +pressure.

+

The code isn't used to test our services yet but we have something interesting +to show: http://github.com/mozilla-services/vaurien/

+

I will not explain the specifics here, I've tried to make the README explicit enough.

+
+
+

Marteau

+

Marteau is the tool we're +using to throw load-test to our services, to check that they're able to handle +it. It's basically a frontend to Funkload. Tarek worked on adding real-time +feedback from the nodes (when in distributed mode, Funkload clients are +deployed on some nodes and send traffic to the service from there), and I am +working on making this available on the web interface. This means playing a bit +with web-sockets and javascript, yay.

+
+
+

Marketplace packaging

+

Currently, the application behind market place, Zamboni uses a non-standard mechanism to deal +with its dependencies. A vendor folder contains the packages themselves, in +the form of git submodules. This comes with some drawbacks such as the fact +that it's not easy to upgrade dependencies etc, and very long updates of the +repository, into other things.

+

We were also dependant on github to deploy Marketplace, which isn't reliable at +all, especially when you know that github was down last week, for instance. We +now have a local PyPI mirror at Mozilla, and we use it to avoid reaching the +internet for something else than our code.

+

This also means that we need to pull all the dependencies out of this vendor +folder, and rely on PyPI packages when they are up to date. Then we will be +able to directly use pip to deal with dependency management and packaging.

+
+
+

Splitting up the Marketplace

+

Zamboni is currently one big django project. This led to something quite hard +to understand and hard to deal with., especially for newcomers. Also, it means +that all the aspects of the site are inter-connected and that you need to be +comfortable with the whole infrastructure of the project to add new features +/ fix bugs.

+

Splitting this big project into smaller chunks can allow to have something +easier to work on. We're trying to do that these days. More on this later :)

+

That's all for now, I'll try to keep you posted on all this, see you next week +:-)

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/selection-musicale.html b/drafts/selection-musicale.html new file mode 100644 index 0000000..7580a15 --- /dev/null +++ b/drafts/selection-musicale.html @@ -0,0 +1,166 @@ + + + + + + + + + Selection musicale - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Selection musicale

+ + + +
+

🌟

+

Une petite selection de mes morceaux coup de cœur du moment.

+
+

Mai

+
    +
  • Mana - Janek Gwizdala Jazz / Funk. Avec un solo de trombone d'Elio Mason excellent à 6mn et quelques.
  • +
  • The Events of December 11 - Euforquestra Reggae / Funk Oooh yeah !
  • +
  • Piece for Peace - The Skatalites Rock Steady. Parce que ça faisait trop longtemps.
  • +
  • Rock this town - Stay Cats Rockabilly
  • +
  • Hidden orchestra Électro posée
  • +
  • Extrawelt Minimal, parce que ça aide grave à se concentrer !
  • +
  • Trentemoller Minimal
  • +
+
+
+

Juin

+
    +
  • Ouriel
  • +
+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/drafts/un-crieur-public-intergalactique.html b/drafts/un-crieur-public-intergalactique.html new file mode 100644 index 0000000..ebb1703 --- /dev/null +++ b/drafts/un-crieur-public-intergalactique.html @@ -0,0 +1,165 @@ + + + + + + + + + Un crieur public intergalactique ! - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Un crieur public intergalactique !

+ + + +
+

🌟

+

+
+

Mes dames, mes sieurs, mes demoiselles, damoiseaux, vous les endormis et vous +les reveillés, rejouissez vous: Je suis un crieur, et je crie fort !

+

Réjouissez vous parce que je vous permet de passer vos messages les plus fous, +importants, personnels ou collectifs, de manière toute à fait anonyme, durant +notre cher festival.

+

Poèmes, déclarations d'amour, Réclamations, Blagues, Petites annonces… je les +prends toutes.

+

Une criée aura lieu tous les soirs sur le festival, et vous pouvez y raconter +ce que vous voulez !

+

Vous pouvez retourner à une activité normale, mais pensez à moi, et mettes vous +mots dans la boite à criée !

+

Oooooh, yeah !

+
+

C'est à peu près sur ce ton là que notre cher public du festival +intergalactique, ont pu être reçus à plusieurs reprises lors de +la soirée.

+

Le résultat était des plus impressionnant:

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/dynamically-change-your-gnome-desktop-wallpaper.html b/dynamically-change-your-gnome-desktop-wallpaper.html new file mode 100644 index 0000000..3c64e8b --- /dev/null +++ b/dynamically-change-your-gnome-desktop-wallpaper.html @@ -0,0 +1,189 @@ + + + + + + + + + Dynamically change your gnome desktop wallpaper - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Dynamically change your gnome desktop wallpaper

+ + + +
+

🌟

+

In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.

+

You can have a look to the git repository if you want: http://github.com/ametaireau/gnome-background-generator

+

Some time ago, I've made a little python script to ease that, and you can now +use it too. It's named "gnome-background-generator", and you can install it via +pip for instance.

+
$ pip install gnome-background-generator
+
+

Then, you have just to use it this way:

+
$ gnome-background-generator -p ~/Images/walls -s
+/home/alexis/Images/walls/dynamic-wallpaper.xml generated
+
+

Here is a extract of the --help:

+
$ gnome-background-generator --help
+usage: gnome-background-generator [-h] [-p PATH] [-o OUTPUT]
+                                  [-t TRANSITION_TIME] [-d DISPLAY_TIME] [-s]
+                                  [-b]
+
+A simple command line tool to generate an XML file to use for gnome
+wallpapers, to have dynamic walls
+
+optional arguments:
+  -h, --help            show this help message and exit
+  -p PATH, --path PATH  Path to look for the pictures. If no output is
+                        specified, will be used too for outputing the dynamic-
+                        wallpaper.xml file. Default value is the current
+                        directory (.)
+  -o OUTPUT, --output OUTPUT
+                        Output filename. If no filename is specified, a
+                        dynamic-wallpaper.xml file will be generated in the
+                        path containing the pictures. You can also use "-" to
+                        display the xml in the stdout.
+  -t TRANSITION_TIME, --transition-time TRANSITION_TIME
+                        Time (in seconds) transitions must last (default value
+                        is 2 seconds)
+  -d DISPLAY_TIME, --display-time DISPLAY_TIME
+                        Time (in seconds) a picture must be displayed. Default
+                        value is 900 (15mn)
+  -s, --set-background  '''try to set the background using gnome-appearance-
+                        properties
+  -b, --debug
+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/faire-moins.html b/faire-moins.html new file mode 100644 index 0000000..2af81f2 --- /dev/null +++ b/faire-moins.html @@ -0,0 +1,158 @@ + + + + + + + + + Faire moins - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Faire moins

+ + + +
+

Et retrouver le contrôle de son engagement.

+

🌟

+

L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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'occasion de contribuer à éviter notre société d'experts.

+

Le hic, c'est que trop, c'est trop. J'ai donc décidé d'arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j'ai même arreté de faire des choses que j'avais commencé à faire (par exemple de l'escalade), me libérant du temps.

+

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.

+ L'image d'illustration utilisée est un travail de Christopher proposé sous license CC BY NC 2.0. Merci ! + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/feeds/alexis-metaireau-mathieu-leplatre.atom.xml b/feeds/alexis-metaireau-mathieu-leplatre.atom.xml new file mode 100644 index 0000000..bd8e5a1 --- /dev/null +++ b/feeds/alexis-metaireau-mathieu-leplatre.atom.xml @@ -0,0 +1,154 @@ + +Carnets Web - Alexis Métaireau, Mathieu Leplatrehttps://blog.notmyidea.org/2012-02-04T00:00:00+01:00Thoughts about a form generation service, GIS enabled2012-02-04T00:00:00+01:002012-02-04T00:00:00+01:00Alexis Métaireau, Mathieu Leplatretag:blog.notmyidea.org,2012-02-04:/carto-forms.html<p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of it.</p> +<p>This idea has been stuck …</p><p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of 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've named it +<em>carto-forms</em> for now, but that's only the &quot;codename&quot;.</p> +<p>To put it shortly: what if we had a way to build forms, ala Google forms, but +with geographic information in them?</p> +<p>If you don't know Google forms, it means having an user-friendly way to build +forms and to use them to gather information from different users.</p> +<p>In my opinion, Google forms is missing two important things: first, it's not +open-source, so it's not possible to hack it or even to run it on your own +server. Second, it doesn't really know how to deal with geographic data, and +there is no way to filter the information more than in a spreadsheet.</p> +<p>I knew that <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu</a> and some folks at <a class="reference external" href="http://makina-corpus.com">Makina Corpus</a> would be interested +in this, so I started a discussion with him on IRC and we refined the details +of the project and its objectives.</p> +<p>Imagine the following:</p> +<ol class="arabic simple"> +<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) ;</li> +<li>In situ, users fill the form fields with what they see. Geo fields can be +pre-populated using device geolocation ;</li> +<li>At the end of the day, we can see a map with all user contributions seized +through this particular form ;</li> +<li>If relevant, a script could eventually import the resulting dataset and +publish/merge with OpenStreetMap.</li> +</ol> +<div class="section" id="some-use-cases"> +<h2>Some use cases</h2> +<p>I can see some use cases for this. The first one is a collaborative map, with +facet filtering. Let's draw a potential user flow:</p> +<ul> +<li><p class="first">An &quot;administrator&quot; goes to the website and creates a form to list all the +alternative-related events. He creates the following fields:</p> +<ul class="simple"> +<li>Name: a plain text field containing the name of the event.</li> +<li>Category: the category of the event. Can be a finite list.</li> +<li>Location: The location of the event. It could be provided by selecting a +point on a map or by typing an address.</li> +<li>Date: the date of the event (a datepicker could do the 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 etc)</p> +</li> +<li><p class="first">Once finished, the form is generated and the user gets an url (say +<a class="reference external" href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>) for it.</p> +</li> +<li><p class="first">REST APIs allow third parties to get the form description and to +push/edit/get information from there.</p> +</li> +<li><p class="first">He can communicate the address in any way he wants to his community so they +can go to the page and add information to it.</p> +</li> +<li><p class="first">Then, it is possible to filter the results per location / date or category. +This can be done via API calls (useful for third parties) or via a nice +interface in the browser.</p> +</li> +</ul> +<p>So, as you may have noticed, this would allow us to create interactive maps really +easily. It's almost just a matter of some clicks to the users. If we also come +up with a nice Web API for this, we could do server-side validation and build +even phone applications 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 clients.</p> +<p>As mentioned before, the idea of a simple tool to support collaborative mapping +fullfils a recurring necessity !</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'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 class="reference external" href="http://fixmystreet.ca">http://fixmystreet.ca</a>), +geocaching, trajectories (e.g hiking, runners, cyclists)...</p> +<p>Here are some other examples of where <em>carto-forms</em> could be useful:</p> +<div class="section" id="simple-gis-storage-backend"> +<h3>Simple GIS storage backend</h3> +<p>Let's say you are a mobile developer, you don't want to bother with PostGIS +nor write a custom and insecure code to insert and retrieve your GIS data! You +need carto-forms! A simple API helps you design your models/forms and the +same API allows you to CRUD and query your data. Thus, you only need to focus +on your application, not on how GIS data will be handled.</p> +<p>We make a distinction between storage and widgets.</p> +<p>Besides, if you are a django / drupal / plomino... maintainer : you +can develop a module to &quot;plug&quot; your models (content types) and UI to carto-forms! +Carto forms are then exposed to your backoffice users (ex: drupal admin UI, django +adminsite), and likewise you can write your own HTML widgets that consume datasets +in frontend views (facets in JSON/XML, and map data in GeoJSON).</p> +</div> +<div class="section" id="visualization-tool"> +<h3>Visualization tool</h3> +<p>Since data submission can be done programmatically using the API, you could use Carto-forms +results page as a visualization 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're in +front of a decision support system!</p> +<p>Of course, filtered raw data can be downloaded (GeoJSON, XML) and a permalink allows to +share the page with the state of the filters and the zoom/location of the map.</p> +</div> +<div class="section" id="generic-forms-service"> +<h3>Generic forms service</h3> +<p>If you want to generate a configuration file (or whatever, email messages, ...), +you will need a form and a template to inlay user submitted values and get the result.</p> +<p>A form service would be really useful to create forms programmatically and retrieve +cleaned and validated input 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 result).</p> +<p>Note that for this use-case, there is no specific need of GIS data nor storage of records +for further retrieval.</p> +</div> +</div> +<div class="section" id="what-s-out-in-the-wild-already"> +<h2>What's out in the wild already?</h2> +<p>Of course, there is Google forms, which allows you to do these kind of things, +but it's closed and not exactly what we are describing here.</p> +<p>We've discovered the interesting <a class="reference external" 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't handle APIs and +geolocation information.</p> +<p>The idea of <a class="reference external" href="http://thoth.io">http://thoth.io</a> is very attractive : an extremely simple web API to store +and retrieve data. In addition, <em>carto-forms</em> would do datatype validation and have +basic GIS fields (point, line, polygon).</p> +<p><a class="reference external" href="http://mapbox.com">http://mapbox.com</a> also did an awesome work on cartography, but didn't take into +account the form aspect we're leveraging here.</p> +</div> +<div class="section" id="so-let-s-get-it-real"> +<h2>So… Let's get it real!</h2> +<p>As you may have understood, this isn't a really complicated problem. We have +been sometimes chatting about that with Mathieu about what we would need and +how we could achieve this.</p> +<p>We can probably come with an elegant solution without too much pain. Mathieu is +used to work with GIS systems (which is really cool because I'm not at all) and +knows his subject, so that's an opportunity to learn ;-)</p> +<p>We will be at <a class="reference external" 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 join!</p> +<p>We don'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 welcome!</p> +<p>Here is the etherpad document we worked on so far: +<a class="reference external" href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don't hesitate to add your thoughts and edit +it, that's what it's made for!</p> +<p>Thanks to <a class="reference external" href="http://sneakernet.fr/">Arnaud</a> and <a class="reference external" href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo fixing.</p> +</div> + \ No newline at end of file diff --git a/feeds/alexis-metaireau-mathieu-leplatre.rss.xml b/feeds/alexis-metaireau-mathieu-leplatre.rss.xml new file mode 100644 index 0000000..22a57b3 --- /dev/null +++ b/feeds/alexis-metaireau-mathieu-leplatre.rss.xml @@ -0,0 +1,6 @@ + +Carnets Web - Alexis Métaireau, Mathieu Leplatrehttps://blog.notmyidea.org/Sat, 04 Feb 2012 00:00:00 +0100Thoughts about a form generation service, GIS enabledhttps://blog.notmyidea.org/carto-forms.html<p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of it.</p> +<p>This idea has been stuck …</p>Alexis Métaireau, Mathieu LeplatreSat, 04 Feb 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-02-04:/carto-forms.htmlGISforms \ No newline at end of file diff --git a/feeds/alexis-metaireau.atom.xml b/feeds/alexis-metaireau.atom.xml new file mode 100644 index 0000000..94bfb4b --- /dev/null +++ b/feeds/alexis-metaireau.atom.xml @@ -0,0 +1,6906 @@ + +Carnets Web - Alexis Métaireauhttps://blog.notmyidea.org/2019-07-03T00:00:00+02:00Ours2019-07-03T00:00:00+02:002019-07-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-07-03:/ours.html<p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>De manière plus large, est-ce normal …</p><p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>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 ?</p> +<p>Suis-je en train de devenir un ours ?</p>velotaf2019-06-27T00:00:00+02:002019-06-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-27:/velotaf.html<p>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 …</p><p>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 personelle et le taf à la brasserie.</p>Un espace des communs Rennais ?2019-06-26T00:00:00+02:002019-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-26:/un-espace-des-communs-rennais.html<p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le …</p><p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le sujet des <em>communs</em>; +2. Monter une structure Rennaise pour proposer de l’hébergement de services web.</p> +<p>Élaborons un peu...</p> +<h2>1. Un espace pour fédérer</h2> +<p>L'idée qui à été développée est celle d'avoir un espace (un ou des lieux, à différents moments dans l'année) pour que les rencontres entre les projets <em>du libre</em> à Rennes puissent se dérouler. Le constat est qu'il existe différentes structures actuellement en place, mais que a) certaines personnes ne se retrouvent pas dans ces espaces et b) la porosité entre ces différents groupes est assez faible.</p> +<p>Pour l'instant pas d'idée précise de ce qui pourrait être proposé, mais quelques pistes ont été évoquées. l'envie est de faire un document d'intention et de proposer à d'autres de rejoindre le collectif en création.</p> +<h3>Fréquence</h3> +<p>Deux pistes ont été évoquées:</p> +<ul> +<li> +<p><strong>Faire des rencontres suffisamment espacées les unes des autres</strong>, pour que leur caractère « exceptionnel » soit une force. Si la fréquence des réunions est assez faible, alors l'incitation pour y prendre part est peut-être plus grande ?</p> +</li> +<li> +<p>ou au contraire, <strong>avoir des rencontres avec une fréquence assez forte</strong>, pour qu'en cas d'incapacité à participer il n'y ait pas trop longtemps à attendre ?</p> +</li> +</ul> +<h3>Charte éthique</h3> +<p>Le fait d'avoir un <em>code de conduite</em> pour de tels évènements à été discuté, un des arguments évoqués étant le fait qu'un tel code n'est pas considéré nécessaire par certaines personnes, puisque les règles évoquées tiennent du bon sens.</p> +<p>Il a été précisé que l'établissement de ce type de document a pour objectif de: +- Faire que des minorités et/ou oppressés se sentent protégés et considérés, et donc bienvenues à ce type d'évènements; +- En cas de situations considérées comme problématiques, des personnes référentes soient désignées pour aider à leur résolution</p> +<h3>Gouvernance</h3> +<p>Le sujet de la gouvernance à été également abordé : pour avoir de tels rendez-vous, peu importe leur nature, il faut que ceux-cis soient organisés. La possibilité d'avoir des organisat·rices·eurs· tournantes à été proposé.</p> +<p>Pour :</p> +<ul> +<li>Cela permet de ne pas reposer uniquement sur quelques personnes;</li> +<li>Faire des fiches explicatives qui permettent à tou·te·s de s'impliquer</li> +</ul> +<p>Contre : </p> +<ul> +<li>Quand tout le monde est responsable, personne ne l'est.</li> +</ul> +<p>Peut-être que des solutions intermédiaires sont à trouver, en désignant d'une fois sur l'autre les personnes qui s’occupent du prochain rendez-vous, par exemple.</p> +<h2>2. Hébergement de services Web</h2> +<p>On a discuté très rapidement de la possibilité de monter une structure pour faire de l’hébergement de services web sur Rennes. Le sujet n'a pas été vraiment développé, mais la question de la relation entre avoir un espace pour fédérer (le 1.) et être un hébergeur de service (le 2.) a été rapidement abordé.</p> +<p>Faut-il avoir une seule et même structure / groupe de personnes pour ces deux projets ? Dans le cas ou l'un s'arrête, entraînerait-il l'autre dans sa « chute » ? Est-il logique de lier les deux ?</p> +<h2>Et donc ?</h2> +<p>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 :-)</p>De Mozilla à la Brasserie du Vieux Singe2018-05-27T00:00:00+02:002018-05-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2018-05-27:/de-mozilla-a-la-brasserie-du-vieux-singe.html<p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que …</em></p><p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que d'autres ont pris plus de place que prévu. J'avais donc envie de reprendre mes notes pour les transformer en billet de blog, question d'élaborer sur le sujet.</em></p> +<hr> +<p>J'ai toujours été motivé par mes passions. Quand j'ai commencé à travailler professionnellement, je me suis rendu compte que même si je faisais quasiment la même chose qu'auparavant, ça n'avait plus le même goût. J'étais maintenant <em>obligé</em> de le faire, et je n'en tirais pas le même plaisir.</p> +<p>Quand j'étais plus jeune au lycée j'écrivais des programmes en <em>Visual Basic</em> que je partageais en ligne sur mon site en <code>.free.fr</code>. Programmes que probablement personne n'a lu, mais l'intention était bel et bien celle de partager mes créations, et d'échanger à leur propos.</p> +<p>Cette culture du partage — celle du logiciel libre — est celle qui m'anime.</p> +<p>Quelques années plus tard, je découvre le langage de programmation Python, et avec lui toute une communauté, mue par ces mêmes valeurs de partage et d'amélioration de nos pratiques. Puis je rencontre le Logiciel Libre, avec l'écriture d'un programme (<a href="https://getpelican.com">pelican</a>) qui reste encore largement utilisé aujourd'hui. Autant dire que c'est une bonne claque que de voir des inconnus contribuer à un bout de code qu'eux aussi jugent utile.</p> +<p>À la fin de mes études, alors que je reste passionné par le développement logiciel, je ne veux ni travailler pour l'industrie, ni pour la finance. Je songe même déjà à cette époque à changer de métier (avant même d'avoir commencé !). Coup de bol, une structure qui m'est chère cherche des développeurs Python: Mozilla. Sans trop y croire, je passe une série d'entretiens qui se déroulent bien (!) et je commence quelques mois plus tard à travailler pour cette organisation incroyable, porteuse d'espoir et de toute une symbolique pour moi.</p> +<p>Je bosse sur du Logiciel Libre, en Python, en télétravail parfois, avec une bonne paie, sans parler du côté prestigieux. Grisant.</p> +<p>Mais au fur et à mesure je découvre l'envers du décors: une méritocratie ancrée et assumée, une hiérarchie de plus en plus importante, menant à une lourdeur administrative assez présente. À ajouter à la barrière de la langue, et aux différences culturelles. Finalement tout n'est pas rose ici.</p> +<p>Je décide alors de (je pense) faire un de mes meilleurs choix de vie à ce jour: passer aux 4/5èmes. Je récupère tous mes vendredis. Des weekends de 3 jours, toutes les semaines. Un espace précieux pour me reposer, et pour rêver un peu.</p> +<p>C'est à ce moment que Fred, un ami de longue date, en revenant du Québec (ou les brasseries sont légion), me propose de faire de la bière avec lui. Moi qui ne savais même pas qu'il était <em>possible</em> de faire de la bière. On tente donc l'expérience, et nos premières expériences sont des journées bien <em>funky</em>, à faire toutes les erreurs possibles.</p> +<p>Peu à peu, on découvre un nouveau monde: celui des brasseurs amateurs. De nouvelles compétences sont nécessaires, de la physique à la biochimie. On se met à rencontrer des professionnels, des passionnés, à échanger sur les forums. On se forme, petit à petit. Tout comme il y a la communauté des gens qui font du Python, il y a la communauté des gens qui font de la bière. Pas encore autant fédérés, ça semble balbutiant alors mais la passion elle est bien présente.</p> +<p>Tout comme le monde du Logiciel Libre est constitué autour d'un ennemi commun (les GAFA), le monde de la bière artisanale à la sien: les brasseries industrielles, qui uniformisent les goûts et les processus.</p> +<p>Je continue en parallèle mon travail chez Mozilla, pendant 4 années. Et puis un jour, une annonce d'arrêt d'un projet sur lequel je travaillais me fait réaliser que cette situation m'épuise. La fameuse goutte de trop.</p> +<p>Je décide alors de partir, de faire une pause, sans trop savoir ce que l'avenir me réserve. Une petite période de blanc de deux mois. Le regard des autres est parfois culpabilisant. Mes parents me demandent si « je ne veux pas attendre encore un peu ». La transition me fait peur, mais je choisis quand même de troquer mon confort matériel pour de la cohérence.</p> +<p>Petit à petit, l'idée de monter ce qui est maintenant devenu <a href="https://www.vieuxsinge.com">La Brasserie du Vieux Singe</a> se pose en évidence. Mais monter une brasserie ce n'est pas uniquement faire de la bière: c'est se mettre d'accord sur des valeurs, trouver comment les défendre, monter un projet pour, et tenir le cap.</p> +<p>Quelques mois après mon départ, on se retrouve donc à parler de ces valeurs de partage, de documentation, de goût. De gouvernance et de collaboration aussi. +Dans nos pratiques courantes, on décide d'intégrer du temps pour documenter la vie de la brasserie.</p> +<p>À titre d'exemple, nos étiquettes contiennent l'ensemble des ingrédients que l'on utilise de la manière la plus détaillée possible. On travaille aussi sur un projet de laveuse de fûts, qui sera publié sous licence libre, avec l'idée de pouvoir, petit à petit, constituer un ensemble d'outils utiles à tous les brasseurs, et peut être même réussir à favoriser les échanges entre toutes ces personnes.</p> +<p>Nous sommes deux brasseurs, deux chefs d'entreprise, mais aussi deux développeurs. Nos compétences de développeurs nous sont utiles quotidiennement: pour notre laveuse de fûts, pour nos créations de recettes (j'ai découvert la puissance des tableurs !), pour notre site de préventes, notre site Web, nos outils du quotidien. On se rend compte qu'il s'agit de compétences précieuses.</p> +<p>Mais monter une entreprise, c'est aussi assumer une partie administrative. Vous vous rappelez cette histoire de réactions face aux activités subordonnées ? Et bien quand je fais mes déclarations aux douanes, ce n'est pas de gaîté de cœur. Je sais par contre pourquoi je le fais: ce sont les règles du jeu. Des obligations, mais peut-être moins de coercition. J'y trouve plus de sens.</p> +<p>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.</p> +<p>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. </p>Groupement d'achats & partage d'expérience2018-03-03T00:00:00+01:002018-03-03T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.html<p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers …</p><p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers et une 60aine de 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'expérience et quelques astuces / outils, au cas où l'envie vous prenne à vous aussi :)</p> +<h1>Organisation</h1> +<p>On organise environs trois ou quatre distributions par an. Le <em>modus operandi</em> est le suivant:</p> +<ul> +<li>chaque product·eur·rice à un·e référent·e, qui s'occupe de faire le lien;</li> +<li>une personne est désignée pour coordonner la distribution;</li> +<li>4 semaines avant la distribution, les référent·e·s mettent à jour les prix / produits dans le tableau de commandes;·e·</li> +<li>3 semaines avant la distribution, les commandes sont ouvertes;</li> +<li>2 semaines avant la distribution, les commandes sont closes;</li> +<li>Les référent·e·s ont ensuite deux semaines pour récupérer les commandes pour la distribution</li> +</ul> +<h1>Quels produits ?</h1> +<p>On essaye d'avoir uniquement des produits qui se conservent (on a également quelques autres produits plus frais, mais avec d'autres modalités).</p> +<p>Entre autres: bières, légumes secs, conserves, jus, miel, pâtes, semoule, café, vinaigres, pommes de terre, oignons, huiles, 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'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'est pas animé par la même éthique !).</p> +<h1>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'attendre la date de la distribution pour l'encaissement. La plupart des producteurs acceptent d'être payés sous quinzaine.</p> +<p>Le jour de la distribution, tout le monde apporte son chéquier. Nous avons mis +en place une moulinette qui s'occupe de faire la répartition des chèques automatiquement, chaque membre se retrouve à faire en moyenne un ou deux chèques.</p> +<p>Chaque référent·e est ainsi remboursé·e de la somme avancée, et chaque +membre du groupement d'achat paye ce qu'il doit payer. Nous n'avons +volontairement pas de structure juridique et pas de compte en banque. Les +paiements s'effectuent directement entre nous.</p> +<h1>Transports</h1> +<p>Chaque référent·e commande les produits, puis ensuite s'occupe de les rapatrier. À Rennes, on a la chance d'avoir pas mal de producteurs aux alentours, donc c'est assez simple.</p> +<p>Le mieux est de ramener les produits juste un peu avant la distribution au lieu de distribution, ça permet d'éviter de les stocker trop longtemps, et d'éviter aux producteurs d'attendre trop longtemps avant d'encaisser les chèques.</p> +<p>Pour les grosses commandes, les voitures se remplissent bien, mais ma petite Clio suffit, que ce soit dit !</p> +<h1>La distribution</h1> +<p>Un peu en amont de la distribution, il faut organiser l'espace. Des tas par membre sont constitués pour faciliter les choses le jour de la 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 pour:</p> +<ul> +<li>discuter de la date de la prochaine distribution;</li> +<li>trouver une nouvelle personne pour la coordonner;</li> +<li>discuter de nouveaux produits;</li> +<li>refaire le monde;</li> +<li>changer de référents pour les producteurs.</li> +</ul> +<p>Et c'est reparti pour un tour ;)</p> +<h1>Nos outils</h1> +<p>On utilise un tableur en ligne pour partager les prix et prendre les commandes. On a essayé d'utiliser <em>ethercalc</em> au début mais ça ne fonctionnait pas pour nous à l'époque (trop de petits bugs). On a donc préféré utiliser Google docs (ouch).</p> +<p>Il est d'ailleurs possible d'y intégrer de nouvelles fonctionnalités assez facilement, du coup Fred et Rémy ont planché sur un moyen d'automatiser la répartition des chèques (qu'on faisait dans un premier temps à la main - assez péniblement).</p> +<p>Le système n'est pas parfait mais fonctionne quand même assez bien !</p> +<p>Quelques ressources, donc:</p> +<ul> +<li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des 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'en faire une copie !).</li> +</ul> +<p>Bon groupement d'achat ;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière …</p><p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c'est à dire:</p> +<ul> +<li>enregistrer une sélection de texte ainsi que son contexte: heure, site web.</li> +<li>fonctionner sur Firefox;</li> +<li>stocker mes notes à un endroit que je contrôle (ce sont mes données, après tout !)</li> +<li>rester en dehors de mon chemin: je suis en train de lire, pas en train d'organiser mes notes.</li> +<li>automatiquement partager les notes sur une page web.</li> +</ul> +<p>J'ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j'ai baptisé « Webnotes ». C'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'est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué !</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 !</p>Faire moins2018-02-19T00:00:00+01:002018-02-19T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-19:/faire-moins.html<p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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 …</p><p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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'occasion de contribuer à éviter notre société d'experts.</p> +<p>Le hic, c'est que trop, c'est trop. J'ai donc décidé d'arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j'ai même arreté de faire des choses que j'avais commencé à faire (par exemple de l'escalade), me libérant du temps.</p> +<p>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.</p> +<p>Et surtout, c'est se retrouver à contrôler son engagement.</p>NEIPA #32017-12-29T00:00:00+01:002017-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-29:/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les trouvailles des deux premières versions;</li> +<li>Hop stand de 40mn;</li> +<li>Contrôle du pH à 5.2;</li> +<li>Refroidissement dans l'évier;</li> +<li>Ajouter plus d'avoine;</li> +<li>Faire un mash out;</li> +<li>Augmenter un peu la quantité de grain.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1055 (atteint) +pH: 5.2 (5.4 mesuré)</p> +<h2>Grains:</h2> +<ul> +<li>75% de Pale Ale</li> +<li>12.5% de blé</li> +<li>12.5% flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Mosaic (Hop Stand 40mn)</li> +<li>2g/L Citra (Hop Stand 40mn)</li> +<li>4g/L Citra à cru (en deux fois)</li> +<li>4g/L Mosaic à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li> +<h2>Gypse: 1g</h2> +<dl> +<dd>1.8g (=4.05ml)</dd> +</dl> +</li> +<li>Acide lactique: 0.4ml</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>68°C durant 40mn;</li> +<li>75°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>GigaYeast «Vermont Ale». Le nombre de cellules n'est pas indiqué sur le packaging, ni en ligne.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>12h50: empâtage à 68°C</li> +<li>pH = 5.5. Ajout de 0.2 d'acide.</li> +<li>Pas mal de mesures du pH:<ul> +<li>5.2@23°C (13h05)</li> +<li>5.4@18°C (13h05)</li> +<li>5.2@27°C (13h15)</li> +<li>5.3@19°C (13h20)</li> +<li>5.4@25°C (13h30)</li> +</ul> +</li> +<li>13h33: Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: OK</li> +<li>14h11: 1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>31/12/2017 - Fermentation à 20°C</li> +<li>01/01/2018 - Ajout de 12g de Citra et 12g de Mosaic après deux jours.</li> +<li>10/01/2018 - 1.040 SG = 1.008 corrigé</li> +<li>15/01/2018 - Ajout de 12g de Citra et 12g de Mosaic</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>En mettant 1.5ml d'acide, si on mesure le pH de l'eau, il est à 3.5. Ça nous à pas mal effrayé, puisque on a pas trop l'habitude de monitorer le pH. On refait: 0.4ml d'acide = pH de 4.1. Au final, cela ne semble pas utile de mesurer le pH de l'eau avant de mettre son grain.</li> +<li>Je le savais déjà, mais travailler à deux en discutant n'est pas vraiment une bonne idée: sur les opérations un peu technique, un manque de concentration se fait tout de suite ressentir.</li> +<li>BeerSmith semble proposer un outil pour calculer les modifications de pH, je devrais l'utiliser la prochaine fois.</li> +<li>Baisser le ration d'empâtage: On s'est retrouvé avec beaucoup trop d'eau de rincage, alors qu'on était sur une bière assez faible en densité.</li> +<li>Au final, ajouter l'acide au départ est problématique pour le pH de l'eau qui baisse énormement. Après quelques recherches, il semble qu'il faille faire confiance au logiciel, et prendre une seule mesure de pH à 10mn (cela devrait être stable). Le pHmetre est aussi peut-être en cause.</li> +<li>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 ?</li> +</ul>NEIPA #22017-12-18T00:00:00+01:002017-12-18T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-18:/neipa-2.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le fermenteur</li> +<li>Ne pas se laisser avoir par la baisse de température durant l'empâtage.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1060 (1050 mesuré) +pH: 5.2 (atteint)</p> +<h2>Grains:</h2> +<ul> +<li>90% Pils</li> +<li>10% Flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Wakatu (au Whirlpool)</li> +<li>2g/L Motueka (au Whirlpool)</li> +<li>4.5g/L Wakatu à cru (en deux fois)</li> +<li>2.5g/L Motueka à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li>Gypse: 0.9g</li> +<li>CaCl2: 3.4g</li> +<li>Acide lactique: Au batch précédent, j'avais mesuré 5.6, donc: ajout de +2ml d'acide (=2.4g).</li> +<li>Utilisation d'Irish Moss (2g) pour coaguler les protéines.</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>65°C durant 90mn (68°C au départ, 65 visé)</li> +<li>78°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>London Ale III.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>18h36 - empatage à 65°C</li> +<li>19h16- pH = 5.2</li> +<li>Densité 1er moût: 1070</li> +<li>Ébullition importante pour atteindre 6,2L avec la bonne densité.</li> +<li>Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: NOK</li> +<li>1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>18/12/2017 - Fermentation à 18°C</li> +<li>21/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Passage à 10°C.</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>Je change de technique, et mets l'acide lactique directement dans l'eau.</li> +<li>Je concasse moins fin mais reteste quand même l'avoine. Aucun souci de filtration (mais l'avoine n'est pas concassé).</li> +<li>1g de CaCl2 ~= 2.25ml en solution à 33%.</li> +<li>Les deux thermomètres n'affichent pas la même température. Super :(.</li> +<li>Au final, j’empâte dans une casserole pour pouvoir faire un mash-out.</li> +<li>Le pH oscille pas mal durant l'empâtage. J'ai mesuré des pH de 4.9 à certains moments, mais au final la dernière lecture est de 5.2, ce qui me semble bon.</li> +<li>Le système que j'utilise (refroidisseur en cuivre) pour refroidir mon moût n'est pas génial parce que ça mélange pas mal ce qu'on veut voir se déposer au fond de la cuve. Refroidir directement dans l'évier est vachement plus simple (c'est pratique de faire du 6L pour çà !)</li> +<li>Le teste à l'iode était positif: tout n'était pas converti. Mais à 90mn de mash, je ne crois pas pouvoir faire grand chose de plus.</li> +<li>Idée en vrac, à voir à la dégustation, mais ajouter un peu de cara pourrait être sympa.</li> +<li>L'irish moss à vraiment bien fonctionné. Je me demande si je ne devrais pas même laisser décanter un peu plus longtemps durant le whirlpool pour avoir un effet encore plus impressionnant.</li> +<li>Je trouve que l'efficacité de cette brasserie est vraiment pourrie.</li> +<li>Un peu d'eau est venue diluer le moût (DI = 1050 au lieu de 1060 souhaité)</li> +<li>Au goût, le moût à vraiment un goût qui m'assèche la gorge. Trop de modifications de l'eau ? A voir si l'effet persiste après fermentation.</li> +<li>A priori, d'après un article de Scott Janish, empâter avec de l'avoine cru ne fonctionne que si on empate haut. Ca à un impact sur l'efficacité générale (2h pour conversion totale, c'est peut-être pour ça que mon teste à l'iode était positif)</li> +<li>Sur l'avoine toujours, il faut <strong>dépasser 18%</strong> pour avoir un côté moelleux. Certains mettent jusqu'à 40% !</li> +</ul>Un club des brasseurs amateurs Rennais2017-11-06T00:00:00+01:002017-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-11-06:/un-club-des-brasseurs-amateurs-rennais.html<p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante …</p><p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante autour de la brasserie artisanale dans le coin.</p> +<p>En six mois, on est maintenant une grosse trentaine de personnes à être inscrits sur les listes et à se retrouver de temps à autres.</p> +<p>On en profite pour s'échanger des bons plans, déguster nos créations, (essayer de) faire des commandes groupées de malt, et pour se rencontrer pour papoter entre passionnés.</p> +<p>On a pas mal d'idées de trucs sympa a faire, entre autres:</p> +<ul> +<li>brasser une fois en gros puis se séparer le batch en plein de petits fermenteurs pour essayer différentes levures, différents houblons en <em>dry hop</em>, etc.</li> +<li>A la dernière rencontre, on s'est mis d'accord sur un style de bière pour se lancer un petit défi: tous brasser <a href="https://blog.notmyidea.org/larrivee-du-trouble-ou-comment-faire-des-neipa.html">une NEIPA</a> pour ensuite comparer nos résultats.</li> +</ul> +<p>Bref, c'est plutôt chouette ! Je me suis rendu compte qu'on avait quasiment aucune existence en dehors des réseaux sociaux, alors je me permet de publier ce petit bout d'article avec quelques liens…</p> +<p>Si tu es dans le coin et que tu souhaite nous rencontrer, n'hésite pas à rejoindre <a href="https://www.facebook.com/groups/899071153568179/">notre groupe de discussion Facebook</a> et notre <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">liste de diffusion mail</a>.</p> +<p>A bientôt ;)</p>L'arrivée du trouble (ou comment faire des NEIPA ?)2017-10-17T00:00:00+02:002017-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-10-17:/larrivee-du-trouble-ou-comment-faire-des-neipa.html<p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir …</p><p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir leur propre bataille qui divise au moins autant: une IPA peut elle être aussi trouble qu'une hefeweizen ? En provenance du coin Nord Est des  États-Unis, l'IPA trouble est en passe de devenir culte depuis quelques années. Mais la mode ne vient pas sans contrecoup. En fait, tout le monde y va de son opinion chez les brasseurs artisanaux. Pour ceux qui apprécient ce type d'IPA, l'apparence trouble signifie que les gorgées qui suivent seront extrèmenent riches en huiles de houblons; pour les autres, l'apparence est un affront à des principes ancestraux. Que vous les appeliez des rince-bouches, des soupes boueuses, brillantes ou horribles, ne vous faites pas de fausse idée: ces ales troubles sont là pour rester.</p> +<p>Pour commencer cette histoire, revenons un peu au début des années 1990. La scène brassicole artisanale était en train de vivre son premier boom et les nouvelles brasseries faisaient leur apparition dans tous les coins des États-Unis. Menée par Sierra Nevada Brewing Company, les American Pale Ale et les American IPA étaient en train d’émerger en tant que styles populaires parmi les amateurs de bière, pour leurs caractéristiques riches en houblon.</p> +<p>Le niveau d'amertume était un trait notoire, et avoir la bonne morsure d'amertume était essentiel pour une IPA. L'innovation a ensuite commencée à arriver sur la cote Ouest des États Unis à la fin des années 1990, et au début des années 2000, quand quelques doubles ou impériales IPA telles que Pliny the Elder de Russian River et Ruination IPA de Stone Brewing ont commencées à sortir des fermenteurs. Alors que celles ci contenaient énormement de « morsure du houblon», ce qui séparaient ces bières de beaucoup d'autres versions du style était le fait que le nez et la saveur du houblon semblaient éclater de la bière.</p> +<p>Du point de vue du brasseur, les huiles essentielles de ces houblons étaient bien plus présents que les acides alpha. En utilisant un profil de malt neutre et une souche de levure neutre, ces bières laissaient la part belle aux houblons. Ces brasseurs utilisaient aussi des houblons souvent critiqués, forts en acides alpha, tels que Columbus, Centennial, Simcoe et Chinook à la fin de l'ébullition ou en houblonnage à cru... et en grosses quantitées. Cela peut sembler comme une pratique courante pour une IPA actuellement, mais il y a à peine 15 ans, la plupart de la littérature évitaient d'utiliser ces variétés de houblon pour une utilisation autre que de l'amérisant. Lévolution d'une nouvelle American IPA était en train de prendre forme, sur la cote Ouest des étants unis, un style que les buveurs de bière ont nommé la « West Coast IPA».</p> +<h1>La phase de démarrage</h1> +<p>De retour sur la cote Est des États-Unis, dans un petit brewpub de Burlington à Vermont, deux brasseurs commencent innocemment à développer un type d'American IPA avec des objectifs similaires que les brasseurs de la côte Ouest, mais en utilisant une stratégie différente. Crée en 1988 par Greg Noonan et Steve Polewacyk, le « Vermont Pub &amp; Brewery » deviendra le berceau d'une nouvelle révolution autour des IPA.</p> +<p>Souvent citée comme étant les premiers brasseurs des Black IPA modernes ainsi que des New England IPA, offrant une variété de bières qui était extrèmement rare à cette époque, le « Vermont Pub &amp; Brewery » a des racines provenant de la connaissance du brassage et de la chimie de Greg Noonan, ainsi que son flair pour la créativité.</p> +<p>Se reposant sur la révolution de la bière mondiale (menée par Michael Jackson), Greg Noonan à exploré des styles de bières qui étaient en dehors des sentiers battus, même pour les brasseurs qui étaient déjà en avance sur leur temps.</p> +<p>Arrive John Kimmich, qui, en 1994 à déménagé dans le Vermont avec l'objectif de brasser sous la tutelle de Greg Noonan. John à travaillé un temps à Pittsburg (en Pennsylvanie) dans un <em>home brewshop</em> nommé Country Wines. Il a travaillé avec Alexis Hartung et sa grande bibliothèque sur le brassage maison et a eu son premier éclair de génie brassicole en lisant le livre de Greg Noonan « New Brewing Lager Beer ». Un an plus tard, il commence à travailler au « Vermont Pub &amp; Brewery ». En quelques mois, Greg commence à avoir confiance dans les capacités de son nouveau protégé. Avec chaque bière que John travaillait, le mentor était impressionné. Après douze mois, Greg donne la liberté à John d’expérimenter seul sur les recettes.</p> +<p>En 1997, John part du « Vermont Pub &amp; Brewery » et cofonde avec sa femme Jen un brewpub en 2003, le « Alchemist Pub &amp; Brewery », situé 30mn à l'est de Burlington à Waterbury dans le Vermont. A cette époque, Waterbury était un petit village dormant du New England, n'attirant pas grand monde autre que quelques touristes. Il était par contre assez bien situé, à un croisement des chemins, juste à la sortie d'une autoroute majeure, Waterbury est facilement accessible par à la fois les voyageurs en route pour les endroits touristiques et pour les locaux en allant / revenant du travail ou pour leurs excursions shopping. Grâce à ces quelques éléments, Waterbury s'est donc révélé êre un excellent spot pour Jen et John.</p> +<p>Une caractéristique unique des bières houblonnées de Kimmich était que lorsque servies fraîches et non filtrées, elles étaient souvent assez troubles. Il trouvait que filtrer ses bières pouvait introduire de l'oxygène non souhaité, enlevant de la bière beaucoup d'aspects intéressants. Il utilisait une souche nommée Conan (VPB1188), une levure que son mentor a développé et que maintenant beaucoup connaissent. Avec les dérivés Anglais, la souche de levure Conan, les bonnes connaissances en brassage de John, ainsi que son habitude à expérimenter avec les houblons, on se retrouve avec une combinaison gagnante pour une révolution du brassage sur la côte est.</p> +<h1>La phase de croissance</h1> +<p>En 2007, alors que j'allais au festival des brasseurs du Vermont, la queue pour accéder au stand de The Alchemist était d'au moins 20 minutes pour un verre. Certaines personnes remplissaient leurs verres et retournaient faire la queue pour avoir la chance de goûter une autre de ces bières tant acclamées, en particulier pour Heady Topper. Pour la première fois brassée en 2003, Heady Toper retenait alors l'attention, alors qu'elle n'était réellement qu'une parmi les nombreuses IPA acclamées de chez The Alchemist. Des histoires circulaient comme quoi certaines personnes amenaient leurs pintes aux toilettes pour remplir des bouteilles, les capsuler et les ramener chez eux, puisque le bar ne proposait pas de remplir de Growlers à l'époque, ni ne vendait de bouteilles. Je pensais alors que l'engouement pour ces IPAs avait atteint une sorte de paroxysme. Je n'avais pas encore compris que le feu était seulement en train de se construire.</p> +<p>J'ai récemment demandé à Shaun Hill, de la brasserie « Hill Farmsted » à Greensborrow Bend dans le Vermont, classée « meilleure brasserie du monde » 3 des 4 dernières années sur RateBeer.com, quel était sa relation avec John Kimmich à l'époque. Shaun brassait à l'époque 30mn plus loin, à Stowe, dans un brewpub appelé « The Shed».</p> +<p>« En 2005, je ne tarissais pas d'éolges pour les bières de John me faisait le plaisir de critiquer mes bières » me dit Hill, « Cette relation à évoluée avec le temps, plus specialement lorsque j'ai déménagé au Danemark et que cette conversation est devenue une conversation entre pairs, poussant l'autre dans de nouvelles directions.». Avec le decès de Greg Noonan en 2009, l'ancien protégé est devenu le nouveau mentor. Lors d'un échange avec Joel Mahaffey de Foundation brewing Co, à Portland à propos des IPAs influentes pour cette nouvelle révolution, il dit de The Alchemist « Quiconque réponds à cette question et oublie Heady Topper, ils sont à coté de la plaque. Il s'agit de la première IPA trouble, et à laissée une marque sur la communauté brassicole.»</p> +<p>Ce qui à emergé dans le coin nord-est des états unis est une explosion de nouvelles brasseries produisant des Pale Ale, des IPA et des double IPA basées sur la non filtration, l'explosion de saveurs, et un corps doux, un style que Greg Noonan et John Kimmich ont découvert, et qu'ensuite Shaun Hill à continué à affiner. John et Shaun ont séparemment pointé du doigt le fait qu'ils brassaient juste des bières à leur convenance, et qu'ils appréciaient le produit fini. Le terme « Juicy IPA » s'est retrouvé être un nom pour ces bières, et la texture est souvent aussi importante que le nez et le gout de houblons. Et comme les IPA de la côte Ouest se sont répendues en 2008, les bières troubles, non filtrées, les New England IPA se répendent en 2016.</p> +<h1>C'est parti !</h1> +<p>Il est maintenant temps de passer à la brasserie et de regarder comment faire pour brasser une IPA, New England style. Shaun Hill dit « soyez vous mêmeet faites une bière qui goute, sent et ressemble à ce que vous voulez qu'elle soit », JC Tetreault de Trillum à Boston dans le Massachussetts ajoute « la réponse courte… tout est important ! Vous devez vous concentrer sur chaque aspect pour arriver à la bière que vous souhaitez. » L'objectif est d'arriver à une bière douce, un peu ronde, presque tropicale, à la texture ressemblant presque à un jus de fruit, laissant une morsure subtile sur la langue en fin de bouche graçe au houblon.</p> +<h2>Les malts</h2> +<p>Tout comme les IPAs de la cote Ouest, les NEIPA sont relativement simples en malts. Le style évite les malts qui ajoutent des saveurs de pain et de crackers. Les malts cristals et autres malts au dessus de 20°L (ndt: 52 EBC) sont d'une manière générale évités. Ces bières peuvent bénéficier de certains ajouts de malts cristal clairs, mais gardez les à l’œil. Des flocons d'avoine, d'orge, de blé et autres peuvent être ajoutés pour contribuer au corps, mais ne pensez pas qu'ils soient une necessité. J'ai pu jouer avec des pourcentages de 15% de flocons dans mes recettes, et les résultats étaient presque excessifs. JC Tetreault dit que « à propos des ajouts de céréales non maltés et de flocons… nous ne les utilisons pas dans toutes nos bières basées sur le houblon. En fait, une proportion plutôt petite de nos bières basées sur le houblon en font usage». Les ajouts de sucre tels que les dextrose, saccharose et sucres crus augmentent la densité du moût pour s'assurer de la sécheresse dans les versions plus alcoolisées. Si vous choisissez d'ajouter du sucre cru, encore une fois, faites en sorte que l'ajout soit modeste; j'ai trouvé que certaines saveurs de mélasses avaient tendance à arriver à partir de 10% du total du grain. L'objectif est de garder les houblons comme caractéristique principale de la bière, tout en ayant une base de malt douce mais présente.</p> +<h2>Les levures</h2> +<p>Et c'est ici que les NEIPA dérivent des IPA de la cote Ouest. L'ajout des levures ainsi que le traitement à partir de la fermentation semble être la plus grosse différence entre les deux styles. D'abord, regardons comment ces bières sont fermentées. La plupart des NEIPA ne sont pas clarifiées dans le fermenteur avec des agents clarifiant tels que de la gélatine, du Biofine® ou du Polyclar™, et elles ne sont pas filtrées ou centrifugées plus tard pour clarifier la bière. La pensée derrière ce process est qu'enlever les levures de la bière à également pour effet d'enlever les huiles essentielles ainsi que d'autres nuances subtiles qui permettent à la bière d'avoir son caractère propre. Cela permet de garder un niveau d'huiles assez elevé dans le produit fini. Deuxièmement, les brasseurs de New England fermentent en utilisant une souche de levure d'origine anglaise. Ashton Lewis, l'éditeur technique de Brew Your Own précise « D'après des études ADN, la levure California Ale (White Labs WLP001, Wyeast 1056 et les autres souches de Chico) viendraient plutôt de Cologne, en Allemagne ». Ces souches américaines ont été choisies pour leur capacité à produire des bières claires, transparentes et amères sans ajouter de caractère. Les souches de levure utilisées par les brasseurs de New England IPA sont utilisées pour ajouter des esters, qui aident à produire le profil juteux de ces bières. Les IPAs brassées avec ces souches ne semblent pas être aussi transparentes que les souches Americaines lorsqu'elles sont exposées à des niveaux d'huiles elevés. Ceci vient en désaccord avec la plupart de la littérature sur les souches Anglaises. Si vous lisez la description de la plupart des souches de levures utilisées pour produire ces IPA troubles, la plupart sont considéeées « hautement floculantes », alors que la souche Chico, souvent utilisée pour les IPA de la cote Ouest annonce plutôt une floculation moyenne à faible. Pourquoi alors ces bières ne se clarifient pas lorsqu'elles sont sujettes à des hautes doses de houblon en fin d'ébullition ou en houblonnage à cru ? Cela reste encore une zone floue, j'ai donc demandé à quelques personnes dans l'industrie à propos de ce flou. Certains brasseurs pointent du doigt le fait que ces souches de levures floculent trop rapidement. Cela ne laisse pas le temps aux polyphénols de s'attacher aux levures, laissant ces composés ainsi que d'autres composés dérivés du houblon dans la solution plutôt que des les en enlever. Ashton Lewis nous rappelle aussi que le trouble trouvé dans les hefeweizen est principalement causé par les interactions entre les protéines et les polyphénols, et non pas par les levures.</p> +<p>Donc, quelles sont les souches de levure que vous devriez utiliser ? Le choix est en fait assez large, pour ceux qui souhaitent brasser ces types de American IPA, referez vous donc aux suggestions données dans les recettes jointes pour quelques idées.</p> +<h2>L'eau</h2> +<p>L'eau joue un rôle prépondérant dans le développement des New England IPA. Concentrez vous sur les niveaux de dureté de votre eau. Si vous avez une eau assez douce, alors vous avez un bon point de départ. Si vous avez une eau plutôt dure, obtenez un relevé d'eau (ndt: allez faire un tour sur le site « Eau du bassin Rennais » !). Si vous n'avez pas ces relevés d'eau, vous pouvez aussi faire analyser votre eau par des laboratoires, ou vous pouvez le faire vous même grâce à des kits de test de l'eau. Peu importe ce que vous choisissez, utiliser de l'eau distillée ou osmosée peut vous fournir une bonne base pour construire le profil d'eau que vous souhaitez obtenir. Essayez de garder votre niveau de bicarbonate en dessous de 50 PPM pour votre eau d’empâtage et votre eau de rinçage.</p> +<p>La prochaine chose sur laquelle se concentrer est vos sulfates et vos chlorures. Ceci est parfois controversé, mais encore une fois peut potentiellement être un facteur différenciant entre les IPA de la côte Est et les IPA de la côte Ouest. Quand j'ai commencé à jouer avec la composition de mon eau, j'ai traité l'eau de mes IPA pour atteindre un rapport 2:1 de sulfates / chlorures, ce qui s'est traduit par 100:50 PPM. J'ai produit plusieurs bières qui pouvaient rivaliser (selon moi) avec certaines que mes idoles produisaient. Mais, dans l'esprit du brassage amateur, j'ai continué à expérimenter. J'ai changé l'équilibre de sulfate / chlorures à 200:50PPM sans que je perçoive un changement. J'ai ensuite essayé 100:100 et trouvé que ça me plaisait un peu plus. Mes trouvailles ne sont pas la seule preuve anecdotique que booster le niveau de chlorures peut bénéficier à ce style de bières. Si vous cherchez à ajuster vos sulfates et for chlorures pour votre eau d'empâtage et de rincage, je vous encourage à jeter un oeil à l'article de Scott Janish du 7 Mars 2016 intitulé « Mouthfeel softness ». Scott y parle des effets négatifs d'un taux de sulfates elevé et des aspects positifs d'un niveau de chlorures elevé.</p> +<h2>Les houblons</h2> +<p>Généralement, l'amertume des houblons dans ce type d'IPA joue un rôle support, qui vient équilibrer le corps et la douceur des malts. Premièrement, gardez l'ajout de houblons amérisants modéré à faible. Vous pouvez expérimenter avec l'ajout de houblons amérisants mais je n'ai jamais eu l'occasion de trouver qu'une utilisation importante de houblons amérisants menait à une meilleure New-England IPA. Utilisez des houblons hauts en alpha tels que Magnum, Warrior™ ou Bravo si vous choisissez d'utiliser des houblons en cône ou en pellets, et je recommande de garder les ajouts d'amérisants assez faibles. D'habitude, j'essaye houblonner pour un rapport de 1:3 BU:GU (amertume sur densité). Cela signifie que quand je vise une densité cible de 1.066, l'ajout de houblons à 60mn est de 22 IBUs. Cela est fait pour éviter d'ajouter une dureté qui peut provenir d'une ébullition d'une quantité plus elevée de houblons. L'autre option est d'utiliser des extraits de houblon, qui peuvent contribuer les acides alpha nécessaires pour obtenir la bonne amertume, sans ajouter de polyphénols, que certains brasseurs pensent être à l'origine d'une certaine dureté.</p> +<p>Les ajouts de houblons en fin d'ébullition jouent un rôle beaucoup plus important pour la production de New-England IPA. Des apports copieux à la fin de l'ébullition ou au <em>flame-out</em> sont utiles pour tout type d'IPA hautement aromatique. Cela ajoutera des IBUs pour compléter votre apport en houblons amérisants et commencera à créer votre profil d'huiles. Je trouve que des variétés plus mordantes / piquantes comme le Simcoe®, Columbus, Chinook et Apollo fonctionnent bien à cette étape. Chaque brasseur semble trouver sa technique ici, qu'il s'agisse de faire plusieurs ajouts à 20mn ou moins puis de baisser à une température précise pour faire un <em>hop stand</em>, ou bien de simplement ajouter tous les houblons au <em>flame-out</em> et de les laisser durant 20 minutes ou plus. Il ne semble pas qu'il y ait de mauvaise manière de faire, juste plusieurs manières d'extraire les huiles essentielles des houblons à une température pas trop haute.</p> +<p>Le houblonnage à cru est votre prochain objectif. J'aimerais me concentrer sur les techniques plutôt que sur les quantités ou variétés puisque la technique semble être le plus important ici. Ceci dit, une chose est sure, ne soyez pas trop timide avec les ajouts durant le houblonnage à cru. 7.5g/L est certainement un bon point de départ. Vous pouvez ajuster en fonction de vos résultats. Les brasseurs Scott Janish et Michael Tonsmeir ajoutent que mettre ces bières en fûts à quelques avantages. Houblonner dans le fût, purger au CO2 et le fait de ne pas avoir de période prolongée de carbonatation sont déjà deux des avantages des fûts sur les bouteilles.</p> +<p>Alors, quand est le meilleur moment pour faire son houblonnage à cru ? Biern que ce ne soit pas une necessité, le fait de faire son houblonnage à cru en deux fois semble être un bon choix pour ce genre d'IPA. Prenez ce que vous pensiez ajouter lors du houblonnage à cru et séparez le en deux. Le premier ajout se fera durant la phase active de fermentation alors que le second se fera quand la fermentation se sera calmée et que les levures auront flocculées. Le premier ajout peut se faire à différents stades de la fermentation primaire; certains brasseurs les ajoutent au même moment qu'ils ensemencent, certains autres lorsque le krausen est haut, alors que la plupart l'ajoutent vers la fin de la fermentation. Je préfère faire le premier ajout une fois que le krausen est redescendu. Les hétérosides et les bio-transformations sont des éléments importants dans cette discussion à propos de comment la levure intéragit avec les huiles des houblons et les autres dérivés du houblon. Je trouve que les houblons ajoutés à la fin de l'ébullition vont apporter des caractéristiques similaires que les huiles de houblons ajoutés durant le ébut de la fermentation. Pour ce qui est du second ajout, l'objectif est d'attendre que la fermentation se soit calmée. Le timing n'est pas vraiment un facteur important ici, mais l'introduction d'oxygène est un point crutial. Prenez bien soin d'introduire le moins possible d'oxygène dans la bière à ce moment çi.</p> +<p>Dernièrement, quelque chose qui est nouveau pour moi: le houblonnage à cru sous pression. Cela vous demandera de l'équipement supplémentaire, principalement quelque chose apellée une « Spunding Valve». Il s'agit d'une valve qui permet de garder une certaine pression dans le fermenteur. Si la pression dépasse la valeur cible, alors la valve s'ouvre pour faire redescendre le fermenteur à la valeur souhaité. Mais, en quoi cela pourrait-être interéssant pour nous ? Parce que nous cherchons à garder un maximum de houblons aromatiques, en évitant d'en perdre. Les brasseurs amateurs ainsi que les brasseurs pros se sont penchés sur la question des spuinding valve de plus en plus dernièrement pour la fermentation primaire et pour le houblonnage à cru.</p> +<p>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.</p> +<p>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 !</p>Brasserie du Vieux Singe — Installation en cours.2017-06-26T00:00:00+02:002017-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-06-26:/brasserie-du-vieux-singe-installation-en-cours.html<p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour …</p><p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour être à portée de main.</p> +<p>La chose la plus frappante, c'est la vitesse à laquelle passent les journées: j'ai <em>vraiment</em> l'impression d'avoir quitté Mozilla hier. Si les collègues me +manquent, je ne ferais machine arrière pour rien au monde: je trouve finalement ce sens qui me manquait cruellement.</p> +<p>Après quelques hésitations au départ, j'ai décidé de mettre de côté mes activités liées à l'informatique: difficile à assumer quand on croise les copin.e.s avec qui on avait l'habitude de discuter énormement de ces sujets, mais ça permet de laisser plus de place pour l'humain. Plus de place pour les «Au fait, comment ça va toi ?» quand j'ai l'occasion de les recroiser, ce qui n'est pas plus désagréable :)</p> +<p>Les journées sont donc organisées autour de la brasserie: beaucoup plus de planification que ce que j'imaginais au départ. Peut-être que c'est aussi du au fait que nous soyons tous les deux des ex-informaticiens un peu perfectionnistes sur les bords. On se voit très souvent pour avancer sur des sujets de fond tout comme sur du pratico-pratique. Pour vous donner un ordre d'idée des questionnements: Quelle taille d'entreprise ? Quelles valeurs communes ? Quelles bières ? Quelle image donner ? Quelle place donner au confort ? Comment éviter la compétitivité ? Comment réussir à impacter les producteurs (houblon / malt) de manière positive ? Quels salaires se donner ?</p> +<p>Un peu de production quand même (pour les amis) mais on se garde la grosse partie pour le lancement.</p> +<h2>Apprentissage</h2> +<p>Je profite de ces quelques mois pour apprendre: autour de la fabrication et de la dégustation de bière bien sûr (encore un milieu en constante évolution !), mais pas que. J'ai maintenant quelques bases de gestion d'entreprise, en comptabilité, en biologie et en chimie. J'ai bien dit quelques <em>bases</em>, mais qu'est-ce que c'est agréable !</p> +<p>C'est assez agréable de se remettre dans une posture d'apprenant, et d'avoir le temps pour cet apprentissage.</p> +<h2>Questionner la posture de «Chef d'entreprise» et son rapport au temps</h2> +<p>Décider de créer sa boîte, c'est aussi se poser la question de comment organiser son temps: combien de temps travailler ? Quel temps donner aux loisirs ?</p> +<p>Je trouve rassurant de voir ces interrogations abordées avant-même le démarrage de l'entreprise. La plupart des personnes qui nous suivent et nous guident partent du postulat qu'il faudra bosser énormement, là ou nous essayons de trouver un modèle qui soit viable dans le temps, notre souhait est de bosser à 80% (4 jours par semaine).</p> +<p>Certes, il faut travailler pour que ça tourne, mais il faut aussi s'accorder des temps de respiration pour être d'autant plus efficace quand on bosse. C'est d'autant plus intéressant de prévoir ces aspects lors de la phase de <em>design</em> de l'activité: on organise le temps autrement ! Ceux qui me lisent de temps à autre savent que c'est une constante de mes réflexions, on verra si ça fonctionne dans les faits.</p> +<h2>Les projets collectifs</h2> +<p>Un autre point important est la place que le <em>collectif</em> prends dans cette nouvelle expérience. Au départ, quand j'imaginais le projet sur le court-terme, je mettais la composante collective au second plan dans l'immédiat (au delà des intéractions avec Fred, mon associé). L'occasion de travailler à la construction d'un espace collectif s'est présentée, et on y travaille actuellement.</p> +<p>C'est à la fois riche (en partage de points de vue, en entre-aide) et à la fois difficile (beaucoup d'heures de réunions, il faut apprendre à communiquer de manière efficace, il faut parfois faire face à des conflits). Dans l'ensemble, je ne regrette pas ce choix même si il est important de ne pas perdre de vue les objectifs de la brasserie dans l'histoire.</p> +<p>Et puis la collaboration ne s'arrête pas qu'au collectif d'activité: le milieu brassicole est en mutation, et les valeurs de partage font bel et bien partie du lot de changements. Les rencontre avec les brasseurs du coin de Rennes le montrent bien: l'esprit est plus à l'entraide qu'à la concurrence, au vu de la demande qui est toujours croissante. Tant mieux, on a autre chose à faire qu'à se tirer dans les pâtes ;)</p> +<h2>Besoin de concret</h2> +<p>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…</p> +<p>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 ?</p>Comment est-ce que vous générez vos formulaires ?2016-05-31T00:00:00+02:002016-05-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.html<p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est …</em></p><p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est passé par pas mal d'é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'organisateurs d'é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'est +pas libre et que les données sont stockées chez 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'ils puissent y répondre. +Je reviens ensuite plus tard pour voir la liste des réponses apportées.</p> +<p><img alt="Capture de l'interface de création du formulaire" src="{filename}/static/formbuilder-build.png"></p> +<h2>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'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 à +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'opération terminée.</p> +<p><img alt="Capture de l'écran avec les URLs générées" src="{filename}/static/formbuilder-created.png"> +<img alt="Capture d'écran d'un exemple de formulaire" src="{filename}/static/formbuilder-form.png"></p> +<h3>Pas de compte</h3> +<p>Vous n'avez pas besoin d'avoir un compte sur le site pour commencer à l'utiliser. +Vous créez simplement un nouveau formulaire puis envoyez le lien à vos amis pour +qu'eux puissent à leur tour le remplir.</p> +<p><img alt="Capture de la page d'accueil, ou aucun compte n'est requis" src="{filename}/static/formbuilder-welcome.png"></p> +<h3>Gardez la main sur vos 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="{filename}/static/formbuilder-results.png"></p> +<h3>API</h3> +<p>L'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 HTTP. Ce qui fait qu'il est très facile de +réutiliser les formulaires que vous avez construits (ou leurs réponses) depuis +d'autres outils.</p> +<h3>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'instance qui est mise à votre disposition sur +<a href="https://www.fourmilieres.net">wwww.fourmilieres.net</a>, mais vous pouvez +également l'héberger vous même très +simplement, et vous êtes d'ailleurs fortement encouragés à le faire ! Notre +objectif n'est pas de stocker l'ensemble des formulaires du monde, mais de +(re)donner le contrôle aux utilisateurs !</p> +<h2>On commence petit…</h2> +<p>Cette <em>release</em> n'est (bien sur) pas parfaite, et il reste encore pas mal de +travail sur cet outil, mais je pense qu'il s'agit d'une base de travail +intéressante pour un futur où Google n'a pas la main sur toutes nos données.</p> +<p>La liste des champs supportés est pour l'instant assez faible (Texte court, +Texte long, Oui/Non, choix dans une liste) mais elle à vocation à s'étendre, en +fonction des besoins de chacun.</p> +<p>J'ai d'ailleurs créé <a href="https://www.fourmilieres.net/#/form/cfd878264cec4ed2">un formulaire pour que vous puissiez me faire part de vos +retours</a>, n'hésitez pas !</p> +<h2>Et, euh, comment ça marche ?</h2> +<p>Le <em>formbuilder</em>, comme j'aime l'appeler se compose en fin de compte de deux +parties 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 HTTP</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'envoyer les données sur les <em>APIs</em> coté + 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'il génère en fin de compte du +<a href="http://jsonschema.net/">JSON Schema</a>, un format de validation de données <em>JSON</em>.</p> +<p>Donc, reprenons! Vous arrivez sur la page d'accueil puis cliquez sur +"Create a new form", puis vous vous retrouvez face à une interface ou vous pouvez +ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez sur +"Create the form".</p> +<ul> +<li>Le JSON Schema est alors envoyé au serveur Kinto, qui l'utilisera pour valider + les données qu'il recevra par la suite.</li> +<li>Ce JSON Schema sera aussi utilisé lors de l'affichage du formulaire aux + personnes qui le remplissent.</li> +<li>Un jeton d'accès est généré et ajouté à l'URL, il s'agit de l'identifiant du + formulaire.</li> +<li>Un second jeton d'accès administrateur et généré, il vous faut le garder de + coté pour avoir accès aux 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 !</p>Cloisonnement des activités ?2016-05-29T00:00:00+02:002016-05-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-29:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en …</p><p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en faire +un plaisir. Oh, et des fois on parle un peu de technique aussi.</p> +<h1>Alors, brasserie ou code ?</h1> +<p>Ces quelques jours ont été fort inspirants. Alors que je suis en train de +changer de métier (vers celui de brasseur) c'était un moyen de me rendre compte +que bien que je ne souhaite plus faire du Web mon métier <em>la, tout de suite, +maintenant</em>, je reste un passionné par la chose.</p> +<p>En partant de Rennes, je ne savais pas trop quoi penser de cette situation. +Prendre un week-end pour échanger avec les gens sur quelque chose dont je +m'éloigne ? C'est pas une perte de temps ?</p> +<p>Si je passe du temps à écrire des bouts de code, des logiciels, à reflechir +à comment solutionner certains problemes, ce n'est pas parce que je suis payé +pour le faire, mais bel et bien parce que je me sens bien lorsque je le fais, +parce que j'y trouve un équilibre et une utilité.</p> +<p>Alors que je ne trouvais plus cet équilibre dans mon travail, j'ai choisi d'en +changer, mais il n'empèche que je continue à avoir des rèves d'un +monde meilleur, dans lequel l'informatique a sa place. Juste à voir les +discussions (ux, sécurité informatique, décentralisation, architecture +logicielle) que j'ai pu avoir ce weekend, il n'y a pas l'ombre d'un doute !</p> +<p>Jusqu'ici je me suis dit que je devais choisir. J'ai pensé naivement +que je ne pouvais pas être <em>et</em> un brasseur <em>et</em> un developpeur, mais la +réalité c'est que c'est exactement ce que je suis: les deux.</p> +<p>Je ne suis pas pour autant dupe sur le temps necessaire à lancer une activité +brassicole, il va falloir fournir de l'énergie et avancer sur le projet, mais +il n'empèche que même si je décide de faire de la bière mon metier, mes +passions pour le reste sont bien vivantes.</p> +<p>Bref, merci sudweb pour m'avoir accompagné dans ces reflexions, à l'année +prochaine, je ramène des futs ?</p>Avez vous confiance en SSL?2016-03-25T00:00:00+01:002016-03-25T00:00:00+01:00Alexis Métaireautag: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'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop …</p><p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop, c'est parti pour:</p> +<ul> +<li>un tour d'horizon du fonctionnement de SSl</li> +<li>quelques moyens contourner cette "protection" en faisant une attaque en pratique</li> +<li>un tour des solutions existantes actuellement et de pourquoi je ne les trouve + pas vraiment satisfaisantes.</li> +</ul> +<h2>Comment fonctionne SSL?</h2> +<p>Pour expliquer les problèmes de SSL, j'ai d'abord besoin d'expliquer comment +tout ça fonctionne.</p> +<p>SSL repose sur l'utilisation de certificats, qui sont générés par des autorités +de certification (<em>Certificate Authority</em> que je nomme <em>CA</em> dans la suite de +l'article).</p> +<p>Les certificats SSL permettent deux 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 même.</li> +<li>De garantir que le site sur lequel vous vous connectez est bien celui que + vous imaginez.</li> +</ul> +<p>Le navigateur, lors d'une visite d'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>CA</em> en qui il a confiance.</p> +<p>Imaginons maintenant qu'une des <em>CA</em> essaye de savoir ce qui s'échange entre +mon navigateur et le site de ma banque (protégé par SSL). Comment cela se +passerait il ?</p> +<p>N'importe quel <em>CA</em> peut donc générer des certificats pour n'importe quel site, +et le navigateur vérifierait, lui, que le certificat a bien été généré par une +<em>CA</em>.</p> +<p>Tout cela ne poserait pas de soucis si les <em>CA</em> étaient gérés de manière fiable, +mais il s'agit d'un travail compliqué, et certains <em>CA</em> ont par le passé montré +des faiblesses.</p> +<p>Par exemple, <a href="https://en.wikipedia.org/wiki/DigiNotar">DigiNotar</a> (un <em>CA</em> des Pays-Bas) +a été compromise et les attaquant.e.s ont pu générer des certificats SSL +frauduleux, ce qui leur a permis d'attaquer des sites tels que Facebook ou GMail.</p> +<p>Vous pouvez retrouver une liste des risques et menaces autour des <em>CA</em> <a href="http://wiki.cacert.org/Risk/History">sur le +wiki de CACert</a>.</p> +<h2>Attaque de l'homme du milieu avec SSL</h2> +<p>A force de dire que c'était très facile à faire, j'ai eu envie d'essayer +d'espionner des connections protégées par SSL, et effectivement c'est +carrément flippant tellement c'est simple.</p> +<p>En l'espace de quelques minutes, il est possible de faire une <em>attaque de +l'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'ensemble du trafic SSL, j'ai simplement eu à lancer quelques +commandes et avoir un <em>CA</em> dans lequel le navigateur de la victime a confiance. +Je l'ai ajouté dans le navigateur cible pour simuler que je l'avais déjà +(c'est le cas si un des 1200 CA se fait pirater, ce qui me semble une surface +d'attaque assez large).</p> +<p>Je les colle ici si ça vous intéresse:</p> +<div class="highlight"><pre><span></span>$ sudo aptitude install mitmproxy +$ mitm-proxy -T --host +</pre></div> + + +<p>Il faut faire croire à votre victime que vous êtes la passerelle vers +l'extérieur et à la passerelle que vous êtes la victime:</p> +<div class="highlight"><pre><span></span>arpspoof -i wlan0 -t victime gateway +arpspoof -i wlan0 -t gateway victime +</pre></div> + + +<p>Puis dire à notre fausse passerelle de rediriger le trafic des ports 80 et 443 +vers notre proxy:</p> +<div class="highlight"><pre><span></span>sudo sysctl -w net.ipv4.ip_forward<span class="o">=</span><span class="m">1</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">443</span> -j REDIRECT --to-port <span class="m">4443</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">80</span> -j REDIRECT --to-port <span class="m">4443</span> +</pre></div> + + +<p>Et paf, <strong>on voit tout ce qui passe entre la machine et le serveur SSL</strong>. On peut +d'ailleurs même imaginer faire tourner ces quelques commandes sur un +raspberry pi, pour aller encore plus vite…</p> +<h3>Key-pinning dans les navigateurs</h3> +<p>Actuellement, n'importe quel <em>CA</em> peut générer des certificats pour +n'importe quel site, et c'est en grande partie ce qui pose souci. Une des +manières de faire évoluer la situation est d'épingler les certificats de +certains sites directement dans les 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>HTTP Public Key Pinning (HPKP)</h3> +<p><a href="https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning"><em>HTTP Public Key Pinning</em></a> +est également une solution de <em>pinning</em> qui permet d'établir une confiance lors +de la première connexion avec le site. C'est ce qu'on appelle du <em>Trust on First +Use</em> ou <em>TOFU</em>.</p> +<p>Le navigateur va alors mettre ces informations dans un cache et vérifiera que +les certificats correspondent bien lors des prochaines visites.</p> +<p><em>HPKP</em> est disponible dans Firefox depuis Janvier 2015 et dans Chrome +depuis Octobre 2015.</p> +<h3>Certificate transparency: des journaux 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 SSL certificates open to scrutiny by +domain owners, CAs, and domain users.</p> +<p>-- <a href="https://www.certificate-transparency.org/what-is-ct">Certificate Transparency</a></p> +</blockquote> +<p>Autrement dit, avec ce système les <em>CA</em> doivent rendre public le fait qu'ils +aient signé de nouveaux certificats intermédiaires. La signature est ajoutée à +un journal sur lequel il n'est possible que d'écrire.</p> +<p>Les navigateurs vont alors vérifier que les certificats utilisés sont bien des +certificats qui ont été ajoutés au journal.</p> +<p>Ici, toute l'intelligence est dans la vérification de ces journaux, qui +permettent donc de valider/invalider des certificats racines ou intermédiaires.</p> +<p>Il me semble donc qu'il serait possible d'ajouter un certificat frauduleux le +temps d'une attaque (et celui ci serait détecté et supprimé ensuite).</p> +<p><em>Certificate-Transparency</em> n'est donc pas une solution contre une écoute +globale mise en place par les gouvernements par exemple.</p> +<p>Si vous lisez bien l'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 écrite.</p> +<h3>DANE + DNSSEC</h3> +<blockquote> +<p>The DANE working group has developed a framework for securely +retrieving keying information from the DNS [RFC6698]. This +framework allows secure storing and looking up server public key +information in the DNS. 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 service.</p> +<p>-- <a href="https://datatracker.ietf.org/wg/dane/charter/">Dane WG</a></p> +</blockquote> +<p>Une autre solution est appelée "DANE" et repose par dessus le protocole +<em>DNSSEC</em>.</p> +<p>Je connais assez mal <em>DNSSEC</em> donc j'ai passé un peu de temps à lire des +documents. L'impression finale que ça me laisse est que le problème est +exactement le même que pour SSL: 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 confiance.</p> +<blockquote> +<p>Secure DNS (DNSSEC) uses cryptographic digital signatures signed with a +trusted public key certificate to determine the authenticity of data. +-- https://en.wikipedia.org/wiki/DNS_spoofing</p> +</blockquote> +<p>Et aussi:</p> +<blockquote> +<p>It is widely believed[1] that securing the DNS is critically important for +securing the Internet as a whole, but deployment of DNSSEC specifically has +been hampered (As of 22 January 2010) by several difficulties:</p> +<ul> +<li>The need to design a backward-compatible standard that can scale to the + size of the Internet</li> +<li>Prevention of "zone enumeration" (see below) where desired</li> +<li>Deployment of DNSSEC implementations across a wide variety of DNS servers + and resolvers (clients)</li> +<li>Disagreement among implementers over who should own the top-level domain + root keys Overcoming the perceived complexity of DNSSEC and DNSSEC + deployment</li> +</ul> +</blockquote> +<h2>Solutions basées sur la blockchain</h2> +<p>Une dernière piste semble être l'utilisation de la <em>blockchain</em> pour distribuer +des clés par site.</p> +<p>La solution <em>DNSChain</em> me paraissait tout d'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'ont fait changer d'avis.</p> +<p>Reste encore la piste de <em>Namecoin Control</em> que je n'ai pas encore creusée. +Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la +bienvenue sur ces sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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><p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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, away from news and +agitation.</p> +<p>Working remotely is sometimes hard. Hard because you need to at the same time +be in the discussions channels and work on the interesting projects. A real +myth.</p> +<p>In practice, I'm really bad at multi-tasking. I tried a few times the <em>Pomodoro</em> +technique, which forces me to focus on a task for 25mn, but this split of my day +into slices of 25mn breaks my natural flow.</p> +<p>So, what do I need? I tried to change my tools, it helped a bit. Still, I'm not +focused like I would like to be.</p> +<p>Maybe that's just me who needs some more persuasion over myself, but the best +way I found to work is to unplug the cable. Literally. At work, at some point I +was using a RJ45 cable to connect to the Internet. When I wanted to work on +something, I could just unplug this cable.</p> +<p>And that's amazing how you find yourself in the process to &quot;check&quot; +something on the web. Mails, irc… well, you got the idea. You're litterally, +without even noticing, switching to your browser an opening a new tab…</p> +<p>Of course, that Web isn't filled only with lolcats and twitter messages +(even if I would <strong>love</strong> to see a pie chart with the repartition of lolcats +VS the rest of the web's content), so sometimes you need some precious bit of +information that's there. Fair enough. plug the cable, do what you <strong>need</strong> to +do, and unplug. Alexis, unplug!</p> +<p>It also helps to have some fair bit of documentation available directly on my +machine (I used to have the python docs, I should get it back!)</p> +<p>I'm feeling adventurous, so I'll try something new starting tomorrow, and I'll +report back in here my findings. Here's the challenge:</p> +<ul class="simple"> +<li><strong>Check emails only once a day</strong>. Do <strong>not</strong> do it in the morning, before +working, to keep my mind clear. I would say at 2pm (after lunch). +(This doesn't mean I will not send mails tho)</li> +<li>Stay away from the Internet during the morning. I'll not connect if I don't +need to.</li> +</ul> +<p>Let's see how it goes :)</p> +Retours sur un atelier ZeroNet2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag: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'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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 …</p><p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> +dans les locaux de l'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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'éviter la censure.</p> +<p>Avant toute autre chose, merci énormément à l'équipe de la bibliothèque de +l'INSA pour l'organisation de cet évènement qui à une réelle portée politique.</p> +<h2>Un peu d'histoire</h2> +<p>Il me semble que Tim Bernes Lee (l'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 accéder.</p> +<p>Avec ce fonctionnement, impossible alors d'accéder à des sites si leur auteur +n'est pas en ligne. Qu'à cela ne tienne, on s'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'utilisateurs des sites.</p> +<h2>Un Web 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'une visite d'un +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 site.</li> +<li>Vous validez que les fichiers servis sont bien les bons (en vérifiant la + signature attachée).</li> +</ol> +<p>N'importe quel visiteur devient alors un <em>pair</em>, qui sert le site aux autres +visiteurs.</p> +<p>Parmi les nombreux avantages de cette approche, je note particulièrement que:</p> +<ul> +<li>Il est très difficile de censurer un site — Il est sur l'ensemble des machines + des visiteurs.</li> +<li>Les attaques par <em>fingerprinting</em> sont impossibles: le navigateur Web se + connecte à un serveur <em>proxy</em> local.</li> +<li>Vous détenez directement vos données et (par design) ne les donnez pas à des + silos (Facebook, Google, etc.)</li> +</ul> +<p>Si vous êtes interessés par une démonstration rapide, j'ai enregistré une vidéo +de 10 minutes où je parle en anglais avec une voix très grave.</p> +<video controls="" src="http://alexis.notmyidea.org/zeronet.webm" width=800></video> + +<h2>Atelier</h2> +<p>Pour l'atelier, j'ai choisi de faire une présentation rapide du projet (<a href="{filename}/static/zeronet-presentation-fr.pdf">j'ai +traduit les slides</a> anglais +pour l'occasion — <a href="https://docs.google.com/presentation/d/158C_-V1ueNaaKHMBMBgGOVhunb9xrXzB3hC_g1N53c0/edit?usp=sharing">accès aux sources</a>) +avant d'installer ZeroNet sur les machines et de l'utiliser pour publier un +site.</p> +<h3>Partager sur le réseau 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'avais pas prévu le coup.</p> +<p>Voici donc comment faire pour contourner le 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'est packagé pour debian pour l'instant</a>) + J'ai choisi d'installer <a href="http://erdgeist.org/arts/software/opentracker/#build-instructions">OpenTracker</a></li> +<li>Ensuite lancer ZeroNet avec des options spécifiques.</li> +</ol> +<div class="highlight"><pre><span></span>$ python zeronet.py --trackers udp://localhost:6969 --ip_external <span class="m">192</span>.168.43.207 +$ python zeronet.py --trackers udp://192.168.43.207:6969 --ip_external <span class="m">192</span>.168.43.172 +</pre></div> + + +<p>Il est nécessaire de spécifier l'adresse IP externe que chaque nœud expose pour +éviter qu'elle n'essaye d'aller la trouver par elle même: nous voulons l'adresse +du réseau local, et non pas l'adresse internet.</p> +<p>La prochaine fois je tenterais de venir avec un HotSpot Wifi et un tracker +BitTorrent dans la poche!</p> +<h2>Questions / Réponses</h2> +<p>Il y avait quelques questions intéressantes auxquelles je n'ai pas toujours su +répondre sur le moment. Après quelques recherches, je rajoute des détails ici.</p> +<h3>Torrent + Tor = brèche de sécu ?</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'utilisation de BitTorrent par dessus Tor</a>.</p> +<blockquote> +<p>Dans certains cas, certains clients torrents (uTorrent, BitSpirit, etc) +écrivent directement votre adresse IP dans l'information qui est envoyée +au tracker et/ou aux autres pairs. +— 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'est pas le cas de ZeroNet</a>, ce qui évacue le souci.</p> +<h3>ZeroMail, c'est lent non ?</h3> +<p>Une des applications de démo, <em>ZeroMail</em>, propose un mécanisme qui permet de +s'envoyer des messages chiffrés sur un réseau pair à pair. L'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 siens.</p> +<p>Cela permet de ne <strong>pas</strong> fuiter de méta-données, <a href="{filename}../crypto/2015.05.pgp-problemes.rst">à l'inverse de PGP</a>.</p> +<p>Je n'ai en fait pas de réponse claire à donner à cette question: l'auteur de +ZeroNet me disait que 10MB (la limite de taille d'un site, par défaut) +correspondait à beaucoup de place pour stocker des messages, et qu'il était +possible de supprimer les anciens messages une fois qu'ils sont lus par 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'un +utilisateur peut recevoir.</p> +<p>Je vois plusieurs problèmes avec le design actuel de ZeroMail (il me semble +assez facile d'y faire un déni de service par exemple). A creuser.</p> +<h3>Comment héberger des très gros sites ?</h3> +<p>Par exemple, comment faire pour héberger Wikipedia ?</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 demande)</p> +<h3>Est-ce qu'on à vraiment besoin d'un tracker ?</h3> +<p>Le support d'une DHT <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, +mais pour l'instant pas encore implémenté. L'utilisation de la DHT BitTorrent +n'est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas UDP</a>.</p>L'horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-02:/lhorizon.html<blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont …</p><blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont +eu lieu juste avant une descente de cave en Bourgogne avec Tarek pour +y déguster quelques saveurs de vins différentes.</p> +<p>Quatre ans plus tard, je me retrouve à coder sur Daybed, mon petit projet +perso, devenu <a class="reference external" href="http://kinto.readthedocs.org/">Kinto</a> avec une équipe de +personnes plus talentueuses et sympathiques les unes que les autres (Niko, +Rémy, Mat, si vous me lisez…).</p> +<p>Mozilla a bien évolué en quelques années: les petits bureaux ou j'avais atterri +se sont transformés en palace où il est possible d'accueillir des membres de la +communauté du logiciel libre de manière quotidienne.</p> +<p>De 14 personnes dans les bureaux Parisiens, nous sommes passés à une 40aine (et +de ~500 salariés à 1100 dans le monde).</p> +<p>Grandir autant en si peu de temps est un challenge difficile à tenir, qui +nécessite des réorganisations et bien souvent dans une structure de cette +taille, de la hiérarchisation. En 4 ans j'ai eu au moins 5 changements de +supérieurs, pour finalement arriver à une situation plutôt convenable (mais +quand même !)</p> +<p>J'ai choisi de rejoindre Mozilla parce que j'ai besoin de causes à défendre, +qui me saisissent et qui me guident. Aujourd'hui, une des visions qui m'anime, +c'est celle que d'autres ont déjà ouverte: celle de données et de vie privée +qui sont rendues à leurs utilisateurs.</p> +<p>Et je veux faire en sorte de réaliser ces «rêves d'un monde meilleur», ce qui +veut dire pour moi qu'il est temps de partir vers des horizons plus propices +à cette vision.</p> +<p>Lesquels ? Cela reste à construire (mais je vous le dis, y'a du Kinto dedans !)</p> +<div class="section" id="la-suite"> +<h2>La suite ?</h2> +<p>Sans m'étaler, je veux prendre du temps pour quelques projets autour du +stockage de données (via Kinto), de l'auto défense numérique (via des +formations) et de la fabrication de bière artisanale (parce que bon, on se +refait pas !)</p> +<p>Évidemment, plein d'envies diverses et variées, envie de me balader un peu et +d'expérimenter des choses collectivement...</p> +<p>On se recroisera surement :)</p> +</div> +Let's Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début …</p><blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début Décembre, la nouvelle <em>autorité de certification</em> Let's Encrypt +est passée en version <em>Beta</em>. Les certificats SSL sont un moyen de 1. chiffrer la +communication entre votre navigateur et le serveur et 2. un moyen d'être sur +que le site Web auquel vous accédez est celui auquel vous pensez vous connecter +(pour éviter des <a class="reference external" href="https://fr.wikipedia.org/wiki/Attaque_de_l'homme_du_milieu">attaques de l'homme du milieu</a>).</p> +<p>Jusqu'à maintenant, il était nécessaire de payer une entreprise pour faire en +sorte d'avoir des certificats qui évitent d'avoir ce genre d'erreurs dans vos +navigateurs:</p> +<img alt="Message de firefox lorsque une connexion n'est pas sécurisée." src="{filename}/static/unsecure-connection.png" /> +<p>Maintenant, grâce à Let's Encrypt il est possible d'avoir des certificats SSL +<strong>gratuits</strong>, ce qui représente un grand pas en avant pour la sécurité de nos +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 SSL valides avec Let's Encrypt et +le répartiteur de charge <a class="reference external" href="http://www.haproxy.org/">HAProxy</a>.</p> +<p>Je me suis basé pour cet article sur d'<a class="reference external" href="https://blog.infomee.fr/p/letsencrypt-haproxy">autres</a> <a class="reference external" 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 d'information.</p> +<div class="section" id="validation-des-domaines-par-let-s-encrypt"> +<h2>Validation des domaines par Let's Encrypt</h2> +<p>Je vous passe les détails d'installation du client de Let's Encrypt, qui sont +<a class="reference external" 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 à:</p> +<pre class="literal-block"> +letsencrypt-auto certonly --renew-by-default +--webroot -w /home/www/letsencrypt-requests/ \ +-d hurl.kinto-storage.org \ +-d forums.kinto-storage.org +</pre> +<p>Le <em>webroot</em> est l'endroit ou les preuves de détention du domaine vont être +déposées.</p> +<p>Lorsque les serveurs de Let's Encrypt vont vouloir vérifier que vous êtes bien +à l'origine des demandes de certificats, ils vont envoyer une requête HTTP sur +<tt class="docutils literal"><span class="pre">http://domaine.org/.well-known/acme-challenge</span></tt>, ou il voudra trouver des +informations qu'il aura généré via la commande <tt class="docutils literal"><span class="pre">letsencrypt-auto</span></tt>.</p> +<p>J'ai choisi de faire une règle dans haproxy pour diriger toutes les requêtes +avec le chemin <tt class="docutils literal"><span class="pre">.well-known/acme-challenge</span></tt> vers un <em>backend</em> nginx qui sert +des fichiers statiques (ceux contenus dans +<tt class="docutils literal"><span class="pre">/home/www/letsencrypt-requests/</span></tt>).</p> +<p>Voici la section de la configuration de HAProxy (et <a class="reference external" href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L63-L72">la configuration +complete</a> +si ça peut être utile):</p> +<pre class="literal-block"> +frontend http + bind 0.0.0.0:80 + mode http + default_backend nginx_server + + acl letsencrypt_check path_beg /.well-known/acme-challenge + use_backend letsencrypt_backend if letsencrypt_check + + redirect scheme https code 301 if !{ ssl_fc } !letsencrypt_check + +backend letsencrypt_backend + http-request set-header Host letsencrypt.requests + dispatch 127.0.0.1:8000 +</pre> +<p>Et celle de NGINX:</p> +<pre class="literal-block"> +server { + listen 8000; + server_name letsencrypt.requests; + root /home/www/letsencrypt-requests; +} +</pre> +</div> +<div class="section" id="installation-des-certificats-dans-haproxy"> +<h2>Installation des certificats dans HAProxy</h2> +<p>Vos certificats SSL devraient être générés dans <tt class="docutils literal">/etc/letsencrypt/live</tt>, mais +ils ne sont pas au format attendu par haproxy. Rien de grave, la commande +suivant convertit l'ensemble des certificats en une version compatible avec +HAProxy:</p> +<pre class="literal-block"> +cat /etc/letsencrypt/live/domaine.org/privkey.pem /etc/letsencrypt/live/domaine.org/fullchain.pem &gt; /etc/ssl/letsencrypt/domaine.org.pem +</pre> +<p>Et ensuite dans la configuration de haproxy, pour le (nouveau) <em>frontend</em> https:</p> +<pre class="literal-block"> +bind 0.0.0.0:443 ssl no-sslv3 crt /etc/ssl/letsencrypt +</pre> +<p>Faites bien attention à avoir un <em>frontend</em> <cite>https</cite> pour tous vos sites en HTTPS. +<a class="reference external" 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 !</p> +</div> +<div class="section" id="automatisation"> +<h2>Automatisation</h2> +<p>Pour automatiser un peu tout ça, j'ai choisi de faire ça comme suit:</p> +<ul class="simple"> +<li>Un fichier domaine dans <tt class="docutils literal">letsencrypt/domains/domain.org</tt> qui contient le script <tt class="docutils literal">letsencrypt</tt>.</li> +<li>Un fichier d'installation de certificats dans +<tt class="docutils literal"><span class="pre">letsencrypt/install-certs.sh</span></tt> qui s'occupe d'installer les certificats +déjà générés.</li> +</ul> +<p>Et voila ! <a class="reference external" href="https://github.com/almet/infra/">Le tout est dans un dépot github</a>, si jamais ça peut vous servir, tant mieux !</p> +</div> +Ateliers d'autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de …</li></ul></blockquote><p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, +envers mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins +pour rendre le déchiffrement des messages plus longue, &quot;noyer le +poisson&quot;.</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="http://blog.notmyidea.org/chiffrement.html">Chiffrement</a></p> +</blockquote> +<p>J'ai mis un peu de temps à mettre le pied à l'étrier, mais je ressors +finalement du premier atelier que j'ai co-animé avec geb, auprès d'un public de +journalistes.</p> +<p>Pour cette première édition l'idée était à la fois d'aller à la rencontre d'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'autodéfense numérique.</p> +<p>L'objectif pour ce premier atelier était de:</p> +<ol class="arabic simple"> +<li>Échanger autour des besoins et <strong>faire ressortir des histoires</strong> ou le manque +d'outillage / connaissances à posé problème, dans des situations concrètes;</li> +<li>Se rendre compte des &quot;conduites à risque&quot;, <strong>faire peur</strong> aux personnes formées +pour qu'elles se rendent compte de l'état actuel des 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 appréhender.</li> +</ol> +<div class="section" id="faire-ressortir-les-problemes"> +<h2>1. Faire ressortir les 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 &quot;Groupes d'Interview Mutuels&quot;, +ou &quot;GIM&quot;:</p> +<blockquote class="epigraph"> +<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é vécu.</p> +<p class="attribution">&mdash;«<a class="reference external" href="http://www.scoplepave.org/pour-s-ecouter">Pour s'écouter</a>», SCOP Le Pavé.</p> +</blockquote> +<p>De ces <em>GIMs</em> nous avons pu ressortir quelques histoires, gravitant autour de:</p> +<ul class="simple"> +<li><strong>La protection des sources (d'information)</strong>: Comment faire pour aider +quelqu'un à faire &quot;fuiter&quot; des données depuis l'intérieur d'une entreprise ?</li> +<li><strong>Le chiffrement de ses données</strong>: Comment éviter de faire &quot;fuiter&quot; des données +importantes lors d'une perquisition de matériel ?</li> +</ul> +</div> +<div class="section" id="faire-peur"> +<h2>2. Faire 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'accéder à certaines données. <a class="reference external" href="http://blog.barbayellow.com/">Grégoire</a> m'avait conseillé quelques petites accroches +qui ont ma foi bien marché:</p> +<p>J'ai demandé aux présent.e.s de:</p> +<ul class="simple"> +<li>donner leur mot de passe à voix haute devant les autres: a priori personne ne +le fera;</li> +<li>venir se connecter à leur compte email depuis mon ordinateur. J'ai piégé une +personne, qui est venu pour taper son mot de passe.</li> +</ul> +<p>Cela à été un bon moyen de parler de l'importance des traces que l'on peut +laisser sur un ordinateur, et de la confiance qu'il faut avoir dans le matériel +que l'on utilise, à fortiori si ce ne sont pas les vôtres.</p> +<p>Pour continuer à leur faire peur, après une brève explication de ce qu'est SSL +nous avons montré comment il était facile de scruter le réseau à la recherche +de mots de passe en clair.</p> +</div> +<div class="section" id="proposer-des-solutions-concretes"> +<h2>3. Proposer des solutions concrêtes</h2> +<p>Une fois que tout le monde avait pleinement pris sonscience des problématiques +et n'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 attentes:</p> +<ul class="simple"> +<li>On a expliqué ce qu'était <a class="reference external" href="https://tails.boum.org">Tails</a>, et comment +l'utiliser et le dupliquer.</li> +<li>On a pu faire un tour des outils existants sur Tails, notamment autour de +l'<em>anonymisation</em> de fichiers et la suppression effective de contenus.</li> +<li>Certaines personnes ont pu créer une clé tails avec la persistance de +configurée.</li> +<li>Nous nous sommes connectés au réseau <a class="reference external" href="https://www.torproject.org">Tor</a> et testé +que nos adresses IP changeaient bien à la demande.</li> +<li>Nous avons utilisé <a class="reference external" href="https://crypto.cat">CryptoCat</a> par dessus Tor, afin de +voir comment avoir une conversation confidentielle dans laquelle il est +possible d'échanger des fichiers.</li> +</ul> +</div> +<div class="section" id="retours"> +<h2>Retours</h2> +<p>D'une manière générale, pour une formation de trois heures et demi, je suis +assez content de l'exercice, et de l'ensemble des sujets que nous avons pu +couvrir. Il y a beaucoup de place pour l'amélioration, notamment en amont (j'avais +par exemple oublié d'amener avec moi suffisamment de clés USB pour utiliser +Tails).</p> +<p>La plupart des retours qu'on a pu avoir jusqu'à maintenant sont positifs, et il +y a l'envie d'aller plus loin sur l'ensemble de ces sujets.</p> +</div> +<div class="section" id="la-suite"> +<h2>La suite</h2> +<p>Il y a beaucoup de sujets que nous n'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'après-midi par +exemple).</p> +<p>J'ai choisi volontairement de ne pas aborder le chiffrement des messages via +PGP parce que <a class="reference external" href="https://blog.notmyidea.org/les-problemes-de-pgp.html">je pense que la protection que ce média propose n'est pas +suffisante</a>, mais je suis en train de +revenir sur ma décision: il pourrait être utile de présenter l'outil, à minima, +en insistant sur certaines de ses faiblesses.</p> +<p>Un compte twitter à été créé recemment autour des crypto-party à Rennes, si +vous êtes interessés, <a class="reference external" href="https://twitter.com/CryptoPartyRNS">allez jeter un coup d'œil</a>!</p> +<p>Je n'ai pas trouvé de ressources disponibles par rapport à des plans de +formation sur le sujet, j'ai donc décidé de publier les nôtres, afin de +co-construire avec d'autres des plans de formation.</p> +<p>Ils sont pour l'instant disponibles <a class="reference external" href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The Docs</a>. Tous les retours +sont évidemment les bienvenus !</p> +</div> +Rencontres python francophones, 20152015-11-02T00:00:00+01:002015-11-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2015-11-02:/rencontres-python-francophones-2015.html<p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation …</p><p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation était vraiment impressionnante (merci +, si vous me lisez !). Et puis comme toujours l'occasion de recroiser quelques +copains, et d'en découvrir quelques autres... J'en ai profité pour parler de +Kinto (voici d'ailleurs <a class="reference external" href="http://alexis.notmyidea.org/kinto-pycon/">les slides de la présentation que j'ai faite</a>).</p> +<p>Parmis les conférences qui m'ont marquées, je vous conseille <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-hospital-des-tests-en-prod.html">celle de Benoit +Bryon, sur Hospital</a>, qui parle de +heartbeat, ou de comment tester vos projets en prod, et celle <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-geoalchemy.html">sur Geo Alchemy, +par Éric Lemoine</a>. Et bien sur, <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-cliquet.html">celle +de Mathieu Leplatre sur Cliquet</a>, le +toolkit qui rassemble les bonnes pratiques que nous souhaitons mettre en avant +chez Mozilla services, mais là, je suis tout sauf impartial !</p> +<p>Sinon, il peut être interessant de jeter un coup d'oeil au <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-table-ronde-diversite.html">compte rendu de la +table ronde sur la diversité</a>, si c'est un sujet qui vous +touche. Encore beaucoup de choses à faire sur le sujet, bien sur, mais cette table ronde +était un pas nécessaire dans la bonne direction. Un groupe de travail sur le +sujet est en train de se constituer au sein de l'association.</p> +<p>L'ensemble des notes que j'ai pu prendre sont disponibles dans la section <a class="reference external" href="http://blog.notmyidea.org/category/pyconfr2015.html">PyconFR 2015</a>.</p> +PyconFR 2015 — Assemblée générale2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-assemblee-generale.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes + Marseille +Support pour 2 Django Carrots. +Par rapport au mentoring, très peu de retours, peut etre de nouvelles choses +à faire.</p> +<p>FOSDEM 2015 était complet. Il y avait une salle python tojours pleine. +Dsicussions sur la diversité.</p> +</div> +<div class="section" id="futur"> +<h2>Futur</h2> +<p>Amandine propose d'organiser des soirées à NUMA l'an prochain. +Global code retreat: participation +Migrer le serveur de l'AFPY +Reboot des status: nos pratiques ne sont pas en ligne avec nos status. +Mise en place de mentoring pour python.</p> +<div class="section" id="status"> +<h3>Status</h3> +<p>Comité directeur renouvelé par tiers. Il est composé de 18 personnes. Les +discussions qui sont dans le CD n'en sortent pas, et les discussions sont donc +effectuées en priuvées.</p> +<p>L'idée actuelle serait de réduire le CD de 18 à 9 personnes. Tout le travail +serait fait en dehors du CD. Il est possible de mettre en place un groupe de +travail pour travailler sur l'évolution de la charte.</p> +<p>Il faut faire évoluer les status: ils ne sont pas actuellement bien faits par +rapport à notre utilisation.</p> +</div> +</div> +PyconFR 2015 — Hospital - des tests en prod2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-hospital-des-tests-en-prod.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et +envoi de fichiers).</p> +<p>Pour des applications plus complexes, il y a beaucoup de choses à tester (base +de données, cache, email, etc). Beaucoup de parties sont utiles: reverse +proxy, django, base de données etc.</p> +<p>Lors d'un déploiement, comment faire pour vérifier que tout tourne lorsque tout +est déployé ?</p> +<div class="section" id="comment-faire"> +<h2>Comment faire ?</h2> +<ul class="simple"> +<li>Les tests permettent de tester hors sol.</li> +<li>Le provisionning permet de valider que tout tourne correctement, mais</li> +<li>simplement au démarrage. Les pannes ne sont pas détectées.</li> +<li>Le logging va permettre de detecter les erreurs, mais trop tard.</li> +<li>Le monitoring permet d'avoir une vue de l'exterieur.</li> +</ul> +<p>Hostpital propose de faire des assertions sur la configuration, +l'environnement, <em>en cours de fonctionnement</em>. Ce sont les developeurs qui +ajoutent ces assertions.</p> +<p>Cela peut servir à valider un déploiement, pour etre rassuré une fois que le +déploiement effectué. Cela peut aussi service à surveiller un service et +diagnostiquer les problèmes.</p> +</div> +<div class="section" id="hospital"> +<h2>Hospital</h2> +<dl class="docutils"> +<dt>::</dt> +<dd>pip install hospital</dd> +</dl> +<p>Hospital est un outil en python. On définit des tests, de la même manière que +l'on définit des tests unitaires. On fait des assertions, comme pour les tests +unitaires. Hospital propose des helpers pour les cas courants: +<cite>assert_http_response</cite> ou <cite>assert_ping</cite>.</p> +<p>La vue est une vue de l'intérieur. La différence avec le monitoring est que +l'on teste la connectivité entre les services (exemple d'une requete +elasticsearch qui échoue depuis un service django).</p> +<p>Pour la supervision, les healthchecks sont lancés avec une ligne de commande +<cite>hospital-cli</cite>. Il est possible de lancer également ces tests avec nose ou +py.test.</p> +<p>Il est aussi possible de faire le monitoring avec une API HTTP <cite>hospital +serve</cite>.</p> +<div class="section" id="les-lacunes-de-hospital"> +<h3>Les lacunes de hospital</h3> +<p>Les healthchecks sont fait actuellement en synchrone. Cela peut prendre du +temps. Il pourrait etre interessant de lancer des taches de manière distribuée +/ en paralelle.</p> +<p>Il pourrait etre utile de faire la distinction entre les smoketests et les +diagnostiques: les premiers sont des petits checks qui permettent de dire si ça +marche, de manière très simple. De l'autre coté, les diagnostiques seraient eux +plus fins.</p> +</div> +</div> +<div class="section" id="wrap-up"> +<h2>Wrap up</h2> +<p>Validez votre configuration, la connectivité avec les services externes. Faites +des tests souvent !</p> +</div> +PyconFR 2015 — We don't need your loop2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-we-dont-need-your-loop.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer comment atteindre le resultat.</p> +<p>En python, par exemple, il vaut mieux utiliser <cite>sum</cite> plutôt que de faire +l'addition nous même (pour faire une addition des elements d'une liste).</p> +<p>Actuellement, le compilateur python est lent si on utilise numpy.sum sur des +matrices complexes.</p> +<div class="section" id="comment-aller-plus-vite"> +<h2>Comment aller plus vite?</h2> +<p>Cython est assez compliqué, il faut savoir ce que l'on fait pour optimiser et +écrire du bon code Cython.</p> +<p>Avec pythran, l'intelligence est dans le compilateur, qui permet d'écrire +notemment des boucles correctement.</p> +<p>En donnant plus d'informaitons au compilateur, plutôt que de faire des boucles, +cela lui permet d'avoir un contexte qui lui permet d'optimiser le code.</p> +<p>Par contre, cela veut dire que plus de connaissances sont necessaire pour lire +le code python.</p> +<p>pythran permet de compiler directement vers du C++ sans avoir à changer son +code de base (python). C'est utile pour du code numpy notemment.</p> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<p>Possible de paralelliser de manière explicite <strong>ou</strong> implicite.</p> +<p><strong>C'est très utile pour les gens qui font du &quot;number crunching&quot;. Est-ce que +c'est utile pour d'autres domaines d'application (Web)?</strong></p> +<p>Pas vraiment. CPython est déjà bien fait pour ces cas d'utilisation.</p> +<p><strong>Est-il possible de lancer pythran sans faire de commentaires ?</strong></p> +<p>C'est possible mais cela ne servira pas à grand chose. Il est necessaire de +connaitre le type des objets qui sont utilisés lors des boucles.</p> +<p><strong>Est-ce que vous songez à un compilateur à la volée ?</strong></p> +<p>De gros efforts ont été faits dernièrement pour diminuer le temps de +compilation. Mais pour une fonction qui renvoie None prends de l'ordre d'une +seconde ou une demi seconde. Ce n'est pas très utile pour un compilateur à la +volée puisqu'il faudrait des gains de perfs supérieurs à cela.</p> +</div> +PyconFR 2015 — Cliquet2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-cliquet.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous demande de faire des APIs, tout +le temps.</p> +<p>Souvent, les mêmes questions sont à l'ordre du jour. Heartbeat, codes +d'erreurs, etc. L'inventaire de tout ce qui est attendu d'une API, au dela de +ce qui est la valeur ajoutée du service.</p> +<p>Définition d'un protocole. Définir une API REST n'est pas aussi évident qu'il +y parait. Il faut définir les formats de JSON, les status, etc.</p> +<p>La réutilisation de certaines protocoles existants était possible (Sync, en +production depuis quelques années).</p> +<p>Réutiliser du code nous permettait et faire un template pour démarrer plus +facilement, pour se concentrer sur le métier de l'API. Puisque les besoins ne +sont pas toujours les mêmes, avoir une boite à outil permet de choisir ce que +l'on souhaite.</p> +</div> +<div class="section" id="protocole"> +<h2>Protocole</h2> +<ul class="simple"> +<li>Création d'un protocole qui respecte les bonnes pratiques. CORS, avoir les +bons codes de status, arrêter de se poser toujours les mêmes questions. +Contrairement à ce qu'on imagine, la spécification HTTP n'est pas si facile +à suivre. Plutôt que d'écrire un document, un toolkit à été créé.</li> +<li>Les ops ont besoin de quelques endpoints: un heartbeat (monitoring) des +endpoints de batch, un endpoint &quot;hello&quot;, pour connaitre le type de service, +ses URLs etc.</li> +<li>La service renvoie toujours un JSON avec la description de l'erreur. Cela +permet d'avoir tout le temps la même gestion des erreurs. Utilisation du +header &quot;backoff&quot; qui permet de demander aux clients d'arreter de faire des +requetes durant une durée spécifée par le serveur.</li> +<li>Pour les resources &quot;REST&quot;, quelques règles sont définies: quel est le format +du JSON, quel est la syntaxe du querystring pour filtrer, ordonner, gérer les +opérations concurentes, etc.</li> +<li>Comment la validation fonctionne ? La pagination ? La définition des +permissions ? Les erreurs.</li> +</ul> +<p>Définir le protocole une seule fois permet de se mettre d'accord avec les Ops. +On ne créé pas une RFC pour l'instant, il faut qu'on valide ce qu'on a fait, +il est necessaire de valider notre approche.</p> +</div> +<div class="section" id="toolkit"> +<h2>Toolkit</h2> +<p>La stack en place est basée sur Pyramid et Cornice. Autre chose aurait pu petre +utilisé. Mais pyramid à été choisi pour son approche simpliste et qui permet de +rajouter de la complexité au fur et à mesure.</p> +<p>Cliquet propose de faire l'ensemble du boilerplate, la lecture du protocole, et +vous permet de créer les backends souhaités.</p> +<p>Il est possible de choisir les methodes HTTP acceptables, les URLs à utiliser +etc. Tweaker l'API est possible, la chose qui reste toujouts stable est le +protocole.</p> +<p>le toolkit vise à faire quelque chose de pluggable. Tout est controllable +depuis la configuration.</p> +<p>Pour le deploiement, cela veut dire que le monitoring est déjà connecté, et il +est possible de changer la configuration depuis un fichier <cite>.ini</cite>.</p> +<p>Il est aussi possible de faire du profiling en ajoutant deux lignes de code, +qui permet de générer des graphs qui permettent d'identifier les goulots +d'étranglement.</p> +</div> +<div class="section" id="microservices"> +<h2>Microservices ?</h2> +<ul class="simple"> +<li>Cliquet apporte une manière standard de surveiller, deployer, configurer des +services.</li> +<li>Il est possible de se focaliser sur la logique de l'application, en faisait +une abstraction des backends, etc.</li> +<li>Le fait de figer l'API permet d'avoir des clients génériques que l'on peu +réutiliser d'une application à l'autre.</li> +</ul> +</div> +<div class="section" id="cliquet-est-utilise-pour"> +<h2>Cliquet est utilisé pour</h2> +<ul class="simple"> +<li>Kinto, un service générique de stpclage de données.</li> +<li>Syncto, un proxy pour Sync en utilisant le protocole.</li> +<li>La liste de lecture, service qui à été shutdown.</li> +</ul> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<ul class="simple"> +<li><strong>Qu'est-ce qui est pluggable ?</strong> Les choix qui sont fait dans cliquet +concernent le protocole. Le toolkit est lui fait de manière &quot;pluggable&quot;. Il +est par exemple possible de changer le backend, l'authentification, le cache +ou les permissions.</li> +<li><strong>Quelles sont les parties non standard? Est-il prévu de representer ça via +une RFC ?</strong> Le seul sujet qui pourrait etre utile dans une RFC serait de +définir les headers attendus pour la validation et l'écriture +concurrentielle. L'ensemble de ce qui est proposé est standard.</li> +<li><strong>Existe-il un client JavaScript, comme pour Kinto ?</strong> Actuellement, non. Par +contre, Kinto.js est prévu pour que la partie commune entre les APIs (le +protocole) peut etre extrait.</li> +</ul> +</div> +PyconFR 2015 — Geoalchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-geoalchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des données qui +representent des objets dans un espace géométrique.</p> +<ul class="simple"> +<li>Il est possible d estocker des ligne,s de polygones, des points. Il y a une +colonne géometrie pour stocker ces données.</li> +<li>Il y a aussi des fonctions qui permettent de travailler sur ces données +(transfomrations, projections, etc).</li> +<li>Indexs géographiques qui permettent de faire des recherches de manière +performante.</li> +</ul> +<div class="section" id="postgis"> +<h2>POSTGIS</h2> +<p>POSTGIS s'appuie sur postres pour offrir des types géographiques, des fonctions +et des indexes (R-Tree), qui permettent de ranger les géométries dans des +&quot;boites englobantes&quot;.</p> +<p>Pour créer une base de données postgis, il faut faire un &quot;create extension +postgis&quot;, ce qui installe tout ce dont on a besoin.</p> +<p>il est possible d'apeller <cite>GEOMETRY(POINT)</cite> par exemple.</p> +<p><cite>ST_GeomFromText('POINT(lat long)')</cite> permet de convertir un point dans un objet +geometrie interne à postgres.</p> +<p><cite>ST_DWithin</cite> permet de trouver les personnes qui sont autour d'un rayon donné.</p> +<p>L'ensemble des fonctions proposées par postgres commencent par <cite>ST_*</cite></p> +</div> +<div class="section" id="sqlalchemy"> +<h2>SQLAlchemy</h2> +<p>Il s'agit d'une bote à outil qui permet de faire des requetes de manière +simple. Il y a une philosophie forte.</p> +<ul class="simple"> +<li>Il ne sohaite pas cacher la base de données</li> +<li>C'est un language pour faire du SQL en python</li> +<li>Rien n'est caché.</li> +<li>Fourni un vocabulaire riche pour générer le SQL</li> +<li>L'objectif est de changer la manière dont on pense à SQL, redonner le gout du +SQL aux developeurs.</li> +</ul> +<p>Deux parties: +- ORM +- CORE</p> +<p>Il est possible d'utiliser simplement le core si l'on sohaite (sans utiliser +l'ORM)</p> +<div class="section" id="core"> +<h3>Core</h3> +<p>Il est possible d'utiliser SQL Alchemy pour générer les tables à l'origine. +Core permet d'utiliser des tables, et d'executer une insertion, depuis python. +Il est possible de representer les requetes avec des methodes chainées +<cite>select().where()</cite> etc.</p> +<p>Le &quot;core&quot; ne fait pas de mapping du tout, il manipule des Tables SQLA +directement.</p> +</div> +<div class="section" id="orm"> +<h3>ORM</h3> +<p>L'ORM fait, lui, du mapping. C'est cette couche que l'on va utiliser dans une +application Web complexe par exemple.</p> +<ul class="simple"> +<li>il est possible de travailler avec une session <cite>Session()</cite> puis on effectue +des opérations et on <cite>commit()</cite>.</li> +</ul> +<div class="section" id="geoalchemy"> +<h4>GeoAlchemy</h4> +<ul class="simple"> +<li>Créé en 2009, pour supporter uniquement postgis.</li> +<li>Depuis, d'autres bases de données (MySQL, Spatialite, MySQL server) etc.</li> +<li>Réécriture depuis grace à la nouvelle API de SQLAlechemy, mais perte du +support d'autres backends.</li> +<li>Finalement, retour sur POSTGIS uniquement, pour évite d'avoir à supporter les +différences de tous les backends.</li> +</ul> +</div> +</div> +</div> +<div class="section" id="features"> +<h2>Features</h2> +<p>Très simple de s'intégrer avec les features de POSTGIS, par exemple en +déclarant une colonne en tant que &quot;Géometrie&quot;.</p> +<p>Exemple: session.query(Lake).filter(Lake.geom.ST_Buffer(2).ST_Area) permet de +lister l'ensemble des lacs avec une aire de 2 au moins.</p> +<p>S'intègre bien avec des services existants (shapely, pyramid, etc).</p> +<p>Utilisation de geojsondumps pour representer des features en geojson.</p> +</div> +<div class="section" id="status"> +<h2>Status</h2> +<p>Le projet est completement documenté sur read the docs. La documentation est +assez complete et solide. Il est intégralement testé, sur differentes versions +de python, sqlalchemy et postgres.</p> +<dl class="docutils"> +<dt>3 ou 4 developeurs actifs sur le projet, ça fonctionne plutôt bien. Pour</dt> +<dd><p class="first">contribuer, il est possible de faire cela sur github.</p> +<p class="last">Slides de la presentation sur <a class="reference external" href="http://erliem.net/talks/pyconfr2015">http://erliem.net/talks/pyconfr2015</a></p> +</dd> +</dl> +<p>Resources:</p> +<ul class="simple"> +<li><a class="reference external" href="https://pypi.python.org/pypi/Shapely">https://pypi.python.org/pypi/Shapely</a> - Manipulation and analysis of geometric +objects in the Cartesian plane.</li> +</ul> +<p>Question:</p> +<ul class="simple"> +<li>Dans les exemples geoalchemy, les données geométriques sont passées sous +forme de chaine. Est-ce normal ? Oui.</li> +<li>Les rasters sont également supportés.</li> +</ul> +</div> +PyconFR 2015 — SQL Alchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-sql-alchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent …</li></ul><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent nos tables, et les liaisons entre les +tables, en utilisant <cite>relationship</cite> (qui à énormement d'attributs).</li> +<li>On définit quelles osnt les clés étrangères entre les tables.</li> +<li>Puis on va définir les attributs qui sont liés entre les tables +(relationship).</li> +<li>Pour définir des relations entre les Tables, il est possible d'utiliser des +chaines de caractère <cite>relationship('OtherTable')</cite>.</li> +<li>La session es tun concept important.</li> +<li>Lire efficacement. Attention à ne pas faire énormement de requetes avec +L'ORM.</li> +</ul> +<p><strong>Performance SQL</strong></p> +<ul class="simple"> +<li>Générer le SQL (python)</li> +<li>Ne pas faire énormement de petites requetes.</li> +</ul> +<p>Il est possible de demander à la session de charger les données qui sont +associées. (avec un joinedload). Par defaut, cela risque de charger +l'ensemble des colonnes.</p> +<p>Pour la générer avec SQLAlchemy, il est possible de faire un +<cite>.query(Table).join(Table).join(Table2).filter_by(field=value)</cite></p> +<p>En pratique, le mieux est de lister clairemnet le nom des tables</p> +<p>2ème partie:</p> +<p>Pour de l'import de données,</p> +<ul class="simple"> +<li>first() fait une requete SQL. A éviter dans les boucles</li> +<li>session.flush() c'est quand la session écrit en base tout ce qui est en cours +dans la transaction. Par default, la session fait un flush avant chaque +requete.</li> +<li>une option backçpopulates mets à jour la liste des documents associés à une +table qui à une foreign key. +backref modifie implicitement la classe associée. Il est recommandé +d'utiliser <cite>back_populates</cite> et non pas <cite>backref</cite>.</li> +<li><cite>subqueryload</cite> permet de générer une requete séparée plutôt qu'une jointure.</li> +</ul> +PyconFR 2015 — Table ronde diversité2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-table-ronde-diversite.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et …</strong></p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et Alexia).</strong></p> +<p><strong>JP — Pourquoi</strong>:On a eu une discussion sur la ML de l'AFPy suite à une décision +de l'afpy de ne pas financer un évènement qui n'était pas ouvert à tous-tes +(restreint aux femmes et personnes trans). Cette décision à été prise +conformément a la charte de l'AFPY qui dit que les evènements promus sont +ouverts à tous. Ce qui veut dire que cela n'inclue pas les évènement exclusifs. +(Je n'ai jamais demandé de financement à l'AFPY. J'ai juste demandé la +diffusion sur la mailing interne de la création de Pyladies Paris. Je ne sais +pas d'où vient cette histoire de financement! Pyladies Paris)</p> +<p>Suite à ça, une modification de la charte à été proposée. Demain matin, la +modification de la charte sera proposée lors de l'AG. Suite à la proposition de +modification, les discussions se sont enchainées, avec des points de vue +divergents. Cette table ronde vient donc dans ce contexte. +I +BD d'introduction: +<a class="reference external" href="http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/">http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/</a></p> +<div class="section" id="tour-de-presentation"> +<h2>Tour de présentation:</h2> +<ul class="simple"> +<li>Laurence directrice de l'école qui accueille d'évènement, docteure en Maths. +Contente de voir que la tendance s'inverse un peu (de plus en plus de filles).</li> +<li>Vivianne, maitre de conférence en informatique à paris sud. Études dans un +milieu assez masculin. Dans le domaine du developpement pour la recherche, ou +des environnements techniques, c'est très masculin. Essaye de voir comment +faire pour que les filles s'intéressent plus a l'informatique.</li> +<li>Amandine Neyrolle, diplomée d'école de commerce (plutot 50% fille/garcon dans +ces fillières). Intégrée le monde de l'informatique par la suite en autodidacte +et formations. Rencontré la créatrice de pyladies et discuté de ces questions.</li> +<li>Laurenne Chelan, organistrice des django girls bdx. Nouvelle dans cet +univers. Travaille dans des musées de science depuis quelques années. L'idée de +dj girs bdx part de l'idée de découvrir le code. Les djangogirls viennent de +berlin, créé par ???.</li> +<li>Alexia Sumois. organisatrice de django girls bdx. Nouvelle dans le milieu du +code. Les conférences d'aujourd'hui on donné envie d'apprendre.</li> +<li>Anna, créatrice de 4ideas. Essaye de faire en sorte que plus de femmes +viennent dans l'IT. En reconversion pro. Choisi ce domaine il ya un an. Trouve +que ce sujet est vraiment extremement important, et sur lequel il est possible +de faire quelque chose, et d'influencer positivement. L'idée étant de +démystifier l'IT, et laisser le choix aux femmes de choisir cette profession.</li> +<li>Jean Phillipe Campguillhem, secrétaire de l'AFPY</li> +</ul> +</div> +<div class="section" id="pourquoi-django-girls"> +<h2>Pourquoi Django Girls ?</h2> +<p><strong>Alexia</strong> — Le déclencheur de cette aventure vient des goodies (!). La décoration +de l'évènement a attiré l'attention et donné envie de creuser.</p> +<p><strong>Laurenne</strong> — C’est pour ça qu’on se pose la question « comment attirer ces +publics, ces personnes-là ? », importance de l’image qu’on renvoie. Ce n’est +pas tant une question de genre, mais d’initié·e·s : on a souvent peur d’entrer +dans ce milieu. Django-girls vise une plus grande bienveillancet Carte de la +convivialité, chaleureux, et facile d'accès pour les débutants. Tout est livré +clé en main, et l'évènement est facile à prendre en main. Le 28 oct à bordeau, +recherche de coachs / sponsors pour l'évènement. +<a class="reference external" href="http://djangogirls.com/bordeaux">http://djangogirls.com/bordeaux</a></p> +<p><strong>Laurence</strong> — Aspect macho présent dans la communication de l’école (pas +forcément explicite). « On a toujours dessiné des symboles de métiers +identifiés par des garçons »</p> +<p><strong>Laurenceu</strong> — Il y a une partie d'inconscient dans l'ensemble de +l'enseignement qui est donné. Il y a peu de candidates qui essayent. Pas +question de discrimination positive puisque cela a des effets indésirables +(communautarisme). La question est tout de meme posée, mais il est impensable +d'accepter des gens grace / a cause de leur genre. L'ambiance change lorsqu'il +y a de la mixité. À la recherche d’idées pour faire venir plus de candidates.</p> +<p><strong>Viviane</strong> — En tant que femme, on reçoit en permanence le message que ce +métier n’est pas fait pour nous. Ces messages ont un impact, le résultat est +que les filles ne vont pas dans les écoles d’informatiques. Il faut aller +convaincre les jeunes filles que c’est aussi fait pour elles. Ça passe par +changer les plaquettes. Il faut réussir à changer l'image existante des confs / +communautés. Un développeur peut aussi etre une développeuse. Dans l'assemblée, +on se rend compte que certaines femmes sont en dehors du parcours. Il faut +qu'en tant que communauté on soit capables d'accueillir les nouvelles / +nouveaux. C’est en ayant une diversité qu’on parviendra à changer l’image du +métier. Les rencontres pyladies permettent aussi de rencontrer d'autres femmes +qui ont les mêmes problématiques. Accompagner les nouvelles entrantes pour +trouver du boulot, découvrir l'AFPY et les initatives existantes. Les +initiatives existantes django girls / pyladies est très important.</p> +<p><strong>Amandine</strong> — C’est pourquoi ce genre d’évènements non-mixtes permet de faire +des séances de rattrapage pour permettre d’intégrer la communauté dans son +ensemble. C’est le point clé pour faire accepter ce genre d’initiatives.</p> +<p><strong>Laurenne</strong> — DjangoGirls et Django Carrots ne sont pas des évènements +excluants. Ils sont simplement orientés en priorité aux femmes. Sur la question +de « comment amener des jeunes filles vers ces études-là », ça se joue bien +avant, dans l’enfance, bien avant l’école. cf les jeux genrés. Il faut +travailler à ce niveau-là.</p> +<p><strong>Anna</strong> — Pour illustrer ce que dit Laurenne, l'importance des clichés +existants. Avant le mi-80s, il y avait autant de femmes que dans d'autres +domaines. Si on regarde les stats, dans tousles autres domaines, le pourcentage +de femmes augmente. Et en IT, en 84 il y a un pic qui inverse la tendance. Ce +sont des stats américaines. A priori cela s'applique aussi en Europe. En IT, la +culture qui à été créé autour des hackers qui ont des super pouvoirs, mangent +des pizzas, etc. Ces clichés ont influencé le monde. Nous ne sommes pas +complètement autonomes, et nous sommes influencés par la culture autour de +nous. Les dommages qui ont été fait dans le domaine de l'IT sont graves, et il +est important de renverser la tendance. La question de l'image est centrale. +Les personnes ont besoin de place pour faire leurs évènements. Il est important +de comprendre et respecter que les autres veuillent faire de la discrimination +positive. Ce sont des actions qui sont supportées par la France. Ce sont des +valeurs qui sont beaucoup lus fortes en France qu'ailleurs (Anna souligne +qu'elle est Polonaise). On devrait respecter ce droit.</p> +<p><strong>Vivianne</strong> — Certaines evènements sont non-mixtes (pour les personnes qui +s'identifient comme des femmes). Ce ne doit pas etre les seules initiatives. +Elle est pour la mixté. PyLadies est assez spécifique : ce n’est pas de la +formation, mais principalement des évènements tournés autour du réseau. Il est +important d'avoir un endroit ou les jeunes femmes seront moins imprésionnées. +Les situations exposées dans la BD sont réelles. De se retrouver dans un +environnement où elles sont sûres qu’elles ne subiront pas de micro-agressions.</p> +<p><strong>Laurence</strong> — Témoignage d'une mère qui dit à sa fille, en passant devant un +panneau de l'école, mentionnant maths et informatique, et qui dit à sa fille « +oh non, c'est pas pour toi ça » . On dit « attention les garçons, vous devez +être sympas avec les filles ». Les garçons ont envie que ça se passe bien avec +les filles.</p> +<p><strong>JP</strong> — Sans revenir sur les décisions qui ont été prises, nous n'avons pas +dit que nous étions contre ces évènements (à l'AFPY). A plusieurs reprises, +j'ai du faire des blagues sexistes. Évidemment qu'on est mieux ensemble. Pour +revenir sur la discussion de la mailing-list, je me suis rendu compte que +j'avais un regard biaisé. Si on en est la, c'est quil y a énormement de +travail. Que faire, du coup ? En tant qu'hommes ? Qu'association ? Si il est +necessaire de créer une zone de confort / sécurité, c'est qu'il y a une zone +d'inconfort / insécurité qui est forte. Les couleurs, les jolis goodies, sont +le sommet de l’iceberg. Rappel de l'éxistence du Code of Conduct : il y a déjà +eu des incidents par le passé. On passe la parole à Florent, qui est à +l’origine du CoC. Remerciement envers les intervenantes.</p> +<p><strong>Florent (vice secrétaire de l'AFPY)</strong> — Comme le dit JP, un code of conduct +est affiché devant toutes les portes et à l'entrée. Tout le monde n’aimait pas +forcément l’idée d’en avoir, on a fini par trancher. Le but est d’avoir des +endroits safes. Avant d’avoir un CoC, on ne peut pas dire qu’on soit safes, +envers l'ensemble des minorités. On a écrit le CoC en conséquence des +agressions. Aujourd’hui, pas de tolérance pour des comportements qui n’ont pas +lieu d’être (qu’on a définis comme tels). Ça fonctionne sur la dénonciation +lorsque l’on est témoin de ça. On n’a pas vraiment de mal à rencontrer des +femmes, mais plus de mal à faire comprendre qu’elles sont bienvenues. Impact +important de blagues sexistes, qu’on défend comme « c’est pour rire ». Merci de +lire le Code of Conduct. Les blagues sexistes etc. ne sont pas les bienvenues. +Merci de réagir lors de ces cas.</p> +</div> +<div class="section" id="questions"> +<h2>Questions.</h2> +<p><strong>Questiond de Gawel</strong>: Question pour Amandine. Est-ce que tu te sens bien à l'AFPY ? Si non, que faire pour que tu te sente mieux ?</p> +<p>Amandine — Oui je me sens bien, est-ce qu’il y a eu des évènements ? oui, sans +doute mais j’y suis aguerrie, donc je me rends peu compte. Qu’est-ce qu’on peut +faire ? L’idée du CoC est d’aller à l’encontre des comportements négatifs, mais +l’idée derrière est une ouverture à la différence dans son ensemble, promouvoir +l’ouverture à l’autre et à la différence. L’enjeu culturel est d’arriver à +changer d’état d’esprit et d’identifier ces biais cognitifs. Il faudrait pas +qu’on se dise « ho là là, il y a une fille, faut rien dire sinon je vais me +faire taper » Il faut cultiver la différence. et être curieux/se.</p> +<p><strong>Question</strong> : « c’est pas fait pour moi », mais plutôt « je suis mauvais, donc +je dois travailler », on en revient à l’importance de l’éducation. Il faut +continuer de pointer du doigt les problèmes. Je suis aussi membre d’un LUG, +nous sommes entre hommes diplomés blancs de 30 à 40 ans. La réflexion sur les +plaquettes pas accueillantes est pertinente : le site de l’asso est très +masculin.</p> +<p><strong>Question de Bruno</strong>. Pour l’école: quand j’étais étudiant, 20% de filles. +(Aujourd’hui on est partis de 7/8% pour arriver à 15%). Est-ce que les filles +réussissent plus ?</p> +<p>Laurence — on n’a pas de stats, mais elles posent moins de problèmes. Les +filles sont favorisées par les employeurs.</p> +<p>Vivianne — la motivation des filles à la sortie est identique aux garçons, mais +tout n’est pas rose. En entretien par exemple, ils sont faits par des hommes, +mais au niveau des stats, le nombre de femmes qui quittent le milieu est +important. Effort à faire au niveau de la communauté, des entreprises. Schémas +masculins, mais sur le long terme, on subit des agressions. Difficile de rester +dans le métier et faire une carrière intéressante, à compétences/motivation +identiques aux hommes. Il faut en avoir conscience</p> +<p><strong>Question de Benoit</strong>: il y a peut-être une façon de créer des +lieux/évènements protégés, en utilisant ceux qui existent déjà. Est-ce qu’on +peut aller organiser des évènements dans des écoles/lycées, des endroits où les +gens se sentent déjà à l’aise, où les populations sont plus représentées ?</p> +<p>Vivianne — ça se fait. En tant qu’enseignante, dès que j’ai une occasion, que +ce soit pour aller chercher des JF ou des étudiants maths/infos, même si c’est +ouvert à tous, je le fais. Si c’est que des hommes, les femmes n’ont pas envie +d’y aller.</p> +<p>Laurenne — c’est quelque chose qui se fait beaucoup. On met en avant des femmes +chercheuses dès qu’on le peut.</p> +<p><strong>Question d'Alexis</strong> : je suis très content qu’il y ait cette discussion qui +se fasse. Question par rapport aux discriminations positives, qu’on a pu voir +par le passé (notamment lors de conférences). Difficile de dire « on va +préférer des femmes ». Question irrésolue, parce que pour faire évoluer, on a +besoin d'initier quelque chose, d’essayer. Mais ça a un côté dérangeant.</p> +<p>Vivianne — à la PyCon (US), j’ai été impressionnée du nombre de femmes qui +parlaient. On va pas mettre un quota, ça serait stupide, on va forcer personne. +Mais il faut en avoir conscience. Cette année, on est 4 oratrices, y’a du +travail à faire. En tant qu’hommes, il faut aussi se mettre en retrait et +inviter des femmes à en parler à notre place. Faire le pas d'aller faire un +exposé dans une communauté où on ne se sent pas à sa place (même si on lutte +contre) est difficile. Inviter des gens, sans forcément passer par un énorme +processus. Ça passe par des events comme PyLadies.</p> +<p>Anna — pour les personnes par encore convaincues, juste apres le droit de vote +des femmes en 46, à l'assemblée nationale il y avait très peu de femmes. Puis +en 93, 6.1% apres que des mesures aient été prises. Ensuite de femmes puis vers +20% Les choses ne vont pas se changer toutes seules. Il est necessaire d'avoir +du temps pour faire évoluer les choses. Il est important de noter que PyconFR +fait déjà des choses. Et lors de django carrots, je me suis sentie très +accueillie. J'ai eu beaucoup de très bonnes expériences avec des personnes qui +étaient prêtes à aider.</p> +<p>JP — Remerciement pour Rémy qui abat un travail de ouf. C'est grace à Rémy si +il y a django carrots demain. Il faut faire des choses. :-) Merci !</p> +</div> +Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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't actually +trust the software authors but are rather trusting the software distributors +and certificate authorities (CAs).</p> +<p>I'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 come!</p> +<div class="section" id="the-problem-attack-vectors"> +<h2>The problem (Attack vectors)</h2> +<p>Let's try to describe a few potential 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 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 CDN +which delivers the files,</p> +<p>Trusted <em>Certificate Authorities</em> (&quot;governments&quot; or &quot;hacking team&quot;) can also +trick the User Agents (i.e. Firefox) into thinking they're talking to <em>Indie +Hoster</em> even though they're actually talking to a different 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 users.</p> +</div> +<div class="section" id="problem-mitigation"> +<h2>Problem Mitigation</h2> +<p>Part of the problem is solved by the recently introduced <a class="reference external" href="https://w3c.github.io/webappsec/specs/subresourceintegrity/">Sub Resource +Integrity</a> +(SRI). To quote them: &quot;[it] defines a mechanism by which user agents may verify +that a fetched resource has been delivered without unexpected manipulation.&quot;.</p> +<p>SRI is a good start, but isn't enough: it ensures the assets (JavaScript files, +mainly) loaded from a specific HTML page are the ones the author of the HTML +page intends. However, SRI doesn't allow the User Agent to ensure the HTML page +is the one he 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's not automated, but at least it's possible.</p> +<p>For web applications, we don't have such a mechanism, but it should be +possible. Consider the following:</p> +<ul class="simple"> +<li><em>App Authors</em> publish a new version of their software; They provide a hash of +each of their distributed files (including the HTML files);</li> +<li><em>Crypto Experts</em> audit these files and sign the hashes 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're signed by a trusted +party.</li> +</ul> +</div> +<div class="section" id="chosing-who-you-trust"> +<h2>Chosing who you trust</h2> +<p>In terms of user experience, handling certificates is hard, and that's where +the community matters. Distributions such as <a class="reference external" 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't verified.</p> +<p>But, as highligted earlier, CAs are hard to trust. A new instance of the same +CA system wouldn'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 of).</p> +<blockquote class="epigraph"> +<p>[...] 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 CA scandals. Both schemes can also be attacked if the +authority does not verify keys before vouching for them.</p> +<p class="attribution">&mdash;<a class="reference external" 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 reliable:</p> +<blockquote class="epigraph"> +<p>Melara et al proposed CONIKS, using a series of chained commitments to Merkle +prefix trees to build a key directory [...] for which individual users can +efficiently verify the consistency of their own entry in the directory +without relying on a third 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 self-auditing.</p> +<p class="attribution">&mdash;<a class="reference external" 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'm pretty sure +this design has many security problems attached to it.</p> +<p>However, that's a problem I would really like to see solved one day, so here +the start of the discussion, don't hesitate to <a class="reference external" href="/pages/about.html">get in touch</a>!</p> +</div> +<div class="section" id="addendum"> +<h2>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'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 this.</p> +<p>A bit like User-Agents do for SSL, but for the actual signature of the files +being viewed.</p> +</div> +Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-06-29:/roles.html<blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de …</p></blockquote><blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de +positions qu’adoptent ses protagonistes et les affects qui y sont liés, +imaginer ensuite des questions à résoudre ou des propositions à travailler +qui soient susceptibles d’enrichir la palette, les couleurs de la fonction +de chacun dans le groupe et les manières qui sont les siennes d’intervenir +et de faire évoluer l’histoire.</p> +<p class="attribution">&mdash;David Vercauteren, <a class="reference external" href="http://micropolitiques.collectifs.net/Role">Micropolitiques des groupes</a></p> +</blockquote> +<p>Réussir la transformation d'un espace compétitif vers un groupe soudé demande +de réaliser quels sont les points forts de chacun au sein d'un groupe.</p> +<p>Une solution évoquée par <a class="reference external" href="http://www.starhawk.org/about/">StarHawk</a>, reprise +par <em>David Vercauteren</em> repose sur l'existence de rôles informels au sein des +groupes et la nécessité de les faire tourner (ainsi que les responsabilités +attachées).</p> +<p>Parmi les rôles principaux, quelques autres citations:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">l'emphase est de mon fait, et je retravaillé très legèrement certains +passages afin d'avoir une lecture plus fluide. Je vous invite à suivre +les liens pour voir les &quot;questions que chaque rôle fait exister&quot;, et +poursuivre la lecture du livre, qui est entièrement disponible en +ligne.</p> +</div> +<div class="section" id="id1"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_0">Les corbeaux</a></h2> +<blockquote class="epigraph"> +<p>Les Corbeaux sont visionnaires […] Ils voient à long terme, et gardent en +ligne de mire les objectifs du groupe. Ils suggèrent de nouvelles directions, +dressent des plans, développent des stratégies et anticipent les problèmes et +les besoins.</p> +<p>Les Corbeaux ont souvent beaucoup d’influence sur le groupe. Si une ou deux +personnes pensent à des plans au long-terme, les autres acquiesceront, +simplement parce qu’ils n’ont pas amené d’autres propositions. <strong>Le groupe +aurait intérêt à considérer ensemble les questions du Corbeau</strong></p> +</blockquote> +</div> +<div class="section" id="id2"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_1">Les graces</a></h2> +<blockquote class="epigraph"> +<p>Les Grâces sont toujours attentives à l’énergie du groupe, prêtes à la +renforcer au moment où elle faiblit, à la diriger et à la canaliser quand +elle est forte.</p> +<p>Elles apportent au groupe […] enthousiasme, énergie, capacité +à s’agrandir. <strong>Elles font en sorte que les gens se sentent bien</strong>, génèrent de +l’enthousiasme pour le groupe, accueillent les nouveaux venus, amènent de +nouvelles personnes. Elles offrent au groupe l’inspiration et génèrent de +nouvelles idées.</p> +</blockquote> +</div> +<div class="section" id="id3"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_2">Les dragons</a></h2> +<blockquote class="epigraph"> +<p>Le dragon permet au groupe de rester connecté à […] l’aspect pratique et +réaliste des choses. […] Le dragon veille aux ressources du groupe, à ses +frontières et donne voix à ses limites.</p> +<p>Questions que fait exister le dragon:</p> +<ul class="simple"> +<li>Notre manière de travailler est-elle viable ?</li> +<li>Nos ressources sont-elles renouvelées ?</li> +<li>Les gens s’épuisent-ils ? Pourquoi ?</li> +<li>Pouvons-nous vraiment nous lancer dans ce projet et le mener à bien +convenablement ?</li> +<li>De quelles frontières avec l’extérieur avons-nous besoin et voulons-nous +?</li> +<li>Comment établissons-nous ces frontières ? Comment nous protégeons-nous +des intrusions ? Invasions ? Distractions ? De ce qui épuise nos énergies +?</li> +</ul> +<p><strong>Les Dragons établissent des frontières qui donnent au groupe un sentiment +de sécurité et des limites qui le rendent viable dans le temps</strong>. Ils peuvent +être perçus comme des rabat-joie, mais ils peuvent gagner l’estime de ceux +qui, dans le groupe, se sentent dépassés et ne peuvent partager l’énergie +des Corbeaux et des Grâces.</p> +<p>Nourrir les Dragons peut permettre au groupe de se maintenir dans le temps. +Mais une fois encore, si ce rôle ne tourne pas, même les Dragons risquent +de s’épuiser.</p> +</blockquote> +</div> +<div class="section" id="id4"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_3">Les araignées</a></h2> +<blockquote class="epigraph"> +<p>Le centre d’un groupe peut consister en un « cœur spirituel », <strong>un but ou une +vision commune</strong>, ou peut se manifester à travers une personne. Dans les modes +de pensée hiérarchique, le professeur ou le gourou occupe le centre du +réseau. […]</p> +<p>Dans les groupes non-hiérarchiques, certaines personnes peuvent être perçues +comme centrales : en disposant des informations dont les autres ont besoin, +en étant le point de contact pour les autres.</p> +<p>Une Araignée est toutefois plus efficace en ne monopolisant pas la +communication et les informations mais en posant les questions susceptibles +de créer et de renforcer un véritable réseau d’interactions complexes.</p> +</blockquote> +</div> +<div class="section" id="id5"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_4">Les serpents</a></h2> +<blockquote class="epigraph"> +<p>Les serpents cultivent une attention particulière à la manière dont les gens +se sentent. […]</p> +<p>Les serpents sont au courant de ce qui se murmure dans les couloirs, des +conflits naissants, et les mettent sur la place publique, là où ils +pourraient aider à une médiation, à une résolution du problème. […]</p> +<p>Les serpents transgressent les lois du Censeur, <strong>parlent des non-dits, mettent +en évidence ce que d’autres ne voient pas ou préfèrent garder caché</strong>. […]</p> +<p>Les serpents peuvent diminuer l’antipathie dont ils font l’objet s’ils +prennent la peine de poser des questions au groupe et non d’apporter des +analyses.</p> +</blockquote> +<p>Ainsi, il est possible de se rendre compte de la complexité et de l'importance +d'une position ou d'une autre, et de les faire évoluer ensemble, en prenant en +compte leur impact positif sur le groupe.</p> +<p>Il est par exemple possible, après avoir expérimenté des rôles, de questionner +leur pertinence et d'établir des pistes d'amélioration en enlevant une part +importante d'affect personnel qui parfois empêche des discussions +constructives.</p> +<p>Je n'ai pour l'instant pas pu expérimenter l'évolution des rôles au sein d'un +groupe donné, mais je peux d'ores et déjà me rendre compte que selon les +groupes et selon les moments je n'ai pas le même rôle (tour à tour dragon, +araignée et grace, parfois corbeau, rarement serpent)</p> +<p>Aussi, il semble que le groupe doive souhaiter l'établissement d'un +environnement <em>horizontal</em>, avec une considération partagée de la direction que +le groupe souhaite prendre pour qu'un tel dispositif ait du sens.</p> +</div> +Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois …</p><blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois passé l'euphorie du &quot;il faut utiliser PGP pour l'ensemble de nos +communications&quot;, j'ai réalisé lors de discussions que PGP avait plusieurs +problèmes, parmi ceux-ci:</p> +<ul class="simple"> +<li>Les <em>meta données</em> (y compris le champ &quot;sujet&quot; de la conversation) sont quand +même échangées en clair (il est possible de savoir qu'un message à été échangé +entre telle et telle personne, a telle date);</li> +<li>PGP 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 chiffrée;</li> +<li>Il est facile de connaître votre réseau social avec PGP, puisque tout le +principe est de signer les clés des personnes dont vous validez l'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 PGP 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 &quot;sécurisée&quot; (HTTPS). Tout le monde peut donc voir ces échanges et +savoir de qui vous cherchez la 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 clés).</li> +</ul> +<p>Je suis en train de creuser à propos les alternatives à PGP, par exemple <a class="reference external" href="https://pond.imperialviolet.org/">Pond</a>, qui lui ne construit pas par dessus un +standard déjà établi, et donc n'hérite pas de ses défauts (mais pas non plus de +son réseau déjà établi).</p> +<p>En attendant, quelques bonnes pratiques sur PGP ;)</p> +<div class="section" id="bonnes-pratiques"> +<h2>Bonnes pratiques</h2> +<p>Il est en fait assez facile d'utiliser PGP de travers. Riseup à fait <a class="reference external" href="https://help.riseup.net/en/security/message-security/openpgp/best-practices">un +excellent guide</a> +qui explique comment configurer son installation correctement.</p> +<ul class="simple"> +<li>J'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 oubliez.</li> +<li>Générez des clés RSA de 4096 bits, en utilisant sha512;</li> +<li>Il faut utiliser une date d'expiration de nos clés suffisamment proche (2 +ans). Il est possible de repousser cette date si nécessaire, par la suite.</li> +</ul> +<p>Parmi les choses les plus frappantes que j'ai rencontrées:</p> +<ul class="simple"> +<li>Utiliser le <em>flag</em> <cite>–hidden-recipient</cite> avec PGP pour ne pas dévoiler qui est +le destinataire du message;</li> +<li>Ne pas envoyer les messages de brouillons sur votre serveur, ils le seraient +en clair !;</li> +<li>Utilisez HPKS pour communiquer avec les serveurs de clés, sinon tout le +trafic est en clair.</li> +</ul> +<p>Le <a class="reference external" href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils de +chiffrement d'échanges de messages et de VPN simples à utiliser, encore quelque +chose à regarder.</p> +<p>Enfin bref, y'a du taf.</p> +</div> +Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui …</p><blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui n'étaient bien souvent que des +envies passagères.</p> +<p>Il est arrivé que quelqu'un m'ait demandé de le faire, et que j'y prenne du +plaisir, ou que je le fasse simplement pour moi et que d'autres y trouvent leur +compte, mais il s'agit nécessairement de projets non <em>commandités</em> par l'extérieur.</p> +<p>Encore un signal dans la direction du travailler moins, cette fois ci pour +être plus créatif.</p> +<img alt="Soupa'Soups." src="https://blog.notmyidea.org/images/soupasoups.jpg" /> +Simplifier les preuves d'identités2015-05-11T00:00:00+02:002015-05-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.html<p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la …</p><p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la clé publique que +j'utilise est réellement la mienne.</p> +<p>Traditionnellement, il est nécessaire de faire signer ma clé publique par +d'autres personnes, via une rencontre en personne ou des échanges hors du +réseau. C'est par exemple ce qui est réalisé lors des <a class="reference external" href="https://fr.wikipedia.org/wiki/Key_signing_party">Key Signing parties</a>.</p> +<p>Une manière simple d'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 personne.</p> +<p>PGP propose un mécanisme de signature des clés d'autrui, une fois celles ci +validées, ce qui permet de placer sa confiance dans les signataires de la clé.</p> +<p><a class="reference external" 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'il est possible +d'utiliser différents moyens afin de prouver l'identité des personnes. Par +exemple, leurs comptes Twitter, GitHub ou leurs noms de domaines. De la même +manière qu'il est possible de signer (valider) les clés de nos amis, il est +possible de les &quot;tracker&quot; selon le jargon de keybase.</p> +<p>Donc, en somme, <em>Keybase.io</em> est un annuaire, qui tente de rendre plus facile la +création de preuves. Bien.</p> +<div class="section" id="quelques-points-d-ombre"> +<h2>Quelques points d'ombre</h2> +<p>Il s'agit d'une <em>startup</em> américaine, domiciliée dans le Delaware, qui se trouve être +un des paradis fiscaux qui <a class="reference external" 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 class="reference external" href="https://github.com/keybase/keybase-issues/issues/1569">j'ai ouvert un ticket +sur GitHub pour en savoir plus</a> (après tout, le fait +d'être un paradis fiscal permet peut-être d'échapper à certaines lois sur la +requêtes de données). D'autant plus étonnant, la startup n'a pour l'instant <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/788">pas +de *business model*</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 là).</p> +<p>Le service (bien qu'en Alpha), n'est pas mis à disposition sous licence libre, +ce qui pour l'instant empêche quiconque de créer son propre serveur Keybase. +<a class="reference external" href="https://github.com/keybase/">Une partie des composants, cependant, le sont (open source)</a>.</p> +<p>J'ai du mal à croire en des initiatives qui veulent sauver le monde, mais dans +leur coin, je ne comprends pas pourquoi il n'y à pas de documentation sur +comment monter son propre serveur, ou comment les aider à travailler sur la +fédération. Mais bon, c'est pour l'instant une initiative encore fraîche, et je +lui laisse le bénéfice du doute.</p> +<p>Sur le long terme, une infrastructure comme <em>Keybase.io</em>, devra évidemment être +<a class="reference external" href="https://github.com/keybase/keybase-issues/issues/162">distribuée</a>.</p> +<blockquote class="epigraph"> +<p>We'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'd be so happy to get this +right.</p> +<p class="attribution">&mdash;<a class="reference external" href="http://chris.beams.io/posts/keybase/">Chris Coyne, co-founder of Keybase</a></p> +</blockquote> +<p>Afin de se &quot;passer&quot; de leur service centralisé, les preuves générées (qui sont +la force du système qu'ils mettent en place) pourraient être exportées sur des +serveurs de clés existants. C'est quelque chose <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/890">qu'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'on s'y attarde un brin.</p> +<p>Par ailleurs, <a class="reference external" href="https://leap.se/nicknym">d'autres projets qui visent des objectifs similaires</a> existent, via le projet LEAP, mais je n'ai pas +encore creusé.</p> +</div> +Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html<blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi …</p></blockquote><blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi est trop faible ou construit d'une +manière trop prédictible, cette attaque par la force pourrait se revéler +fructueuse en essayant toutes les possibilités.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://www.eff.org/wp/defending-privacy-us-border-guide-travelers-carrying-digital-devices">The Electronic Frontier Foundation</a> (traduction de mon fait)</p> +</blockquote> +<p>Comprendre les concepts et l'écosystème qui permettent d'avoir une vie +numérique chiffrée n'est pas quelque chose d'aisé. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Plusieurs</a> <a class="reference external" 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 existants.</p> +<blockquote class="epigraph"> +<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 système.</p> +<p class="attribution">&mdash;La page de manuel de GPG.</p> +</blockquote> +<p>Une phrase de passe devrait:</p> +<ul class="simple"> +<li>Être suffisamment longue pour être difficile à deviner;</li> +<li>Ne pas être une citation connue (littérature, livres sacrés etc);</li> +<li>Difficile à deviner même pour vos proches;</li> +<li>Facile à se souvenir et à taper;</li> +<li>être unique et non partagée entre différents sites / applications etc.</li> +</ul> +<p>Une des techniques consiste à utiliser des mots du dictionnaire, sélectionnés de +manière aléatoire, puis modifiés.</p> +<div class="figure"> +<img alt="XKCD sur la force des mots de passe." src="https://imgs.xkcd.com/comics/password_strength.png" /> +</div> +<p>Micah Lee <a class="reference external" 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 longues.</p> +<div class="figure"> +<img alt="Capture d'écran du logiciel de génération et de mémorisation des phrases de passe." src="{filename}/static/passphrases.png" /> +</div> +<p>Oui, ce n'est pas aussi simple que ce qu'il y parait. Pour ma part, j'ai une +copie en local de mes clés, dans un fichier chiffré avec une autre clé que j'ai +généré pour l'occasion et que je ne partagerait pas. J'ai par ailleurs +<a class="reference external" href="https://github.com/jamessan/vim-gnupg">configuré</a> mon éditeur de texte pour +pouvoir chiffrer les documents textes par défaut.</p> +<p>J'ai donc regénéré une nouvelle fois mes clés de travail et personnelles, en +utilisant des phrases de passe plus complexes.</p> +<p>Reste encore la question de la sauvegarde de ces clés privées de manière +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.</p> +Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-08:/chiffrement.html<blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise …</strong></li></ul></blockquote><blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise sous surveillance de pans entiers de la vie politique, syndicale, +militante</strong>, mais aussi économique, scientifique, etc. ;</li> +<li>Légalisation massive de pratiques illégales des services de +renseignement et <strong>introduction de techniques de surveillance de masse +des communications électroniques</strong> ;</li> +<li><strong>Absence de contrôle réel et indépendant</strong> a priori par la future +CNCTR, et recours des citoyens illusoires ;</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="https://www.laquadrature.net/fr/lassemblee-nationale-vote-la-surveillance-de-masse-des-citoyens-francais">La Quadrature du Net - L'Assemblée nationale vote la surveillance de +masse des citoyens français !</a></p> +</blockquote> +<p>Je m'étonne que <a class="reference external" href="https://fr.wikipedia.org/wiki/R%C3%A9v%C3%A9lations_d%27Edward_Snowden">les révélations d'Edward Snowden</a> — qui +ont démontré que la plupart des communications électroniques et téléphoniques +pouvaient être scrutés par la NSA, l'agence de sécurité Américaine) — ne +fassent pas plus de remous que ça.</p> +<p>À peine deux années après ces révélations, la France fait passer une loi qui +légitime cette surveillance de masse, à plus de 77% des voies. Pour moi c'est +un signal fort de la perte de valeurs de notre démocratie, et à fortiori de ma +perte de foi en notre forme de démocratie.</p> +<p>Notre liberté d'expression se voit bien évidemment amputée de par la +surveillance généralisée. Sans avoir nécessairement à cacher mes échanges, ce +qui est de la sphère privée devrait pouvoir le rester.</p> +<p>De toute manière, l'email comme on l'utilise traditionnellement est une +hérésie: toutes les parties qui traitent le message peuvent le lire, +(destinataire, auteur et corps du message entre autres). Il est grand temps de +rendre les outils de chiffrement plus simples et ergonomiques.</p> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, envers +mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins pour +rendre le déchiffrement des messages plus longue, &quot;noyer le poisson&quot;.</li> +</ul> +<p>Si vous êtes intéressé(e)s, faites moi signe, je me ferais un plaisir de vous +expliquer ce qui n'est pas si complexe et vise à laisser dans la sphère privée +ce qui devrait l'être à priori.</p> +<p>Une manière simple de se protéger est d'installer Thunderbird avec Enigmail et +de le configurer correctement. Ce n'est pas très compliqué et permet d'avoir +des échanges chiffrés. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à pas.</p> +<p>La clé publique pour me contacter est <a class="reference external" href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et +vous ?</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 autour (<a class="reference external" href="https://supporters.eff.org/donate">Electronic +Fronteer Fondation</a>, <a class="reference external" href="https://tails.boum.org/contribute/how/donate/index.fr.html">Tails</a>, <a class="reference external" href="https://support.laquadrature.net/">La quadrature +du net</a> en france ou d'autres…)</p> +<link href="http://vjs.zencdn.net/4.12/video-js.css" rel="stylesheet"> +<script src="http://vjs.zencdn.net/4.12/video.js"></script> +<video id="MY_VIDEO_1" class="video-js vjs-default-skin" controls + preload="auto" width="640" height="264" poster="MY_VIDEO_POSTER.jpg" + data-setup="{}"> + <source src="https://citizenfour.thecthulhu.com/citizenfour.mp4" type='video/mp4'> + <p class="vjs-no-js">To view this video please enable JavaScript, and + consider upgrading to a web browser that <a + href="http://videojs.com/html5-video-support/" target="_blank">supports + HTML5 video</a></p> +</video>Language2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-01:/language.html<blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux …</p></blockquote><blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux dont c'est la langue maternelle.</p> +<p>Aussi nous savons tous que les concepts qui paraissent similaires sont +souvent différents d'une civilisation à l'autre. Les mots expriment une +culture, une façon de penser et une vision du monde.</p> +<p class="attribution">&mdash;M. Boutros Boutros-Ghali, ancien secrétaire général des Nations Unies</p> +</blockquote> +<p>Je me surprends à préférer le français pour m'exprimer au lieu de l'anglais, +notamment au niveau des articles non techniques.</p> +<p>Il y a quelques années, alors que je terminais mes études en Angleterre et que +je commençais à travailler pour Mozilla, on me proposait de venir aux +États-Unis, ce que j'ai refusé parce qu'exprimer mes points de vue de manière +fine m'était trop difficile dans une langue qui n'était pas la mienne.</p> +<ul class="simple"> +<li>Cela me permet de pouvoir tenir des discours avec des positions et un +argumentaire &quot;fin&quot;, ce qui me serait beaucoup plus difficile dans une langue +que je maitrise moins;</li> +<li>Sans même parler d'argumentaire, les mots utilisés dans ma langue maternelle +me permettent de manœuvrer plus finement et de faire passer des idées de +manière plus efficace;</li> +<li>J'ai l'impression de pouvoir engager plus facilement avec les gens qui +m'entourent géographiquement, par exemple par rapport à la communauté +technophile / pythoniste francophone.</li> +<li>Même si mon niveau d'anglais à progressé, ce n'est pas nécessairement le cas +de mes interlocuteurs.</li> +</ul> +<p>Par contre, cela nuit clairement à engager avec d'autres personnes dont la +langue n'est pas la mienne, dans tels cas, traduire les contenus intéressants +vers l'anglais semble une solution (chronophage).</p> +Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html<p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village …</p><p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village de dire :</p> +<blockquote> +Mais quel mauvais père qui oblige ainsi son fils d'aller à pied !</blockquote> +<p>Le lendemain ils sortent de nouveau.</p> +<p>Le père ayant installé son fils sur l'âne et lui marchant à côté.</p> +<p>Les gens du village dirent alors :</p> +<blockquote> +Quel fils indigne, qui ne respecte pas son vieux père et le laisse aller à pied !</blockquote> +<p>Le jour suivant, ils s'installent tous les deux sur l'âne avant de quitter la maison. +Les villageois commentèrent en disant :</p> +<blockquote> +Ils ne respectent pas leur bête à la surcharger ainsi !</blockquote> +<p>Le jour suivant, ils partirent en portant eux-mêmes leurs affaires, l'âne trottinant derrière eux. +Cette fois les gens du village y trouvèrent encore à redire :</p> +<blockquote> +Voilà qu'ils portent eux-mêmes leurs bagages maintenant ! C'est le monde à l'envers !</blockquote> +<p>De retour à la maison, le père dit à son fils :</p> +<blockquote> +Tu me demandais l'autre jour le secret du bonheur. +Peu importe ce que tu fais, il y aura toujours quelqu'un pour y trouver à redire. +Fais ce qui te plaît et là tu seras vraiment heureux.</blockquote> +What's Hawk and how to use it?2014-07-31T00:00:00+02:002014-07-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.html<p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original …</p><p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original <a class="reference external" href="https://en.wikipedia.org/wiki/OAuth">OAuth</a> specification authors, that intends to +replace the 2-legged OAuth authentication scheme using a simpler approach.</p> +<p>It is an authentication scheme for HTTP, built around <a class="reference external" href="https://en.wikipedia.org/wiki/Hmac">HMAC digests</a> of requests and responses.</p> +<p>Every authenticated client request has an Authorization header containing a MAC +(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 +server.</p> +<div class="section" id="exchange-of-the-hawk-id-and-hawk-key"> +<h2>Exchange of the hawk id and hawk key</h2> +<p>To sign the requests, a client needs to retrieve a token id and a token key +from the 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 class="reference external" href="http://accounts.firefox.com">Firefox Accounts</a> put together a scheme to do that, which acts +like the following:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p>All this derivation crazyness might seem a bit complicated, but don't worry, +we put together some libraries that takes care of that for you automatically.</p> +<p class="last">If you are not interested into these details, you can directly jump to the +next section to see how to use the libraries.</p> +</div> +<p>When your server application needs to send you the credentials, it will return +it inside a specific <cite>Hawk-Session-Token</cite> 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 requests.</p> +<p>In order to get the hawk credentials, you'll need to:</p> +<p>First, do an <a class="reference external" href="http://en.wikipedia.org/wiki/HKDF">HKDF derivation</a> on the +given session token. You'll need to use the following parameters:</p> +<pre class="literal-block"> +key_material = HKDF(hawk_session, &quot;&quot;, 'identity.mozilla.com/picl/v1/sessionToken', 32*2) +</pre> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">The <tt class="docutils literal">identity.mozilla.com/picl/v1/sessionToken</tt> is a reference to this way of +deriving the credentials, not an actual URL.</p> +</div> +<p>Then, the key material you'll get out of the HKDF need to be separated into two +parts, the first 32 hex caracters are the hawk id, and the next 32 ones are the +hawk key.</p> +<p>Credentials:</p> +<div class="highlight"><pre><span></span><span class="nx">credentials</span> <span class="o">=</span> <span class="p">{</span> + <span class="s1">&#39;id&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">0</span><span class="o">:</span><span class="mi">32</span><span class="p">],</span> + <span class="s1">&#39;key&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">32</span><span class="o">:</span><span class="mi">64</span><span class="p">],</span> + <span class="s1">&#39;algorithm&#39;</span><span class="o">:</span> <span class="s1">&#39;sha256&#39;</span> +<span class="p">}</span> +</pre></div> +</div> +<div class="section" id="httpie"> +<h2>Httpie</h2> +<p>To showcase APIs in the documentation, I like to use <a class="reference external" href="https://github.com/jakubroztocil/httpie">httpie</a>, a curl-replacement with a nicer +API, built around <a class="reference external" 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 class="reference external" href="https://github.com/mozilla-services/requests-hawk">I wrote +a wrapper</a> around <a class="reference external" href="https://github.com/kumar303/mohawk">mohawk</a> to add hawk support to the requests lib.</p> +<p>Doing hawk requests in your terminal is now as simple as:</p> +<pre class="literal-block"> +$ pip install requests-hawk httpie +$ http GET localhost:5000/registration --auth-type=hawk --auth='id:key' +</pre> +<p>In addition, it will help you to craft requests using the requests library:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Alternatively, if you don'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 you:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +</div> +<div class="section" id="integrate-with-python-pyramid-apps"> +<h2>Integrate with python pyramid apps</h2> +<p>If you're writing pyramid applications, you'll be happy to learn that <a class="reference external" 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'm chocked how simple it +is to use it.</p> +<p>Here is a demo of how we implemented it for Daybed:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>The <cite>get_hawk_id</cite> function is a function that takes a request and +a tokenid and returns a tuple of <cite>(token_id, token_key)</cite>.</p> +<p>How you want to store the tokens and retrieve them is up to you. The default +implementation (e.g. if you don't pass a <cite>decode_hawk_id</cite> function) decodes the +key from the token itself, using a master secret on the server (so you don't +need to store anything).</p> +</div> +<div class="section" id="integrate-with-node-js-express-apps"> +<h2>Integrate with node.js Express 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 class="reference external" href="https://github.com/mozilla-services/express-hawkauth">express-hawkauth</a>.</p> +<p>In order to plug it in your application, you'll need to use it as +a middleware:</p> +<div class="highlight"><pre><span></span><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express&quot;</span><span class="p">);</span> +<span class="kd">var</span> <span class="nx">hawk</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express-hawkauth&quot;</span><span class="p">);</span> +<span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span> + +<span class="kd">var</span> <span class="nx">hawkMiddleware</span> <span class="o">=</span> <span class="nx">hawk</span><span class="p">.</span><span class="nx">getMiddleware</span><span class="p">({</span> + <span class="nx">hawkOptions</span><span class="o">:</span> <span class="p">{},</span> + <span class="nx">getSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which pass to the cb the key and algorithm for the</span> + <span class="c1">// given token id. First argument of the callback is a potential</span> + <span class="c1">// error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span><span class="nx">key</span><span class="o">:</span> <span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="nx">algorithm</span><span class="o">:</span> <span class="s2">&quot;sha256&quot;</span><span class="p">});</span> + <span class="p">},</span> + <span class="nx">createSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which stores a session for the given id and key.</span> + <span class="c1">// Argument returned is a potential error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span> + <span class="p">},</span> + <span class="nx">setUser</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function that uses req and res, the hawkId when they&#39;re known so</span> + <span class="c1">// that it can tweak it. For instance, you can store the tokenId as the</span> + <span class="c1">// user.</span> + <span class="nx">req</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="nx">tokenId</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">});</span> + +<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;/hawk-enabled-endpoint&quot;</span><span class="p">,</span> <span class="nx">hawkMiddleware</span><span class="p">);</span> +</pre></div> +<p>If you pass the <cite>createSession</cite> parameter, all non-authenticated requests will +create a new hawk session and return it with the response, in the +<cite>Hawk-Session-Token</cite> 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't have any <cite>createSession</cite> parameter +defined.</p> +</div> +<div class="section" id="some-reference-implementations"> +<h2>Some reference implementations</h2> +<p>As a reference, here is how we're using the libraries I'm talking about, in +case that helps you to integrate with your projects.</p> +<ul class="simple"> +<li>The Mozilla Loop server <a class="reference external" href="https://github.com/mozilla-services/loop-server/blob/master/loop/index.js#L70-L133">uses hawk as authentication once you're logged in with +a valid BrowserID assertion</a>; +request, to keep a session between client and server;</li> +<li><a class="reference external" href="https://github.com/spiral-project/daybed/commit/f178b4e43015fa077430798dcd3d0886c7611caf">I recently added hawk support on the Daybed project</a> +(that's a pyramid / cornice) app.</li> +<li>It's also interesting to note that Kumar put together <a class="reference external" href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for the +django rest framework</a></li> +</ul> +</div> +Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html<p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est …</p><p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est +écrivain il est important de se poser des questions sur les textes que l'on +produit, pour qui et dans quel but; il est important de se questionner sur +l'utilité du métier de développeur, et sur l'utilisation des contenus produits.</p> +<p>Je suis un développeur parce que je défends certaines valeurs. Les valeurs du +partage de connaissances, de la collaboration, et de l'émancipation.</p> +<p>Je suis aussi développeur parce qu'il me plait de créer des contenus à partir +de &quot;pas grand chose&quot;. La <em>magie</em> de la création logicielle m'anime, parce que j'ai +l'impression qu'il est possible de faire des choses géniales à partir de ce &quot;pas +grand chose&quot;. Donnez moi un ordinateur et je vous crée une application de +partage de semences paysannes. Un peu comme il est possible de donner une +feuille de papier à un dessinateur pour se retrouver avec un univers magnifique +couché sur papier.</p> +<p>Je me rends compte qu'au fur et à mesure des années, je me laisse ramollir, +absorber par le quotidien et me retrouve à ne plus me poser de questions +quant à l'utilité de mon métier. Pourquoi est-ce que je code ? À qui cela sert +il ? Quelle est ma motivation réelle ?</p> +<p>En travaillant pour Mozilla, on pourrait croire que ce problème est résolu de fait, +puisque après tout, Mozilla, c'est les &quot;protecteurs du web&quot;, des +gentils, et qu'on essaye nécessairement de faire les choses bien…</p> +<div class="section" id="l-omnipresence-technologique"> +<h2>L'omniprésence technologique</h2> +<p>Je ne suis pas convaincu qu'utiliser la technologie de la manière dont on le +fait actuellement est systématiquement une bonne chose:</p> +<p>Depuis 2 ans quasiment maintenant, Mozilla travaille sur un système +d'exploitation mobile, un remplaçant pour les iphones et androides, qui utilise +cette fois ci les technologies du web. Les avantages sont multiples, et le +principal intérêt est de faire un téléphone qui ne soit pas au service +des &quot;gros&quot; du Web mondial (Google et Apple).</p> +<p>Ces &quot;ordiphones&quot; à destination des pays dits &quot;émergents&quot; sont d'ailleurs +construits à faible coût — toujours de manière honteuse, pour la plupart en +chine, dans les mêmes chaines de production que les autres téléphones, mais +c'est un autre débat.</p> +<p>L'idée, assez intéressante d'un point de vue marché (les pays en question +n'ayant que peu de périphériques actuellement semblent un terrain propice à la +diffusion des &quot;ordiphones&quot;), est de donner accès à la technologie, au Web à ces +pays émergents.</p> +<p>L'accès à la technologie pour tous me semble relever de la chimère +productiviste: je conçois que la technologie puisse être un pas en avant assez +fou, notamment lorsque l'on connaît la richesse des contenus qu'on peut trouver +sur le web, mais cette richesse vient aussi avec un certain coût, que nous +avons actuellement du mal, en tant qu'utilisateurs, à contrôler et à mesurer. +Les gens sont beaucoup beaucoup trop connectés.</p> +<p>Je le suis par exemple bien plus souvent que ce que je voudrais l'admettre, que +ce soit pour regarder un film, lire mes emails, communiquer avec des amis, +faire de l'associatif, écrire du code, des billets sur ces carnets…</p> +<p>Cette technologie, omniprésente dans nos vies, je ne sais pas si c'est un +futur que je souhaite partager.</p> +<p>Pour prendre un autre exemple, les bienfaits de la technologie ne viennent pas +seuls. Les réseaux sociaux, qui constituent une bonne part de l'utilisation du +Web, relèvent du culte de la personnalité, de l'individualisme, et ce n'est pas +ce développement que je souhaite pour notre société.</p> +<p>L'idée de base du Web, le fait de faire une toile de connaissances ouverte et +partagée entre tous est en train, petit à petit, de glisser vers l'idée d'un +outil de relai de l'information, où tout va vite, où l'on ne prends guère +plus le temps de lire autre chose que les titres des quotidiens, ou des +&quot;tweets&quot; de cent vingt caractères…</p> +</div> +<div class="section" id="des-outils-utiles"> +<h2>Des outils utiles</h2> +<p>Bon an, mal an, je pense quand même que la technologie puisse être un vecteur +d'émancipation. Plus spécifiquement, je crois qu'il ne faut pas laisser +l'utilisation de la technologie aux &quot;gros&quot;, aux entreprises, aux états ou +&quot;spécialistes&quot;.</p> +<p>Il est important de ne pas laisser ceux que l'on combat s'emparer des &quot;outils +du pouvoir&quot;. La science, la technologie ou les médias sont autant de champs +qu'il est important de défendre, de conserver, de s'approprier.</p> +<p>Un des objectifs que je me fixe, pour les années à venir, ce que j'ai envie de +créer, c'est à la fois des outils utiles pour les organisations, mais aussi +éduquer à ces outils.</p> +<p>Parce que l'éducation populaire ne s'arrête pas aux frontières du numérique, +parce qu'il est important de se battre avec les mêmes outils que ce monde que +l'on cherche parfois à combattre.</p> +<p>Les outils sur lesquels j'ai envie d'être amené à travailler sont des outils +qui favorisent et questionnent la collaboration.</p> +<p>Des outils comme etherpad par exemple, révolutionnent la manière de prendre des +notes en commun, et il reste énormément à faire sur le web à ce propos.</p> +<p>Nombre d'associations me demandent de plus en plus souvent ce qu'il en est de +Daybed, et de quand est-ce qu'on va pouvoir utiliser un système de génération +de formulaires en ligne, qui ne soit pas centré sur les services de google…</p> +<p>Allez, au boulot !</p> +<p>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, <a class="reference external" href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler-fr.html">sur le sens du travail et +de l'informatique</a>, ça fait du bien :)</p> +</div> +Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud Services&quot;.</p> +<p>Depuis, énormément de choses ont évoluées, tant en ce qui concerne les +objectifs de Mozilla (avec l'arrivée de FirefoxOS) que le travail que +j'effectue au jour le jour. Pour autant, mes objectifs personnels restent +intacts.</p> +<p>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 <a class="reference external" href="ziade.org">Tarek</a> par exemple.</p> +<p>Ç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 !</p> +<div class="section" id="services"> +<h2>Services</h2> +<p>Le principal de mon travail a été de construire des outils. Je suis le +mainteneur de <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>, un +utilitaire qui vient se greffer par dessus <a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">le framework python pyramid</a> pour +vous simplifier la vie et créer des services web; J'ai travaillé un peu +sur un outil de gestion des processus nommé <a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a>, et également sur un outil de +montée en charge dénommé <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a></p> +<p>Au tout début, j'ai travaillé sur un concept de <a class="reference external" href="https://github.com/mozilla-services/tokenserver">serveur de +tokens</a>. L'idée était de +désolidariser l'authentification des services web des services eux mêmes.</p> +<p>L'idée est (je pense) bonne mais le service n'a pas été utilisé durant plus de +deux ans. La raison étant principalement que Sync, pour lequel le serveur de +tokens a été écrit, a subi des changements majeurs (qui sont rentrés en +production il y a quelques semaines)</p> +<p>Circus est né de besoins découverts via le token server, et il m'a +personnellement beaucoup appris. Le token server est finalement utilisé dans la +nouvelle version de Sync qui est rentrée en production il y a peu.</p> +</div> +<div class="section" id="marketplace-chouette-on-va-casser-du-serveur"> +<h2>Marketplace (&quot;chouette, on va casser du serveur&quot;)</h2> +<p>Après 6 mois à travailler à Services, Tarek et moi avons commencé à rejoindre +l'équipe du Marketplace pour faire un travail d'&quot;audit de performance&quot;.</p> +<p>L'idée était de prêter main forte à l'équipe du marketplace, mais les détails +étaient alors assez flous. Le code est assez indigeste au premier abord, ce qui +m'avait alors pas mal refroidi. La raison principale étant que le code est +utilisé à la fois par <cite>addons.mozilla.org</cite> et par <cite>marketplace.firefox.com</cite>, +rendant les choses souvent un peu plus compliquées qu'il ne faudrait.</p> +<p>Cet &quot;audit&quot; a été l'occasion de travailler sur des outils de montée en charge +assez sympa, qui ont donné naissance à un projet qu'on utilise assez souvent +maintenant, <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a>.</p> +<p>Énormément d'efforts sont fait pour aller dans la bonne direction et faire en +sorte que le code soit plus facile à maintenir et que le projet soit plus +facile à aborder. D'ailleurs, pas mal de copains djangonautes français +travaillent dessus (salut <a class="reference external" href="http://virgule.net">Mathieu</a>, Yohan, <a class="reference external" href="http://larlet.fr">David</a> et <a class="reference external" href="http://mathieu.agopian.info">Mathieu Agopian</a>!)</p> +<p>Une partie de notre plan a été de sortir certaines fonctionnalités du code +actuel, pour en faire quelque chose de plus facile à maintenir et de moins +imbriqué.</p> +</div> +<div class="section" id="la-communaute"> +<h2>La Communauté</h2> +<p><a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a> et <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a> sont +deux outils qui semblent utiles à la communauté. J'ai eu des retours très +positifs sur Cornice, et j'essaye de le faire évoluer dans la direction qui me +semble propice.</p> +<p>D'ailleurs, Cornice est utilisé (par <a class="reference external" href="http://blog.mathieu-leplatre.info/pages/about.html">Mathieu L.</a> +— encore un —, <a class="reference external" href="http://twitter.com/natim">Rémy</a> et moi) actuellement pour coder +<a class="reference external" href="https://github.com/spiral-project/daybed">Daybed</a> un service de validation +de formulaires, mais ça sera l'objet d'un futur billet.</p> +<p>Circus commence à recevoir des contributions de plus en plus intéressantes, et +à être utilisé en interne chez nous et chez d'autres, donc c'est une +extrêmement bonne nouvelle.</p> +</div> +<div class="section" id="talkilla-loop"> +<h2>Talkilla / Loop</h2> +<p>Après quelques temps, j'avais envie d'apprendre de nouveau. Python c'est génial +mais c'était devenu ma &quot;zone de confort&quot;. J'adore découvrir des choses, donc +c'était le moment de faire en sorte que ça continue!</p> +<p>C'était aussi l'occasion de travailler avec <a class="reference external" href="https://nicolas.perriault.net/">Nicolas</a> et <a class="reference external" href="http://monkeypatch.me/blog/">Romain</a>. +Je suivais le projet Talkilla de plus ou moins loin depuis quelques mois, +c'était donc l'occasion à ne pas manquer.</p> +<p>En rentrant dans cette équipe, je cherchais principalement à avoir un projet +visible pour les utilisateurs finaux. Refaire un peu de frontend, apprendre +à faire du JavaScript propre et découvrir de nouvelles personnes.</p> +<p>J'y ai aussi récupéré une équipe qui essaye de suivre les principes de +l'agilité et qui est sur mon fuseau horaire (pour la plupart). Le rêve.</p> +<p>L'idée derrière Talkilla est d'utiliser la technologie de communication pair +à pair dans les navigateurs (WebRTC) pour faire des appels audio / vidéo. En +d'autres termes, c'est un peu transformer votre firefox en téléphone, sauf que +personne ne peut espionner ce qui se passe entre vous et l'autre bout du fil.</p> +<p>A peine arrivé dans le projet (peut-être un mois et quelques après mon +débarquement) le choix a été fait de tout réécrire depuis zéro, dans un projet +qui se nomme actuellement &quot;Loop&quot;, qui veut proposer la même chose, mais inclus +directement dans Firefox.</p> +<p>C'est en bonne voie, on a quelque chose qui fonctionne dans nightly, et le code +du serveur fonctionne pas mal. Le code du serveur est ici: +<a class="reference external" href="https://github.com/mozilla-services/loop-server">https://github.com/mozilla-services/loop-server</a>.</p> +<p>Un client est en train d'être implémenté dans Firefox et un autre en tant +qu'application pour FirefoxOS. Le boulot ne s'arrête pas de pleuvoir, mais je +pense qu'on va dans une direction intéressante.</p> +<p>Pour être complètement terminé, il faudrait qu'on soit capable de se passer +complètement de notre provider, TokBox (que l'on utilise en tant que relai +média), pour que n'importe qui puisse choisir d'utiliser son propre serveur +STUN / TURN et installe son serveur loop chez lui.</p> +<div class="section" id="le-travail-a-distance"> +<h3>Le travail à distance</h3> +<p>Quand j'ai commencé à travailler à Mozilla, j'ai décidé de venir m'installer +à Paris. La plupart des personnes de mon entourage ont d'ailleurs fait des gros +yeux, parce qu'ils connaissaient mon avis sur la ville en question, mais casser +des préjugés n'est jamais une mauvaise chose.</p> +<p>Après deux ans passés à Paris, j'ai décidé de partir m'installer à Rennes, +puisque de toute manière, la plupart de mon travail s'effectue au jour le jour +à distance. En d'autres termes, la plupart de mon équipe n'est pas à coté de +moi quand je travaille, ce qui veut dire que je peux travailler depuis +n'importe où.</p> +<p>Ce qui fonctionne pour moi, c'est de ne quasiment jamais travailler depuis la +maison. J'utilise <a class="reference external" href="http://www.lacantine-rennes.net/">un espace de coworking</a> +qui est un moyen de garder ma vie perso séparée de ma vie privée et de +rencontrer des gens passionnés par ce qu'ils font.</p> +<p>Depuis que je suis arrivé à Rennes, Rémy a commencé à travailler avec moi, et +c'est un réel bonheur que de pouvoir partager des journées de travail. On +&quot;pair-prog&quot; énormément et j'ai l'impression d'avoir un boost dans ma +productivité quotidienne.</p> +</div> +<div class="section" id="enseignements"> +<h3>Enseignements</h3> +<p>Mozilla est ma première expérience professionnelle, et par conséquent, je +manque nécessairement de recul sur ce qui est acceptable et ce qui ne l'est +pas. D'une manière générale, avoir un environnement de travail basé sur la +confiance est réellement appréciable (La première réaction des gens quand je +dis que je peux travailler à distance, c'est de me demander comment ils font +pour être sur que je travaille. Et la réponse est… il n'y en a pas).</p> +<p>J'ai encore un peu de mal à savoir quels indicateurs utiliser pour savoir si je +suis &quot;productif&quot; ou non, mais j'ai globalement l'impression que je manque de +concentration et de discipline: beaucoup d'interruptions n'aident pas à se +concentrer.</p> +<p>La motivation fluctue aussi énormément: un jour on est super motivé, un autre +c'est juste impossible de la trouver. Après quelques expérimentations, le mieux +(pour moi) est d'avoir des horaires fixes, pour pouvoir séparer le travail du +reste, de ne pas hésiter à faire des pauses et d'écouter un peu ses envies et +son corps (si je suis crevé, ça ne sert à rien de se lever pour aller +travailler, il vaut mieux se reposer un peu pour être plus efficace ensuite, +par exemple).</p> +<p>J'ai essayé de tirer quelques enseignements de ces deux années:</p> +</div> +</div> +<div class="section" id="malheureusement-le-code-n-est-pas-propre"> +<h2>Malheureusement, le code n'est pas propre</h2> +<p>Je me rends compte que bien souvent je suis assez déçu de la qualité du code +que je regarde. Principalement parce que je ne suis pas capable de le +comprendre rapidement. Spécifiquement, ça m'est arrivé avec certaines parties +de <a class="reference external" href="https://github.com/mozilla/zamboni">Zamboni</a>, le code du <a class="reference external" href="http://marketplace.firefox.com">Marketplace</a> dont je parlais plus haut, avec certaines +parties de Talkilla ou alors le code de Firefox lui même.</p> +<p>C'était extrêmement frustrant pour moi de découvrir que le code écrit à Mozilla +n'était pas exemplaire. Tout le code qui est ajouté à l'heure actuelle est +revu, corrigé et validé par des pairs, mais un certain nombre de projets ont un +historique assez lourd qui rends leur structure complexe.</p> +<p>Je réalise donc que mon travail n'est pas uniquement de savoir écrire du code +propre, mais également de réussir à comprendre du code que je considère comme +&quot;sale&quot; (quitte à l'améliorer au passage !).</p> +<p>Et c'est pas du gâteau; je m'attendais à réussir à comprendre des projets +complexes facilement, mais aucun miracle de ce coté là. Il faut réussir +à rester concentré pendant suffisamment longtemps pour pouvoir tirer tous les +fils et commencer à démêler… Pas facile !</p> +</div> +<div class="section" id="apprendre-est-un-processus-actif"> +<h2>Apprendre est un processus actif</h2> +<p>Il est facile de passer à coté de l'apprentissage. Être entouré de gens +talentueux ne suffit pas pour continuer à apprendre.</p> +<p>Savoir reconnaitre un échec est nécessaire. Dire que l'on comprends pour éviter +de passer pour un idiot est un biais qui se prends assez rapidement, et qu'il +faut éviter à tout prix.</p> +<p>Surtout au début, c'était une erreur que je faisais énormément, une question +d'égo probablement.</p> +<p>Il y a une espèce de honte de ne pas savoir, alors que tout le monde autour +sait ou en tout cas semble savoir. Bien souvent, les gens autour ne savent pas +non plus, ce qui mène à des discussions de comptoir, sans trop savoir pourquoi.</p> +<p>Connaître ses limites techniques est un bon début pour pouvoir les surpasser. +Chercher à les rencontrer est un processus actif.</p> +<p>Le manque de temps m'empêche bien souvent de pouvoir prendre un livre technique +et de pouvoir l'apprécier. Je ne sais pas exactement pourquoi, peut être par +sur-dose, mais je n'ai ouvert que quelques rares livres techniques durant ces +deux années. Et j'aimerais bien que ça change !</p> +</div> +<div class="section" id="assez-bien-est-suffisant"> +<h2>&quot;Assez bien&quot; est suffisant</h2> +<p>La culture de l'excellence se mets parfois au milieu du chemin. On oublie +souvent que &quot;le mieux est l'ennemi du bien&quot;.</p> +<p>Rien ne sert de faire des commits parfaits tout le temps. Quand j'ai besoin de +&quot;hacker&quot; sur un projet, je ne voulais d'abord pas tout péter, par peur de ne +plus m'y retrouver.</p> +<p>Mon approche actuelle est bien différente: on mets les mains dans le cambouis +jusqu'à ce que ça marche, et ensuite on répare les dégâts. Enfin… dans une +certaine mesure hein !</p> +</div> +<div class="section" id="ecrire-des-boites-a-outils-et-non-pas-des-frameworks"> +<h2>Écrire des boites à outils et non pas des frameworks</h2> +<p>Écrire des frameworks force les utilisateurs à les utiliser, et à les connaitre +dans les moindres recoins. Heureusement, il existe déjà énormément de +frameworks qui pour la plupart font très bien leur travail. Ce qui nous manque +ce n'est pas plus de frameworks, mais bel et bien plus de boites à outils.</p> +<p>Une boite à outil prends un problème bien défini et propose une solution pour +ce problème. Une boite à outils est, en mon sens, ce qu'on appelle une +bibliothèque. Pas besoin de réécrire tout votre projet pour utiliser ma +nouvelle bibliothèque afin de profiter des fonctionnalités qu'elle apporte +(alors que c'est le cas avec un framework, justement).</p> +</div> +<div class="section" id="etre-le-moteur-de-son-propre-changement"> +<h2>Être le moteur de son propre changement</h2> +<p>Facile à dire, héhé ! D'une manière générale, je me rends compte qu'il est +facile de se plaindre sans pour autant être moteur du changement que l'on +souhaite voir arriver.</p> +<p>Ça vaut le coup de se donner la peine de faire changer les choses, surtout +à Mozilla, parce que le changement n'est pas seulement vu d'un mauvais œil.</p> +<p>Pour que les choses évoluent, il faut être force de proposition. Se plaindre +n'a jamais servi à rien si ce n'est pas suivi d'actes ;)</p> +<p>Je dis de temps en temps que Mozilla est une &quot;do-o-cratie&quot; (celui qui fait +à raison), et je le pense de plus en plus. Quand j'ai envie que quelque chose +soit fait, et bah… il faut le faire !</p> +</div> +<div class="section" id="ne-pas-chercher-a-avoir-raison"> +<h2>Ne pas chercher à avoir raison</h2> +<p>Peu importe qui a raison, l'important n'est pas de chercher à montrer que tu +sais, mais de trouver ce qui est juste. Ça parait peut être évident, mais bien +souvent on cherche à se mettre en avant, au détriment du projet… Allez, gardons +nos égos de coté ;)</p> +</div> +<div class="section" id="arreter-le-negativisme"> +<h2>Arrêter le négativisme</h2> +<p>Il est très facile de se laisser embarquer dans le négativisme. Il y a toujours +des choses qui ne vont pas, et probablement il y en aura toujours. Ce ne sont +pas des raisons suffisantes pour perdre le moral. Identifier les points faibles +est important est permet de savoir ce qu'il est nécessaire d'améliorer, mais +regarder les choses du coté positif (et il y en a nécessairement un !) est +indispensable !</p> +<p>À plusieurs reprises je me suis retrouvé dans des crises de négativisme, pour +un tas de raisons différentes. La meilleure manière de s'en sortir: en causer +et trouver des solutions, prendre le problème à bras le corps, et ne pas +considérer que c'est un problème sur lequel on a aucune prise possible.</p> +<div class="section" id="la-suite"> +<h3>La suite ?</h3> +<p>Je n'ai aucune idée d'à quoi va ressembler la suite, et c'est justement ce que +j'apprécie et qui m'effraie en même temps…</p> +<p>Je fais actuellement énormément de Javascript et je travaille sur des +projets qui semblent avoir plus de sens qu'avant (même si je vois déjà des +choses que je souhaiterais améliorer, mais chaque chose en son temps). Donc +techniquement j'apprends et dans ma quête de faire des produits qui touchent un +utilisateur.</p> +<p>Depuis quelques semaines, je peux travailler une journée par semaine sur un +projet qui me tiens vraiment à cœur: daybed (<a class="reference external" href="http://daybed.rtfd.org">http://daybed.rtfd.org</a>). +L'objectif est de faire en sorte que le projet avance et soit utilisé au sein +de mozilla.</p> +<p>Avant toute autre chose, il faudra faire des changements de &quot;pitch&quot; pour qu'il +soit plus simple d'expliquer ce que Daybed souhaite faire, mais… c'est une autre +histoire.</p> +</div> +</div> +Le revenu de base2013-10-03T00:00:00+02:002013-10-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-10-03:/le-revenu-de-base.html<iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra …</p><iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra pas suffire à toute la population. En refusant +l'idée du RDB, on est obligé de croire en la croissance économique.</p> +<p>Différence entre une approche qantitative du travail VS une approche sociale.</p> +<p>La croissance éco ≠ croissance de l'emploi.</p> +<p>Parallelle entre le RDB et la déclaration des droits de l'homme. &quot;Et qui voudra +faire le sale boulot ?&quot;</p> +<p>Utopie veut dire le &quot;non lieu&quot;, le lieu qu'on à pas encore trouvé ici sur +terre, à part dans notre imaginaire.</p> +<p>Agriculture: Il y à 100 ans, qqn qui travaillait dans l'agriculture produisait assez pour +3 autres personnes. ajd un agriculteur produit assez pour 120 personnes, via +des machines énormes et à la rationalisation.</p> +<p>Rationalisation: moins d'emploi.</p> +<p>La condition de pouvoir refuser un travail est très importante.</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Le financmenet est acquis, la dificulté c'est la liberté</p> +<p class="attribution">&mdash;NA</p> +</blockquote> +<blockquote> +<p>Il faut en finir avec cette idée fausse, selon laquelle seul le travail +rémunéré constitue une contribution méritoire à la société, en réalité, c'est +souvent exactement l'inverse.</p> +<p class="attribution">&mdash;Katja Kipping, membre du parlement allemand.</p> +</blockquote> +<blockquote> +<p>Si les gens on déjà une sécurité matérielle, ils sont plus difficiles +à corrompre.</p> +<p class="attribution">&mdash;Katja Kipping</p> +</blockquote> +<blockquote> +<p>Soutenir les populations sans poser de condition. c'est un principe qui à la +longe, devra s'imposer. Mais il lui faudra d'abord affronter les droits et +privilèges dont on bénéficie aujourd'hui.</p> +<p class="attribution">&mdash;Anonyme.</p> +</blockquote> +<blockquote> +Si les revenus étaient uniquement lié au travail, il faudrait donner les plus +hauts revenus aux machines.</blockquote> +<p>Le sens de l'économie, c'est de libérer l'homme du travail Beaucoup de gens qui +ont une &quot;place de travail&quot;, n'ont en réalité qu'une &quot;place de revenu&quot;.</p> +</div> +<div class="section" id="chiffres"> +<h2>Chiffres</h2> +<p>Un sondage à été effectué. La question est: &quot;Si vous aviez un revenu de base, +est-ce que vous iriez encore travailler ?&quot;</p> +<ul class="simple"> +<li>~60% disent oui</li> +<li>30% répondent oui, mais plus à plein temps.</li> +<li>10% pour faire autre chose.</li> +</ul> +<p>Avec une question différente:</p> +<p>&quot;Si on instaurait un revenu de base, est-ce que vous pensez que les autres +iraient travailler ?&quot;</p> +<ul class="simple"> +<li>~80% répondent non.</li> +</ul> +<p>C'est un changement aussi dans les modes d'éducation, on nous enseigne à être +&quot;employable&quot;, et non pas à apprendre quelque chose qui nous interesse. Les gens +ont peur de ne pas trouver du travail.</p> +</div> +<div class="section" id="ressources"> +<h2>Ressources</h2> +<ul class="simple"> +<li>Le sens commun, Thomas Payne.</li> +<li>Peter Ulrich</li> +</ul> +</div> +<div class="section" id="comment-financer-le-rdb"> +<h2>Comment financer le RDB</h2> +<p>Si l’on se fie à son produit intérieur brut (PIB), la France est aujourd’hui le +cinquième pays le plus riche du monde. En 2010, le revenu disponible (après +versement des pres- tations sociales et prélèvement des impôts directs) s’y +élevait à 1 276 euros par mois et par personne, adultes et enfants confondus. +Nous disposons donc de ressources suffisantes pour garantir à chaque individu 1 +276 euros si l’on décidait d’opérer un partage strictement égalitaire. C’est +nettement plus que le seuil de pauvreté actuel, fixé en France à 60 % du revenu +médian (1), soit 960 euros par adulte. Qui peut le plus pouvant le moins, la +France a donc sans nul doute les moyens d’assurer à tous ses résidents un +revenu au moins égal au seuil de pauvreté.</p> +</div> +<div class="section" id="a-reculons-par-andre-gorz"> +<h2>À Reculons, par André Gorz.</h2> +<p>(Paru dans le monde diplomatique de Juin 1990)</p> +<p><em>Proche de Jean-Paul Sartre, cofondateur, en 1964, du Nouvel Observateur, le +philosophe André Gorz (1923-2007) s’est converti progressivement à un +écosocialisme dont il est devenu l’un des principaux théoriciens. En 1990, dans +nos colonnes, sous le titre « Pourquoi la société salariale a besoin de +nouveaux valets », il formulait une critique de l’idéologie du travail qui +devait l’amener quelques années plus tard à se prononcer en faveur d’un revenu +d’existence.</em></p> +<p>Dans l’ensemble des pays capitalistes d’Europe, on produit trois à quatre fois +plus de richesses qu’il y a trente-cinq ans ; cette production n’exige pas +trois fois plus d’heures de travail, mais une quantité de travail beaucoup plus +faible. (...)</p> +<p>Nous sortons de la civilisation du travail, mais nous en sortons à reculons, et +nous entrons à reculons dans une civilisation du temps libéré, incapables de la +voir et de la vouloir, incapables donc de civiliser le temps libéré qui nous +échoit, et de fonder une culture du temps disponible et une culture des +activités choisies pour relayer et compléter les cultures techniciennes et +profes- sionnelles qui dominent la scène. (...)</p> +<p>Pour près de la moitié de la population active, l’idéologie du travail est +devenue une mauvaise farce ; l’identification au travail est désormais +impossible, car le système économique n’a pas besoin ou n’a pas un besoin +régulier de leur capacité de travail. La réalité que nous masque l’exaltation +de la « ressource humaine », c’est que l’emploi stable, à plein temps, durant +toute l’année et toute la vie active, devient le privilège d’une minorité. +Pour [les autres], le travail cesse d’être un métier qui intègre dans une +communauté productive et définit une place dans la société. Ce que le patronat +appelle « flexibilité » se traduit pour les salariés par la précarité. (...)</p> +<p>Que doit être une société dans laquelle le travail à plein temps de tous les +citoyens n’est plus nécessaire, ni économiquement utile ? Quelles priorités +autres qu’économiques doit-elle se donner ? Comment doit-elle s’y prendre pour +que les gains de productivité, les économies de temps de travail profitent à +tout le monde ? Comment peut-elle redistribuer au mieux tout le travail +socialement utile de manière à ce que tout le monde puisse travailler, mais +travailler moins et mieux, tout en recevant sa part des richesses socialement +produites ?</p> +<p>La tendance dominante est d’écarter ce genre de questions et de poser le +problème à l’envers : comment faire pour que, malgré les gains de productivité, +l’économie consomme autant de travail que par le passé ? Comment faire pour que +de nouvelles activités rémunérées viennent occuper ce temps que, à l’échelle de +la société, les gains de productivité libèrent ? A quels nouveaux domaines +d’activité peut-on étendre les échanges marchands pour remplacer tant bien que +mal les emplois supprimés par ailleurs dans l’industrie et les services +industrialisés ?</p> +<p>On connaît la réponse, pour laquelle les Etats-Unis et le Japon ont montré la +voie : le seul domaine dans lequel il est possible, en économie libérale, de +créer à l’avenir un grand nombre d’emplois, c’est celui des services aux +personnes. Le développement de l’emploi pourrait être illimité si l’on +parvenait à transformer en prestations de services rétribuées les activités que +les gens ont, jusqu’à présent, assumées chacun pour soi. Les économistes +parlent à ce sujet de « nouvelle croissance plus riche en emplois », de « +tertiarisation » de l’économie, de « société de services » prenant le relais de +la « société industrielle » (1). (...)</p> +<p>Le problème de fond auquel nous sommes confrontés est celui d’un au-delà de +l’économie et, ce qui revient au même, d’un au- delà du travail rémunéré. La +rationalisation économique libère du temps, elle continuera d’en libérer, et il +n’est plus possible, par conséquent, de faire dépendre le revenu des citoyens +de la quantité de travail dont l’économie a besoin. Il n’est plus possible, non +plus, de continuer à faire du travail rémunéré la source principale de +l’identité et du sens de la vie pour chacun.</p> +<p>La tâche d’une gauche, si gauche il doit y avoir, consiste à transformer cette +libération du temps en une liberté nouvelle et en des droits nouveaux : le +droit de chacun et de chacune de gagner sa vie en travaillant, mais en +travaillant de moins en moins, de mieux en mieux, tout en recevant sa pleine +part de la richesse socialement produite. Le droit, d’autre part, de travailler +de façon discontinue, intermittente, sans perdre durant les intermittences de +l’emploi le plein revenu – de manière à ouvrir de nouveaux espaces aux +activités sans but économique 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.</p> +</div> +Des carnets d'esquisse2013-08-16T00:00:00+02:002013-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-08-16:/des-carnets-desquisse-fr.html<p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir …</p><p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir un &quot;carnet&quot; et d'y jeter juste quelques +notes. Pas grand chose: mes quelques pensées ou alors des liens 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.</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'accueil, mais vous pouvez les +trouver dans <a class="reference external" href="https://blog.notmyidea.org/category/notes.html">la section notes</a>.</p> +<p>Je ne sais pas encore si il s'agit du meilleur endroit pour ça, mais peu importe, +essayons. A bas la pudeur rédactionelle.</p> +<p>J'ai du au passage chambouler un peu vos agrégateurs, pardonnez moi :)</p> +<div class="section" id="le-retour-des-commentaires"> +<h2>Le retour des commentaires</h2> +<p>Au passage, je ne me rappelle plus quand exactement, mais j'avais décidé de +supprimer les commentaires de cet espace. Paf, apu. Comme ça, sans prévenir.</p> +<p>Les raisons en étaient à la fois techniques (je ne souhaitait pas avoir recours +à disqus qui est un silo propriétaire de plus) et parce que je considérais que +les commentaires n'avaient que peu d'intérêt. Ceci dit, le manque d'échange me +manque; j'aimerais bien savoir ce que vous pensez de ce que j'écris des fois, +et avoir des débats si nos opinions divergent.</p> +<p>Et puis bon, partager dans un seul sens, c'est un peu dommage !</p> +<p>Il est maintenant possible, avec <a class="reference external" href="http://talka.tv">talka.tv</a> d'héberger soi +même ses commentaires. J'ai dans l'idée d'héberger une instance de ce service +sur <cite>discus.notmyidea.org</cite>, 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 !)</p> +</div> +Notes: Économie libidinale et économie politique2013-07-06T00:00:00+02:002013-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-06:/notes-economie-libidinale-et-economie-politique.html<p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un …</p><p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un autre comportement s'est développé: le modèle &quot;collaboratif et contributif&quot;. +Ce modèle ne se repose pas sur la consommation mais sur l'implication et la +collaboration. Ce modèle est induit par internet, qui ne repose plus sur +l'opposition production / consommation.</p> +<p>Sur internet nous ne sommes pas des simples consommateurs, puisque vous êtes un +expéditeur / distributeur.</p> +<p>Le changement prduit par internet est le fait que les gens ne sont plus +simplement des consommateurs,mais sont également producteurs de contenus +/ viennent améliorer les contenus existants.</p> +<p>Note perso: quid du culte de la personalité qui en ressort ? Ce qu'il apelle +l'écologie relationelle ?</p> +<p>Quel est le manque que vient combler facebook par exemple ? Et quel est +l'impact que ces nouveaux réseaux ont sur les modèles relationels que l'ont +connait (famille, école, droit, etc.).</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Une révolution c'est le fait de faire une boucle est d'arriver au terme de +quelque chose. D'avoir clôt un cycle. La lune fait des révolutions aussi.</p> +<p>81% des Américains déclarent que le consumerisme est une plaie pour l'amérique +(d'après Juliet Score)</p> +</blockquote> +</div> +New year python meme, 20122013-07-01T00:00:00+02:002013-07-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-01:/new-year-python-meme-2012.html<p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this …</p><p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this year and +quite enjoyed it. I like the way they bring back some nice concepts on the +table, and how they compete with other frameworks. That's nicely decomposed and +everything fits together really well. I learned a bit about its internal +routing mechanism when working on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, and +it's really well done.</p> +<p><strong>2. What new programming technique did you learn in 2012 ?</strong></p> +<p>I learned about asynchronous programming, something I wasn't really aware of. +(Yes, that's a shame). This was really helpful to understand some bits of +<a class="reference external" href="http://circus.io">Circus</a>. I also started to learn about some related +concepts present in <a class="reference external" href="http://golang.org">go</a> or in <a class="reference external" href="http://erlang.org">erlang</a> with <a class="reference external" href="http://en.wikipedia.org/wiki/Actor_model">the actor model</a></p> +<p><strong>3. Which open source project did you contribute to the most in 2012 ? What did +you do ?</strong></p> +<p>I worked a bunch on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a> and <a class="reference external" href="http://circus.io">Circus</a>, not as much as I would like, but that was two really +interesting projects. For Cornice, I completely <a class="reference external" href="http://blog.notmyidea.org/refactoring-cornice.html">refactored the internals</a> back in May, and since +that, I added support for <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a> +and am currently working on porting it to Python 3 and adding support for <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>. For Circus, I worked on the web interface and +on other bits of the projects related to stats.</p> +<p>I didn't contributed that much to <a class="reference external" href="http://getpelican.com">Pelican</a>, mainly +because I'm less excited about it than I was previously: the project is +working and needs to focus more on code quality than features. We started in +this direction, hopefully it will pay-off; but I committed a lot less code than +previously.</p> +<p><strong>4. Which Python blog or website did you read the most in 2012 ?</strong></p> +<p>I really don't know. I found some interesting python-related news on <a class="reference external" href="http://news.ycombinator.com/">hacker +news</a> and on the printed version as well, +<a class="reference external" href="http://hackermonthly.com/">hacker monthly</a>. Twitter and IRC got me some +interesting articles as well.</p> +<p><strong>5. What are the three top things you want to learn in 2013 ?</strong></p> +<p>On the computer science side, I want to learn more about other paradigms, maybe +in other languages. I like python, but I want to learn about other concepts, +maybe some of them don't really fit with python.</p> +<p>For instance, I don't know that much about pattern matching or about the actor +model. Well I know what it is, but I would like to make good use of them in +order to have something nice and useful.</p> +<p>Also, I want to learn how to make a product. From scratch. Which means +designing, implementing and maintaining something. Maybe this will be the case +with <a class="reference external" href="https://github.com/spiral-project/daybed">daybed</a> ? Who knows.</p> +<p>I want to get better at building communities. Working with others is something +that can be complex and quite hard sometimes. I want to learn how to handle +this better.</p> +<p>On the other side, I want to learn about tons of other non-tech things: taking +pictures, finding a good balance between life and work, working with children, +teaching and animating workshops, writing articles, be better at reading (being +critic when I'm thinking!).</p> +<p><strong>6. What is the top software, application or library you wish someone would +write in 2013 ?</strong></p> +<p>The one missing thing, IMO, is a <strong>good</strong> webmail reader, in python. One we +could contribute to, one we could write features for, and one that could come +and compete with gmail, in term of features of UI.</p> +<p>However, most of the time, I'm just impressed by the new ideas that come from +others. I would like to have a library to handle the actor model in a nice way +in Python, I would like to see packaging fixed in python :-)</p> +<p>Want to do your own list? Here's how:</p> +<ul class="simple"> +<li>copy-paste the questions and answer to them in your blog</li> +<li>tweet it with the #2012pythonmeme hashtag</li> +</ul> +François Elie : Quelle école pour la société de l’information ?2013-06-14T00:00:00+02:002013-06-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-06-14:/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html<p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens …</p></blockquote><p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens font ça entre eux et on n’est pas non plus +dans une école de l’apprentissage où l’école a pour but de donner un métier, un +bagage utilisable. L’école ne sert évidemment pas à ça. D’ailleurs heureusement +parce que sinon on n’enseignerait pas la philosophie qui ne sert à rien à part +fabriquer des profs de philosophie !</p> +<p>On n’a pas besoin de tableau numérique pour enseigner l’informatique elle-même +pour enseigner la science. De la même façon on n’a pas besoin de machine à +calculer pour enseigner les mathématiques. Évidemment ! On n’a pas besoin d’une +machine à calculer pour savoir faire une division. Au contraire, surtout pas !</p> +<p>Il faut cesser d’opposer l’enseignement de la programmation d’une part et +l’enseignement des usages, c’est important mais ça c’est l’école des maîtres et +des esclaves. Ce qu’il faut enseigner, vite et à tous, c’est la science, pas la +technologie ou l’usage. C’est en amont de la programmation, l’algorithmique. +C’est, en amont de telle instanciation, du codage, du chiffrement, la théorie, +quelque chose qui comme les maths n’ont besoin que d’une craie et d’un tableau +noir.</p> +<p>Ce n'est pas un hasard si le mot &quot;numérique&quot; à remplaçé le mot &quot;informatique&quot;, +c'est qu'on voudrait nous faire croire qu'il n'y a pas besoin de l'apprendre.</p> +</blockquote> +Des profils de confiance partout et pour tout ?2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/confiance-fr.html<p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site …</p><p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site et de les appeler soi même, chose maintenant automatisée.</p> +<p>Dès que cette décision à été prise, il y a eu des émules. Le site <a class="reference external" href="http://covoiturage-libre.fr">Covoiturage +Libre</a> à été d'ailleurs créé pour faire en sorte +de garder &quot;l'esprit&quot; du covoiturage. Bref ça jasait dans les chaumières.</p> +<p>Il y à peu, j'ai reçu un <em>couriel</em> contenant un lien vers une vidéo d'<a class="reference external" href="http://www.covoiturage.fr/blog/2013-confiance">une +conférence animée par le fondateur de covoiturage.fr</a>.</p> +<p>Ils semblent vouloir parler de confiance, alors ça m'intrigue, d'autant que la +présentation en question est donnée lors d'un évènement TEDx, auquel j'accorde +un certain crédit.</p> +<div class="section" id="un-capital-de-confiance"> +<h2>Un &quot;capital de confiance&quot;</h2> +<p>Cette vidéo parle entre autres du <em>capital de confiance</em> que nous pouvons +nous accorder les uns aux autres; et notamment du fait que ce capital de +confiance n'est malheureusement pas partagé au dela d'un cercle de +connaissances assez limité. Il reste dans notre cercle de connaissances proche, les +amis des amis.</p> +<p>C'est donc une chose regrettable, parce que ça nous fait perdre du temps (et +donc, <em>ohmygod</em> de l'argent) à tous pour construire cette confiance. Temps qui +pourrait être mieux employé.</p> +<p>La solution proposée, attention les yeux, est de faire appel un maximum aux +profils en ligne, une manière de &quot;prouver au monde&quot; que nous sommes des +personnes de confiance. Selon les termes de la présentation, nous pourrions +alors tous devenir des &quot;super héros du trust&quot;, des &quot;trustman&quot;.</p> +<p>Grâce à des profils en ligne ou monsieur et madame tout le monde pourraient +aller voter et donner leur avis sur les personnes qu'ils ont rencontré.</p> +</div> +<div class="section" id="l-avenement-du-paiement-en-ligne"> +<h2>L'avènement du paiement en ligne</h2> +<p>On nous dit maintenant que le paiement en ligne est une révolution, un moyen de +tracer le fait qu'il y à effectivement eu une transaction entre deux personnes; +et que donc il en deviendrait un outil pour vérifier que la confiance est bien +légitime, et non pas créée de toute pièce sur le profil de la personne en +question.</p> +<p>Plu</p> +<p>Plus exactement, ce qui est dit est que le paiement en ligne permet de +justifier qu'il y a bien eu transaction entre deux personnes, et que donc les +commentaires et &quot;notations&quot; effectuées sont donc légitimes.</p> +</div> +<div class="section" id="ce-n-est-pas-un-probleme-de-confiance"> +<h2>Ce n'est pas un problème de confiance !</h2> +<p>Bien que j'arrive à suivre le raisonnement, il soulève certaines questions :</p> +<p>Si j'accorde de la confiance à quelqu'un dans mon cercle de connaissances, +c'est justement parce qu'il fait partie de ce cercle de connaissances. Pas +parce qu'une personne que je ne connait pas me dit qu'il s'agit d'une personne +de confiance. En d'autres termes, <strong>pourquoi ne garderions nous pas ces +relations privilégiées de personne à personne ?</strong></p> +<p>Dans le cadre du covoiturage, j'arrive à comprendre le raisonnement du paiement +<em>à l'avance</em>, pour avoir souvent entendu parler de désistements à la dernière +minute de la part des voyageurs. Le paiement à l'avance permet d'éviter ce +genre de désagréments.</p> +<p>Mais cela n'as rien à voir avec la confiance, il s'agit d'engagement de la part +des deux parties.</p> +<p>Et c'est bien ce qui semble poser problème: lorsqu'on s'attend à partager le +prix d'un trajet avec quelqu'un, c'est bien d'avoir quelque chose qui nous +y engage. J'aime beaucoup l'idée de payer une fois dans la voiture, de garder +cette transaction manuelle; et de laisser peu de place au paiements en ligne +dans cette histoire, mais je n'ai pas d'autre solution miracle.</p> +<p>En tout cas, la question n'est pas la question de savoir avec qui on embarque, +mais bel et bien la question de l'engagement des deux parties.</p> +<p>Nous sommes malheureusement dans une société qui est dirigée par la peur. On +à peur de se faire agresser par le gars qui tends le pouce sur le bord de la +route, peur de se faire envoyer un produit qui ne fonctionne pas via Amazon, +etc.</p> +<p>En poussant l'idée dans ses retranchements, j'aurais bientôt peur de mes +voisins alors je ne leur parlerais plus, parce qu'ils n'ont pas leur profil +disponible en ligne ou parce que quelqu'un à eu une mauvaise expérience avec +eux ?</p> +<p>Exposer des choses qui relèvent de ma vie privée en ligne de la sorte me +pose des problèmes éthiques: d'abord parce que je ne veux pas juger les gens +a priori, ensuite parce que l'expérience d'une personne n'est peut-être pas +représentative, tout simplement.</p> +<p>Donc non, ce n'est pas un problème de confiance, il s'agit d'un problème +d'engagement, dans le cadre du covoiturage, et les profils en ligne n'ont rien +à faire la dedans. Le principe du paiement à l'avance me semble intéressant, +mais il n'est à mon avis pas lié au profils en ligne.</p> +<p>La vidéo termine sur un &quot;libérez la valeur de la confiance&quot;. Oui, mais la +libérer pour qui ? Quels sont les problèmes liés à cette confiance rendue +nécessaire partout et pour tout ? Cela ne nous ferait-il pas évoluer uniquement +dans des cercles fermés ? Quelle place laisser à l'inconnu, à la surprise ?</p> +<p>Cette volonté de &quot;confiance partout&quot; semble découler tout droit des délires +sécuritaires que l'on nous sert à toutes les sauces. Et maintenant cela +serait rendu accessible à tous grâce à &quot;l'intelligence collective&quot;; gommant au +passage les différences de valeur; Préférant éviter de rencontrer les inconnus +aux profils &quot;légers&quot;.</p> +<p>Je sais pas vous, mais elle me fait peur cette idée.</p> +</div> +Implementing CORS in Cornice2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/cross-origin-in-cornice.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In other +words, if you have a page served from the domain <cite>lolnet.org</cite>, it will not be +possible for it to get data from <cite>notmyidea.org</cite>.</p> +<p>Well, it's possible, using tricks and techniques like <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a>, but that doesn't work all the time (see +<a class="reference external" 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's API.</p> +<p>Thankfully, there is a nicer way to do this, namely, &quot;Cross Origin +Resource-Sharing&quot;, or <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>.</p> +<div class="section" id="you-want-an-icecream-go-ask-your-dad-first"> +<h2>You want an icecream? Go ask your dad first.</h2> +<p>If you want to use CORS, you need the API you're querying to support it; on the +server side.</p> +<p>The HTTP server need to answer to the <cite>OPTIONS</cite> verb, and with the appropriate +response headers.</p> +<p><cite>OPTIONS</cite> is sent as what the authors of the spec call a &quot;preflight request&quot;; +just before doing a request to the API, the <em>User-Agent</em> (the browser most of +the time) asks the permission to the resource, with an <cite>OPTIONS</cite> call.</p> +<p>The server answers, and tell what is available and what isn't:</p> +<img alt="The CORS flow (from the HTML5 CORS tutorial)" src="images/cors_flow.png" /> +<ul class="simple"> +<li>1a. The User-Agent, rather than doing the call directly, asks the server, the +API, the permission to do the request. It does so with the following headers:<ul> +<li><strong>Access-Control-Request-Headers</strong>, contains the headers the User-Agent +want to access.</li> +<li><strong>Access-Control-Request-Method</strong> contains the method the User-Agent want +to access.</li> +</ul> +</li> +<li>1b. The API answers what is authorized:<ul> +<li><strong>Access-Control-Allow-Origin</strong> the origin that's accepted. Can be <cite>*</cite> or +the domain 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 methods.</li> +<li><strong>Access-Allow-Headers</strong> a list of allowed headers, for all of the +methods, since this can be cached as well.</li> +</ul> +</li> +<li><ol class="first arabic" start="2"> +<li>The User-Agent can do the &quot;normal&quot; request.</li> +</ol> +</li> +</ul> +<p>So, if you want to access the <cite>/icecream</cite> resource, and do a PUT there, you'll +have the following flow:</p> +<pre class="literal-block"> +&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 +</pre> +<p>You can see that we have an <cite>Origin</cite> Header in the request, as well as +a <cite>Access-Control-Request-Methods</cite>. We're here asking if we have the right, as +<cite>notmyidea.org</cite>, to do a <cite>PUT</cite> request on <cite>/icecream</cite>.</p> +<p>And the server tells us that we can do that, as well as <cite>GET</cite> and <cite>DELETE</cite>.</p> +<p>I'll not cover all the details of the CORS specification here, but bear in mind +than with CORS, you can control what are the authorized methods, headers, +origins, and if the client is allowed to send authentication information or +not.</p> +</div> +<div class="section" id="a-word-about-security"> +<h2>A word about security</h2> +<p>CORS 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 CORS, so you'll need to +write a proxy yourself, to provide this.</p> +<p>Secondly, if misunderstood, CORS 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're authorizing.</p> +<p>An incorrectly secured CORS 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 VPN 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 want.</p> +</div> +<div class="section" id="how-this-is-different-from-jsonp"> +<h2>How this is different from JSONP?</h2> +<p>You may know the <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> protocol. JSONP +allows cross origin, but for a particular use case, and does have some +drawbacks (for instance, it's not possible to do DELETEs or PUTs with JSONP).</p> +<p>JSONP exploits the fact that it is possible to get information from another domain +when you are asking for javascript code, using the <cite>&lt;script&gt;</cite> element.</p> +<blockquote> +Exploiting the open policy for &lt;script&gt; elements, some pages use them to +retrieve JavaScript code that operates on dynamically generated +JSON-formatted data from other origins. This usage pattern is known as +JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. +They are evaluated by the JavaScript interpreter, not parsed by a JSON +parser.</blockquote> +</div> +<div class="section" id="using-cors-in-cornice"> +<h2>Using CORS in Cornice</h2> +<p>Okay, things are hopefully clearer about CORS, let's see how we +implemented it on the 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 CORS support as +well.</p> +<p>In Cornice, you define a service like this:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>To add CORS support to this resource, you can go this way, with the +<cite>cors_origins</cite> parameter:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> +</pre></div> +<p>Ta-da! You have enabled CORS for your service. <strong>Be aware that you're +authorizing anyone to query your server, that may not be what you want.</strong></p> +<p>Of course, you can specify a list of origins you trust, and you don't need +to stick with <cite>*</cite>, which means &quot;authorize everyone&quot;.</p> +<div class="section" id="headers"> +<h3>Headers</h3> +<p>You can define the headers you want to expose for the service:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> + +<span class="nd">@foobar.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> +</pre></div> +<p>I've done some testing and it wasn't working on Chrome because I wasn't +handling the headers the right way (The missing one was <cite>Content-Type</cite>, 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 developing.</p> +<p>So I introduced an <cite>expose_all_headers</cite> flag, which is set to <cite>True</cite> by +default, if the service supports CORS.</p> +</div> +<div class="section" id="cookies-credentials"> +<h3>Cookies / Credentials</h3> +<p>By default, the requests you do to your API endpoint don't include the +credential information for security reasons. If you really want to do that, +you need to enable it using the <cite>cors_credentials</cite> parameter. You can activate +this one on a per-service basis or on a per-method basis.</p> +</div> +<div class="section" id="caching"> +<h3>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's not redone before each actual call.</p> +<p>The caching period is defined by the server, using the <cite>Access-Control-Max-Age</cite> +header. You can configure this timing using the <cite>cors_max_age</cite> parameter.</p> +</div> +<div class="section" id="simplifying-the-api"> +<h3>Simplifying the API</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 CORS-policy for your services, that +can be a bit tedious to pass these to your services all the time.</p> +<p>I introduced another way to pass the CORS policy, so you can do something like +that:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">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> +</pre></div> +</div> +</div> +<div class="section" id="comparison-with-other-implementations"> +<h2>Comparison with other implementations</h2> +<p>I was curious to have a look at other implementations of CORS, in +django for instance, and I found <a class="reference external" href="https://gist.github.com/426829.js">a gist about it</a>.</p> +<p>Basically, this adds a middleware that adds the &quot;rights&quot; headers to the answer, +depending on the request.</p> +<p>While this approach works, it's not implementing the specification completely. +You need to add support for all the resources at once.</p> +<p>We can think about a nice way to implement this specifying a definition of what's +supposed to be exposed via CORS and what shouldn't directly in your settings. +In my opinion, CORS support should be handled at the service definition level, +except for the list of authorized hosts. +Otherwise, you don't know exactly what's going on when you look at the definition of the service.</p> +</div> +<div class="section" id="resources"> +<h2>Resources</h2> +<p>There are a number of good resources that can be useful to you if you want to +either understand how CORS works, or if you want to implement it yourself.</p> +<ul class="simple"> +<li><a class="reference external" href="http://enable-cors.org/">http://enable-cors.org/</a> is useful to get started when you don't know anything +about CORS.</li> +<li>There is a W3C wiki page containing information that may be useful about +clients, common pitfalls etc: <a class="reference external" href="http://www.w3.org/wiki/CORS_Enabled">http://www.w3.org/wiki/CORS_Enabled</a></li> +<li><em>HTML5 rocks</em> has a tutorial explaining how to implement CORS, with <a class="reference external" 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 class="reference external" href="http://caniuse.com/#search=cors">clients support-matrix for this feature</a>.</li> +<li>About security, <a class="reference external" href="https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity">check out this page</a></li> +<li>If you want to have a look at the implementation code, check <a class="reference external" href="https://github.com/mozilla-services/cornice/pull/98/files">on github</a></li> +</ul> +<p>Of course, the W3C specification is the best resource to rely on. This +specification isn't hard to read, so you may want to go through it. Especially +the <a class="reference external" href="http://www.w3.org/TR/cors/#resource-processing-model">&quot;resource processing model&quot; section</a></p> +</div> +Status board2012-12-29T00:00:00+01:002012-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-29:/status-board-fr.html<p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org …</cite></p><p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org</cite>, mon serveur.</p> +<p>Jusqu'à très récemment, rien de tout ça n'était sauvegardé, et non plus monitoré. +Après quelques recherches, je suis tombé sur <a class="reference external" href="http://www.stashboard.org/">stashboard</a>, un &quot;status board&quot; qu'il est bien fait. Le seul +problème, c'est écrit pour se lancer sur GAE, <em>Google App Engine</em>. +Heureusement, c'est open-source, et ça a été forké pour donner naissance +à <a class="reference external" href="https://github.com/bfirsh/whiskerboard">whiskerboard</a> (la planche +moustachue, pour les non anglophones).</p> +<img alt="Capture d'écran du site." src="images/status_board.png" /> +<div class="section" id="verifier-le-statut-des-services"> +<h2>Vérifier le statut des services</h2> +<p>Donc, c'est chouette, c'est facile à installer, tout ça, mais… mais ça ne fait +en fait pas ce que je veux: ça ne fait que m'afficher le statut des services, +mais ça ne vérifie pas que tout est bien &quot;up&quot;.</p> +<p>Bon, un peu embêtant pour moi, parce que c'est vraiment ça que je voulais. Pas +grave, je sais un peu coder, autant que ça serve. J'ai ajouté quelques +fonctionnalités au soft, qui sont disponibles sur mon fork, sur +github:: <a class="reference external" href="https://github.com/ametaireau/whiskerboard">https://github.com/ametaireau/whiskerboard</a> .</p> +<p>Entres autres, il est désormais possible de lancer <a class="reference external" 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 spécifique.</p> +<p>C'é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 dépote).</p> +<p>Les modifications sont assez simples, vous pouvez aller jeter un œil aux +changements ici: +<a class="reference external" href="https://github.com/ametaireau/whiskerboard/compare/b539337416...master">https://github.com/ametaireau/whiskerboard/compare/b539337416...master</a></p> +<p>En gros:</p> +<ul class="simple"> +<li>ajout d'une <cite>connection_string</cite> aux services (de la forme +protocol://host:port)</li> +<li>ajout d'une commande <cite>check_status</cite> qui s'occupe d'itérer sur les services et +de lancer des taches celery qui vont bien, en fonction du protocole</li> +<li>ajout des taches en question</li> +</ul> +</div> +<div class="section" id="deploiement"> +<h2>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, forcément.</p> +<p>Après un essai (plutôt rapide en fait) sur <a class="reference external" href="http://heroku.com">heroku</a>, je me +suis rendu compte qu'il me fallait payer pas loin de 35$ par mois pour avoir un +process <cite>celeryd</cite> qui tourne, donc j'ai un peu cherché ailleurs, pour +finalement déployer la chose chez <a class="reference external" href="https://www.alwaysdata.com/">alwaysdata</a></p> +<p>Après quelques péripéties, j'ai réussi à faire tourner le tout, ça à été un peu +la bataille au départ pour installer virtualenv (j'ai du faire des changements +dans mon <cite>PATH</cite> pour que ça puisse marcher), voici mon <cite>.bash_profile</cite>:</p> +<pre class="literal-block"> +export PYTHONPATH=~/modules/ +export PATH=$HOME/modules/bin:$HOME/modules/:$PATH +</pre> +<p>Et après y'a plus qu'à installer avec <cite>easy_install</cite>:</p> +<pre class="literal-block"> +easy_install --install-dir ~/modules -U pip +easy_install --install-dir ~/modules -U virtualenv +</pre> +<p>Et à créer le virtualenv:</p> +<pre class="literal-block"> +virtualenv venv +venv/bin/pip install -r requirements.txt +</pre> +<p>Dernière étape, la création d'un fichier <cite>application.wsgi</cite> qui s'occupe de +rendre l'application disponible, avec le bon venv:</p> +<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span> +<span class="kn">import</span> <span class="nn">sys</span> + +<span class="n">activate_this</span> <span class="o">=</span> <span class="s1">&#39;/home/lolnet/venv/bin/activate_this.</span> +<span class="nb">execfile</span><span class="p">(</span><span class="n">activate_this</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="vm">__file__</span><span class="o">=</span><span class="n">activate_this</span><span class="p">))</span> + +<span class="n">paths</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;/home/lolnet/public&#39;</span><span class="p">,]</span> + +<span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">paths</span><span class="p">:</span> + <span class="k">if</span> <span class="n">path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="p">:</span> + <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> + + <span class="kn">import</span> <span class="nn">django.core.handlers.wsgi</span> + <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;DJANGO_SETTINGS_MODULE&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;settings&#39;</span> + <span class="n">application</span> <span class="o">=</span> <span class="n">django</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIHandler</span><span class="p">()</span> +</pre></div> +</div> +<div class="section" id="ssl-et-requests"> +<h2>SSL et Requests</h2> +<p>Quelques tours de manivelle plus loin, j'ai un celeryd qui tourne et qui +consomme les taches qui lui sont envoyées (pour des questions de simplicité, +j'ai utilisé le backend <cite>django</cite> de celery, donc pas besoin d'AMQP, par +exemple).</p> +<p>Problème, les ressources que je vérifie en SSL (HTTPS) me jettent. Je sais pas +exactement pourquoi à l'heure qu'il est, mais il semble que lorsque je fais une +requête avec <a class="reference external" 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 <cite>CURL</cite> fonctionnent, donc j'ai fait <a class="reference external" href="https://github.com/ametaireau/whiskerboard/blob/master/board/tasks.py#L17">un fallback +vers CURL lorsque les autres méthodes échouent</a>. +Pas super propre, mais ça fonctionne.</p> +<p><strong>EDIT</strong> Finalement, il se trouve que mon serveur était mal configuré. +J'utilisais haproxy + stunnel, et la négiciation SSL se passait mal. Une fois +SSL et TLS activés, et SSLv2 désactivé, tout fonctionne mieux.</p> +</div> +<div class="section" id="et-voila"> +<h2>Et voilà</h2> +<p>Finalement, j'ai mon joli status-board qui tourne à merveille sur +<a class="reference external" href="http://status.lolnet.org">http://status.lolnet.org</a> :-)</p> +</div> +Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag: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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais …</p><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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais vous aussi ça vous +titille:</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.habicoop.fr/IMG/pdf/Memoire_hbtat_coop_Vaulx-2.pdf">L’Habitat Coopératif : Solution au problème de responsabilisation sociale des +copropriétaires sur la commune de Vaulx en Velin +?</a> - mémoire REPIQUET Anne +2005.</li> +<li>Un bouquin à lire avec plein d'infos: <a class="reference external" href="http://www.ecosociete.org/t101.php">Vivre autrement</a> de Diana Leafe Christian.</li> +<li>…</li> +</ul> +Languages2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/languages.html<p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe><p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe>Tricot2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/tricot.html<p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu …</p><p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu +près un rang d'endroit et j'arrive pas à enchainer sur l'envers pour réussir +à faire un point jersey (jersey c'est un rang endroit puis un rang envers).</p> +<p>Enfin bref, si jamais ça vous botte vous aussi, voila quelques ressources que +j'ai trouvé sur internet (en plus des conseils avisés de maman chérie™):</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.youtube.com/watch?v=VcGiBG2BNxo&amp;list=UUskaiVNnKf7amRb5OI5op_w">Montage des mailles &quot;normales&quot;</a></li> +<li><a class="reference external" href="http://www.youtube.com/watch?v=aIQtNN89pqA&amp;list=UUskaiVNnKf7amRb5OI5op_w">Le point jersey</a></li> +</ul> +<p>La nana explique plutôt bien et assez lentement. En espérant que ça prenne.</p> +Astuces SSH2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/astuces-ssh.html<div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s …</pre></div><div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') +PATH=.:\$PATH nc -w1 $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /') +</pre> +<p>On peut donc spécifier des &quot;sauts&quot; ssh du style:</p> +<pre class="literal-block"> +ssh root&#64;91.25.25.25+192.168.1.1 +</pre> +<p>Ensuite on peut essayer de rajouter:</p> +<pre class="literal-block"> +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é +</pre> +</div> +Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag: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'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial …</a></li></ul><p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de +ubuntu, j'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial Menu</a> vire les +boutons et textes en rapport avec le web social. J'en avais pas besoin +puisque je suis connecté à mon instant messenger dans un terminal, en +utilisant weechat.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/97/coverflow-alt-tab/">Coverflow Alt-Tab</a> change le +switcher d'applications par defaut. Je le trouve bien plus pratique que celui +par defaut puisqu'il me permet de voir &quot;en grand&quot; quelle est la fenêtre que +je vais afficher.</li> +<li><a class="reference external" 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'intègre niquel avec +Spotify, et ça c'est chouette.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/149/search-firefox-bookmarks-provider/">Rechercher dans les bookmarks firefox</a> +permet de… à votre avis ?</li> +</ul> +<p>Un peu moins utile mais sait on jamais:</p> +<ul class="simple"> +<li>“<a class="reference external" href="https://extensions.gnome.org/extension/130/advanced-settings-in-usermenu/">Advanced Settings in UserMenu</a>” +permet d'avoir un raccourci vers les paramètres avancés dans le menu +utilisateur (en haut à droite)</li> +<li>Une <a class="reference external" href="https://extensions.gnome.org/extension/409/gtg-integration/">intégration à Getting things Gnome</a> (un truc de +GTD). Je suis en train d'expérimenter avec cet outil, donc je ne sais pas +encore si ça va rester, mais pourquoi pas.</li> +</ul> +<p>Vous pouvez aller faire un tour sur <a class="reference external" href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> +pour en trouver d'autres à votre gout.</p> +"Groovy"2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/groovy.html<p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>C'est pour ça que j'ai du …</p><p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>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 ;)</p> +Notre dame des landes2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/notre-dame-des-landes.html<p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre …</p><p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre +2012:</p> +<ul class="simple"> +<li>Article dans le monde qui explique la complexité de la lutte sur place: <a class="reference external" href="http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html">http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html</a></li> +<li>autour de relations à la presse: +<a class="reference external" href="http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html">http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html</a></li> +<li>Notre-Dame-des-Landes : un pilote annonce un fiasco pour le futur aéroport <a class="reference external" href="http://www.bastamag.net/article2866.html">http://www.bastamag.net/article2866.html</a></li> +</ul> +Semences paysannes2012-12-20T00:00:00+01:002012-12-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-20:/semences-paysannes.html<p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité …</p><p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité en 1960 au sein de l'UPOV pour faire des textes pour s'approprié les selections qu'ils ont fait. Les textes ont été votés par les députés depuis: bien prové au lieu de bien collectif.</p> +<p>Les semenciers n'existent que depuis 150 ans. Ils revendiquent maintenant le monopole de selection.</p> +<p>Un catalogue est prévu pour les semences dites &quot;de conservation&quot; (alors qu'elles évoluent, conservation n'est pas un terme adapté). C'est la voie qui est possible pour pouvoir échanger des semences entre agriculteurs.</p> +<p>→ Quelles sont les semences de conservation depuis 2002 ? → Quid des semences paysannes, qui évoluent et que l'on garde d'année en année, en selectionnant les meilleures especes. → Existe-il un autre catalogue ? → Au niveau européen, quelles sontles contraintes d'inscription ? Gratuité demandée, qu'en est il ?</p> +<p>→ Relocalistion sur les terroirs des échanges.</p> +<p>→ Biodiversité serait tué par l'utilisation d'espèces inscrites.</p> +<p>Série de vidéos sur la paysannerie: <a class="reference external" href="http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86">http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86</a></p> +Lifestyle2012-11-05T00:00:00+01:002012-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-11-05:/lifestyle-fr.html<p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre …</p><p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre une vie connectée et +une vie <em>réelle</em> (oui, celle avec des vrais gens qui ont d'autres +préoccupations que l'informatique !). Comment réussir à trouver un juste +milieu entre le geek inconditionnel et le bon vivant, qui à du temps à +consacrer à autre chose qu'à son travail ?</p> +<div class="section" id="voyages"> +<h2>Voyages</h2> +<p>Un des premiers trucs que j'ai trouvé surprennant en arrivant à Mozilla, c'est +la fréquence des voyages que l'on peut être amené à avoir. Ah, c'est pour la +bonne cause, c'est tellement plus sympa d'avoir les collègues à coté pour +bosser, plutôt qu'à l'autre bout du monde. Mais quand même, si je le voulais, +entre les semaines de travail et les conférences, je pourrais être tous les +deux mois aux États-Unis !</p> +<p>Une aubaine, penserons certains. Voyager, c'est <em>cool</em> ! Bon, si on mets de +coté le cout écologique d'un voyage (nécessairement en avion), la chose qui me +dérange le plus c'est cette impression de venir pour repartir. Voyager, c'est +sympa, mais avoir le temps de prendre un rythme de vie différent, de rencontrer +des gens, de construire quelque chose, ça me manque.</p> +<p>Donc je décline quand je n'en ai pas l'envie, tout simplement. Je loupe des +choses intéressantes (<a class="reference external" href="http://pycon.us">PyCon</a> à Santa Clara avait vraiment l'air +chouette !), mais ça me permet également d'avoir plus de temps pour vivre là ou +j'habite, pour construire quelque chose localement. Et puis des évènements, il +y en à tellement en France et en Europe auquel je n'assiste pas que ça me fait +mal au cœur d'aller à l'autre bout du monde pour faire la même chose !</p> +<p>Bien sur, je serais amené à voyager. Et autant que faire se peut je le +ferais avec plaisir et je tenterais de rester un peu plus avant et après sur +place (plus question de faire un aller/retour en une semaine !), question de me +faire à l'atmosphère ! <a class="reference external" href="http://ziade.org">Tarek</a> est par exemple resté un mois à San Francisco +en janvier pour son dernier séjour, alors pourquoi ne pas prendre exemple ? +Tout de suite ça me parles plus.</p> +</div> +<div class="section" id="et-quand-est-ce-qu-on-arrete"> +<h2>Et quand-est-ce qu'on arrête ?</h2> +<p>Une autre chose assez difficile à gérer, c'est le temps.</p> +<p>J'ai vraiment une chance monstrueuse, celle de faire un travail qui me plait, +éthiquement et techniquement. Je pourrais y passer mes journées et mes nuits +que je n'aimerais pas moins ça (même si il m'arrive bien sur de saturer !).</p> +<p>Mais j'ai aussi d'autres envies, qui signifient aussi passer du temps +hors-ligne, parce que bizarrement, c'est là que j'ai l'impression de réfléchir +le plus. Loin de ce surplus d'informations…</p> +<p>Facile à dire.</p> +<p>D'autant que quand il est possible de travailler depuis n'importe où, +la séparation physique entre le lieu de travail et le lieu de vie tends à +disparaitre assez facilement. Et sans séparation physique, il faut une sacré +motivation pour savoir quand commencer et quand s'arrêter.</p> +<p>J'essaye de me donner une règle simple: point trop n'en faut. Aucun intérêt à +rester travailler des heures durant sans s'arrêter, ou en tout cas pas +d'intérêt à le faire de manière trop régulière. Une journée qui commence tôt +(~9h) me permet de me concentrer le matin (les collègues californiens dorment) +et d'avoir un rythme assez &quot;normal&quot;. Et puis, avec ce soleil qui commence à +inonder les terrasses, autant faire autre chose que de rester enfermé à coder +en fin d'après midi !</p> +</div> +<div class="section" id="surplus"> +<h2>Surplus</h2> +<p>Tiens, je parlais de surplus, nous y sommes. Que ça soit le surplus +d'informations ou le surplus d'objets, ça m'encombre ! Une journée, pour ma +part est faite de communications diverses, de code et de lectures (se tenir au +courant de ce qui se passe dans le monde du logiciel n'est pas une tâche des +plus facile, et qui peut facilement prendre énormément de temps).</p> +<p>Je me demande si je ne devrais pas aspirer à la frugalité de ce coté là +également. Je reçois des mails toute la journée, et mon aggrégateur rss/atom se +remplit également très vite. Mais je n'ai aucunement besoin d'avoir toutes ces +informations dans l'heure, et de les vérifier de manière fréquente. De la même +manière, j'ai simplement arrêté de lire mes flux rss.</p> +<p>Quelques (longues) fois dans la semaine semblent suffire et me permettent de +réussir à rester concentrer.</p> +</div> +<div class="section" id="resolutions"> +<h2>Résolutions</h2> +<p>Soyons fous, tentons quelque chose de nouveau, c'est le printemps ! Pas de +communication dans la matinée, je n'en ai probablement pas besoin, sauf cas +extrêmes. Le matin, c'est pour se concentrer sur le travail à faire.</p> +<p>Une fois les mails du matin dépilés (à 9h30), pas la peine de garder un œil +sur ma boite mail, j'irais y faire un tour en début et en fin d'après midi.</p> +<p>Je pense même à débrancher internet, pour éviter les interactions et pour me +concentrer, mais j'ai comme l'impression que c'est un peu trop abrupt comme +approche.</p> +<p>Aussi, définir en début de journée la liste des choses prévues, et revenir +dessus jour après jour me permettra surement d'avoir un aperçu un peu plus +global du travail accompli.</p> +<p>L'avenir dira si tout ça fonctionne :-)</p> +</div> +Cheese & code - Wrap-up2012-10-22T00:00:00+02:002012-10-22T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.html<p>This week-end I hosted a <em>cheese &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 well.</p> +<p>Here is a summary of what we worked on:</p> +<div class="section" id="daybed"> +<h2>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 REST web service, in python, and open +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're using <strong>CouchDB</strong> as a backend.</p> +<img alt="Daybed is a big couch!" src="images/daybed.jpg" style="width: 400px;" /> +<p>We mainly hacked on daybed and are pretty close to the release of the first +version, meaning that we have something working.</p> +<p><a class="reference external" href="http://github.com/spiral-project/daybed">The code</a> is available on github, +and we also wrote <a class="reference external" href="http://daybed.rtfd.org">a small documentation</a> for 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'm pretty confidend that we now have really good basis for this project.</p> +<p>Also, we will have a nice todolist application, with the backend <strong>and</strong> the +frontend, in javascript / html / css, you'll know more when it'll be ready :-)</p> +<p>Once we have something good enough, we'll release the first version and I'll +host it somewhere so that people can play with it.</p> +</div> +<div class="section" id="cornice"> +<h2>Cornice</h2> +<p>Daybed is built on top of <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, a framework to +ease the creation of web-services.</p> +<p>At Pycon France, we had the opportunity to attend a good presentation about <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a>. SPORE is a way to describe your +REST web services, as WSDL is for WS-* services. This allows to ease the +creation of generic SPORE clients, which are able to consume any REST API with +a SPORE endpoint.</p> +<p>Here is how you can let cornice describe your web service for you</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>And you'll get a definition of your service, in SPORE, available at <cite>/spore</cite>.</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, etc.</p> +<p>I released today <a class="reference external" href="http://crate.io/packages/cornice/">Cornice 0.11</a>, which adds +into other things the support for SPORE, plus some other fixes we found on our +way.</p> +</div> +<div class="section" id="respire"> +<h2>Respire</h2> +<p>Once you have the description of the service, you can do generic clients +consuming them!</p> +<p>We first wanted to contribute to <a class="reference external" href="https://github.com/bl0b/spyre">spyre</a> but +it was written in a way that wasn't supporting to <cite>POST</cite> data, and they +were using their own stack to handle HTTP. A lot of code that already exists in +other libraries.</p> +<p>While waiting the train with <a class="reference external" href="http://natim.ionyse.com/">Rémy</a>, we hacked +something together, named &quot;Respire&quot;, a thin layer on top of the awesome +<a class="reference external" href="http://python-requests.org">Requests</a> 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're still hacking on it so it may break +(for the better), but that had been working pretty well for us so far.</p> +<p>You can <a class="reference external" 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 daybed)</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Finally, we were out of cheese so everyone headed back to their respective +houses and cities.</p> +<p>Until next time?</p> +</div> +Cheese & Code party: October 20-212012-09-20T00:00:00+02:002012-09-20T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-20:/afpy-computer-camp-october-20-21.html<p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing …</p><p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing something related with the Afpy Computer +Camps at his house each year, I've been there twice and it really was a nice +experience.</p> +<p>At Djangocong 2012, in Montpellier (south of France), <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu Leplatre</a> and myself started to work on a model +validation and storage service, named <a class="reference external" href="https://github.com/spiral-project/daybed/">Daybed</a>.</p> +<p>I've talked about this project to some persons this week-end (I've even done <a class="reference external" href="http://alexis.notmyidea.org/lightning-daybed.html">a +lightning talk</a> about it) +and it gathered some interest from people in the python community, so we +thought about sprinting on this.</p> +<div class="section" id="and-21-october-a-computer-camp"> +<h2>20 and 21 October - A Computer Camp !</h2> +<p>Add to this a few beers, and the sprint turns magically into a camp. We'll be +sprinting at the end of October (the 20 and 21) near Angers, on daybed.</p> +<p>We plan to have great food and wine, so if you feel like it and if you want to +come and work on some python-related things, you're invited!</p> +<p>Although, I can host a limited number of persons, so you'll need to contact me +before :), that's <cite>alexis at notmyidea dot org</cite>.</p> +<p>I've setup a wiki page to organize a bit everything (knowing how many people will +come by will allow me to handle things better), please put information there:</p> +<p><a class="reference external" href="http://wiki.python.org/moin/ComputerCampAlexis">http://wiki.python.org/moin/ComputerCampAlexis</a></p> +</div> +Circus sprint at PyconFR2012-09-17T00:00:00+02:002012-09-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.html<p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're …</p><p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're using +at Mozilla for some of our 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 features.</p> +<p>Having people wanting to sprint on our projects is exciting because that's +when making things in the open unleashes its full potential. You can't imagine +how happy I was to have some friends come and work on this with us :)</p> +<p>Here is a wrap-up of the sprint:</p> +<div class="section" id="autocompletion-on-the-command-line"> +<h2>Autocompletion on the command-line</h2> +<p><a class="reference external" 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're using bash. It seems that not that much work is needed to +make it happen on zsh as well :)</p> +<p><a class="reference external" href="https://github.com/mozilla-services/circus/blob/master/extras/circusctl_bash_completion">Have a look at the feature</a></p> +<p>On the same topic, we now have a cool shell for Circus. If you start the +<cite>circusctl</cite> command without any option, you'll end-up with a cool shell. Thanks +<a class="reference external" href="https://github.com/jojax">Jonathan Dorival</a> for the work on this! You can +have a look at <a class="reference external" href="https://github.com/mozilla-services/circus/pull/268">the pull request</a>.</p> +</div> +<div class="section" id="future-changes-to-the-web-ui"> +<h2>Future changes to the web ui</h2> +<p><a class="reference external" 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'm glad of this. +Currently, it's done with bottle.py and we want to switch to 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 instance.</p> +</div> +<div class="section" id="bug-and-doc-fixing"> +<h2>Bug and doc fixing</h2> +<p>While reading the source code, we found some inconsistencies and fixed them, +with <a class="reference external" href="http://mathieu.agopian.info/">Mathieu Agopian</a>. We also tried to +improve the documentation at different levels.</p> +<p>Documentation still needs a lot of love, and I'm planning to spend some time on +this shortly. I've gathered a bunch of feedback on this</p> +</div> +<div class="section" id="circus-clustering-capabilities"> +<h2>Circus clustering 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 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 be.</p> +<p>Remy wrote <a class="reference external" href="http://tech.novapost.fr/circus-clustering-management-en.html">a good summary about our brainstorming</a> so I'll not do +it again here, but feel free to contact us if you have ideas on this, they're +very welcome!</p> +</div> +<div class="section" id="project-management"> +<h2>Project management</h2> +<p>We've had some inquiries telling us that's not as easy as it should to get +started with the Circus project. Some of the reasons are that we don't +have any release schedule, and that the documentation is hairy enough to lost +people, at some point :)</p> +<p>That's something we'll try to fix soon :)</p> +<p>PyconFR was a very enjoyable event. I'm looking forward to meet the community +again and discuss how Circus can evolve in ways that are interesting to +everyone.</p> +<p>Tarek and me are going to <a class="reference external" href="http://python.ie/pycon/2012/">Pycon ireland</a>, feel +free to reach us if you're going there, we'll be happy to meet and enjoy beers!</p> +</div> +Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla-fr.html<p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi …</p><p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi je me suis dit que ça pouvait avoir du sens de l'écrire +quelque part.</p> +<p>Ça parle bien sur de logiciel libre, de protection de la vie privée et de +contre-pouvoirs.</p> +<p>Je ne m'adresse pas ici aux afficionados du logiciel libre et du non contrôle +du web, mais aux potentiels intéressés, qui souhaitent comprendre ce qu'on fait +à Mozilla, pourquoi et comment, et plus particulièrement quel est le rôle que +je joue la dedans.</p> +<div class="section" id="logiciel-libre"> +<h2>Logiciel libre</h2> +<p>Une des premières choses qui vient à l'esprit des gens quand on parle de +Mozilla, et par extension de Firefox, c'est qu'il s'agit d'un logiciel gratuit. +D'un logiciel soit disant &quot;libre&quot;. Avouez que le concept est de prime abord +curieux. Un logiciel qui serait libéré, mais libéré de quoi ?</p> +<p>Je ne vais pas refaire la génèse du logiciel et du logiciel libre, mais pour +résumer et expliquer ça très grossièrement, le logiciel libre c'est pour moi +l'idée de la collaboration. &quot;Plutôt que de travailler chacun dans son coin, +construisons ensemble quelque chose qui nous sera utile à tous&quot;. Ça marche dans +le domaine de l'informatique parce qu'on est exposé à un bien commun non +matériel. Ce n'est pas parce que je te donne un logiciel que je ne l'ai plus. +La duplication est possible et elle rend la collaboration plus facile.</p> +<div class="section" id="euh-oui-mais"> +<h3>Euh, oui mais…</h3> +<p>Ok, ok. Et comment on coopère ? Derrière un logiciel, il faut écrire des lignes +de code, il faut décrire comment doit se comporter le logiciel dans l'ensemble +des cas qu'il peut rencontrer. Mais pas seulement. Beaucoup de personnes +travaillent pour faire en sorte que Firefox soit disponible dans près de 100 +langues et dialectes par exemple.</p> +<p>J'aime beaucoup penser que le logiciel libre réussit à réunir des personnes +avec des objectifs differents. Linux, qui est un logiciel libre, est par exemple +utilisé dans beaucoup de domaines très différents tels que la médecine, +l'automobile ou l'énergie.</p> +<p>Le logiciel libre est une valeur clé que nous défendons chez Mozilla.</p> +</div> +</div> +<div class="section" id="protection-de-la-vie-privee"> +<h2>Protection de la vie privée</h2> +<p>Mozilla en fait un peu sa devise. Nous ne sommes pas une entreprise, nous +n'avons aucun intérêt à enfermer les utilisateurs chez nous, et surtout nous +n'exploitons et n'exploiterons pas les données utilisateurs à des fins +commerciales. Jamais.</p> +<div class="section" id="stockage-des-donnees"> +<h3>Stockage des données</h3> +<p>Un exemple qui est frappant est celui de <a class="reference external" href="https://www.mozilla.org/en-US/mobile/sync/">Sync</a>, l'outil qui permet de +synchroniser les données de navigation entre plusieurs périphériques (Cela peut +être utile pour avoir votre historique de navigation partagé entre votre +ordinateur de bureau et un téléphone portable par exemple)</p> +<p>Les données qui sont stockées dans un service tel que sync sont cruciales: vos +mots de passe et votre historique de navigation par exemple. Imaginez ce que +des annonceurs publicitaires pourraient faire avec ces données. Il est assez +facile de connaître votre profil et donc d'ensuite faire de la publicité +ciblée à partir de ces informations. Voire pire. Donner ces données à qui fait +suffisemment pression sur vous pour les récupérer.</p> +<p>Heureusement, les données qui sont stockées sur les serveurs Sync sont +chifrées, et seul l'utilisateur a accès a la clé de chiffrement et de +déchiffrement. En d'autres termes, en ayant accès aux serveurs de Mozilla, même +de l'intérieur, je pourrais avoir accès à vos données mais je ne pourrais rien +en faire car celles-ci me sont impossibles à déchiffrer.</p> +<p>Mozilla essaye de mettre le doigt là où ça fait mal dans l'innovation web&nbsp;: la +publicité et le respect de la vie privée des utilisateurs. Facebook, Google, +Twitter sont autant d'entreprises qui gagnent de l'argent grâce à leurs +utilisateurs et à leurs données privées.</p> +<p>Cela n'est pas <em>nécessairement</em> un mal mais il me semble important d'informer +les utilisateurs d'Internet la dessus, et de leur proposer des méthodes qui +leur permettent de protéger leur vie privée.</p> +</div> +<div class="section" id="decentralisation"> +<h3>Décentralisation</h3> +<p>Un autre aspect important est le fait que vous n'avez pas besoin de dépendre des +serveurs de Mozilla si vous ne souhaitez pas en dépendre. Bien que nous +fassions tout ce qui est en notre pouvoir pour avoir des serveurs très réactifs +et capables de tenir la charge, nous ne sommes pas à l'abri de pannes. Auquel +cas il vous faudra simplement vous armer de patience.</p> +<p>Mais il est possible pour vous de maintenir votre propre serveur et de ne pas +dépendre de Mozilla pour stocker vos données privées. J'ai parlé de Sync mais +Mozilla (j'en parle un peu plus bas) travaille aussi sur un système +d'exploitation pour téléphone portable, nommé Firefox OS (anciennement Boot 2 +Gecko), et sur l'écosystème qui va avec.</p> +<p>Actuellement, si vous souhaitez synchroniser vos contacts par exemple, vous +dépendez quasiment toujours d'une autorité à qui vous ne faites peut être pas +confiance: Apple, Microsoft ou bien Google.</p> +<p>On ne vous propose pas simplement de nous faire confiance, on vous propose la +possibilité de ne faire confiance qu'à ceux à qui vous souhaitez accorder votre +confiance, et ça peut être vous si vous le souhaitez.</p> +<p>La décentralisation à ceci de bon qu'elle vous laisse le choix d'où vous +souhaitez stocker vos données.</p> +</div> +</div> +<div class="section" id="innovation-et-standardisation"> +<h2>Innovation et standardisation</h2> +<p>Mozilla, dès ses débuts, a été un laboratoire. Firefox (si je ne me trompe pas) +a été le premier navigateur à avoir des onglets. Le web, c'est cool parce que +ça bouge tout le temps ! (Edit: en fait, <a class="reference external" href="http://en.wikipedia.org/wiki/Tabbed_document_interface">ce n'était pas le premier</a>, mais l'idée est là)</p> +<p>La dernière innovation en date est Firefox OS: utilisons les technologies du +web pour créer un téléphone: utilisons le web comme plateforme, et profitons de +tout l'écosystème qui existe déjà autour de celui-ci.</p> +<p>C'est bien que ça bouge mais il faut qu'on se mette d'accord sur comment on +veut faire bouger les choses. La guerre des navigateurs a eu lieu. Ne pas +reproduire ça est parfois un challenge. La standardisation, tout le monde s'y +met.</p> +<p>On a gagné une guerre: aux utilisateurs de choisir les outils qu'ils souhaitent +et non pas aux développeurs d'imposer leurs choix.</p> +</div> +<div class="section" id="et-moi-qu-est-ce-que-je-fais-la-dedans"> +<h2>Et moi, qu'est-ce que je fais la dedans ?</h2> +<p>Je travaille dans l'équipe nommée Services. On travaille à la mise en +place de services web qui sont capables de tenir la charge, de fonctionner de +manière décentralisée.</p> +<p>Ce travail a plusieurs objectifs:</p> +<ul class="simple"> +<li>Mettre à disposition des outils pour les développeurs, leur permettant de +créer des services de bonne qualité rapidement;</li> +<li>Permettre aux utilisateurs d'héberger eux mêmes leurs propres serveurs s'ils +le souhaitent, réduisant leur dépendance a des services externes.</li> +<li>Écrire les services en question de telle manière que les utilisateurs (vous +!) puissent les utiliser sans avoir trop de tracas :)</li> +</ul> +<p>Ça semble peu, mais j'aime ce boulot. Éthiquement et techniquement. C'est ça, +pour moi, la mission de Mozilla. Si vous avez des suggestions sur ce qui +pourrait être amélioré dans les services de Mozilla en termes de protection de +la vie privée, de décentralisation et de haute disponibilité, vous savez vers +qui vous tourner !</p> +<p>La liste des projets sur lesquels je travaille ou j'ai travaillé à Mozilla pour +l'instant:</p> +<ul class="simple"> +<li><a class="reference external" href="https://github.com/mozilla-services/tokenserver">https://github.com/mozilla-services/tokenserver</a></li> +<li><a class="reference external" href="http://circus.io/">http://circus.io/</a></li> +<li><a class="reference external" href="http://powerhose.rtfd.org/">http://powerhose.rtfd.org/</a></li> +<li><a class="reference external" href="https://github.com/mozilla-services/server-aitc">https://github.com/mozilla-services/server-aitc</a></li> +<li><a class="reference external" href="http://cornice.readthedocs.org/en/latest/index.html">http://cornice.readthedocs.org/en/latest/index.html</a></li> +<li><a class="reference external" href="https://github.com/mozilla/PyBrowserID/">https://github.com/mozilla/PyBrowserID/</a></li> +<li><a class="reference external" href="http://chaussette.readthedocs.org/en/0.3/index.html">http://chaussette.readthedocs.org/en/0.3/index.html</a></li> +</ul> +</div> +Refactoring Cornice2012-05-14T00:00:00+02:002012-05-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-05-14:/refactoring-cornice.html<p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> routing system, +allowing to register services in …</p><p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" 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 HTTP headers <a class="reference external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">as defined by the HTTP specification</a> without the need +from the developer to deal with them nor to know them.</p> +<p>If you're not familiar with Cornice, here is how you define a simple service +with it:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>This external API is quite cool, as it allows to do a bunch of things quite +easily. For instance, we've written our <a class="reference external" href="https://github.com/mozilla-services/tokenserver">token-server</a> code on top of this in a +blast.</p> +<div class="section" id="the-burden"> +<h2>The 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 internally.</p> +<p>The API of the <cite>cornice.service.Service</cite> class was as following (simplified so +you can get the gist of it).</p> +<div class="highlight"><pre><span></span><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="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="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> +</pre></div> +<p>I encourage you to go read <a class="reference external" 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 done.</p> +<p>A bunch of things are wrong:</p> +<ul class="simple"> +<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 <cite>get_drink</cite>, you will instead get a decorator which +contains this view.</li> +<li>second, we are using decorators as APIs we expose. Even if decorators are +good as shortcuts, they shouldn't be the default way to deal with an API. A +good example of this is <a class="reference external" href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/resource.py#L56">how the resource module consumes this API</a>. +This is quite hard to follow.</li> +<li>Third, in the <cite>api</cite> 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 API.</li> +</ul> +</div> +<div class="section" id="how-do-we-improve-this"> +<h2>How do we improve this?</h2> +<p>Python is great because it allows you to refactor things in an easy way. What I +did isn'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 API that much.</p> +<p>Here is the gist of the new architecture:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">None</span><span class="p">):</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="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="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> +</pre></div> +<p>So, the service is now only storing the information that'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 +<cite>register_service_views</cite> and has the following signature:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>To sum up, here are the changes I made:</p> +<ol class="arabic simple"> +<li>Service description is now separated from the route registration.</li> +<li><cite>cornice.service.Service</cite> now provides a <cite>hook_view</cite> method, which is not a +decorator. decorators are still present but they are optional (you don't +need to use them if you don't want to).</li> +<li>Everything has been decoupled as much as possible, meaning that you really +can use the <cite>Service</cite> class as a container of information about the services +you are describing. This is especially useful when generating 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. <cite>cornice.services.Service</cite> 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 system.</p> +<p>However, no integration with other frameworks is done at the moment even if the +design allows it.</p> +<p>The same way, the sphinx description layer is now only a consumer of this +service description tool: it looks at what's described and build-up the +documentation from it.</p> +<p>The resulting branch is not merged yet. Still, you can <a class="reference external" 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 :-)</p> +</div> +Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-30:/bidouille-fr.html<p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de …</p><p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de comprendre comment les choses fonctionnent, +et depuis peu cette envie de mettre en pratique ces connaissances dépasse la +bidouille logicielle. J'ai passé une grosse partie de mon week-end à Main +d'Œuvre, où l'association <a class="reference external" href="http://www.underconstruction.fr">Under Construction</a> faisait se rencontrer le milieu de +l'éducation populaire et le milieu de la bidouille.</p> +<p>Forcement, ni une ni deux, je saute dans le bateau en marche et, n'étant ni un +très grand bidouilleur ni un très grand animateur, j'en ressort enrichi de +toutes ces rencontres, de tous ces préjugés qui tombent, et de quelques +découvertes bluffantes, des idées plein la tête.</p> +<p>J'avais entendu parler des &quot;<a class="reference external" href="http://www.reprap.org">rep-raps</a>&quot;, des +imprimantes en 3 dimensions capables de produire des pièces en plastique +mais je n'avais jamais eu l'occasion de voir le bousin en vrai. Et +c'est impressionnant. Vraiment. (&quot;Bienvenue dans le 21ème siècle !&quot;)</p> +<p>Ça laisse énormément à penser autour des questions d'émancipation +technologique, et de non dépendance envers les constructeurs, dans le milieu de +l'électro-ménager, par exemple. &quot;Ah tiens, cette pièce est cassée, je vais +aller utiliser la rep-rap du coin pour me la fabriquer&quot;. Et hop, on mets fin à +tout un cycle d'obsolescence programmée…</p> +<p>Mais au delà du défi technique et technologique, j'ai pu refaire un petit peu +d'électronique, et découvrir que j'y prends vraiment gout rapidement. Il y a +bien évidemment un coté très ludique (la led s'allume quand on la branche), +mais il y a surtout cette notion de DIY (Do It Yourself) sous jacente: une fois +que je sais comment ça fonctionne, je peux vraiment faire des choses utiles de +mes 10 doigts, réparer des petits objets, bidouiller ceux existants etc.</p> +<p>De la récupération de composants on essaye de voir ce qu'on peut faire, on a +terminé par faire un &quot;vibro-bot&quot;, un vibreur de téléphone portable monté sur +une tête de brosse à dents, faisant donc avancer cette dernière.</p> +<p>C'est pour s'amuser, c'est pas sérieux ! Pour autant, les concepts de +l'électricité sont appris et je me retrouve avec cette envie de comprendre un +peu plus ce monde de l'électronique qui, je m'en rends compte, m'échappe encore +complètement. De l'éducation à la bidouille !</p> +<p>Allez, demain c'est fer à souder, piles, leds, interrupteurs, potars et c'est +parti !</p> +Djangocong 20122012-04-16T00:00:00+02:002012-04-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-16:/djangocong-2012-fr.html<p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une …</p><p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une qualité d'é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 :)</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'ai eu l'occasion de discuter de projets tournant autour de +l'entraide, que ça soit pour mettre en lien des associations d'économie sociale +et solidaire (ESS) ou simplement pour que les populations <em>non tech</em> <a class="reference external" href="http://blog.notmyidea.org/quels-usages-pour-linformatique-fr.html">puissent +utiliser toute la puissance de l'outil qu'est le web</a>.</p> +<p>Au niveau du format des conférences, je ne savais pas trop à quoi m'attendre, +au vu des échos de l'an dernier, mais c'était adapté: des mini-confs de 12mn le +samedi matin + début d'aprem, en mode no-wifi pour récupérer une qualité +d'écoute. Et contrairement à mes attentes, ce n'est pas trop court. Pas mal de +retours d'expérience pour le coup, et une matinée pas vraiment techniques, mais +ça pose le décor et permet de savoir qui fait quoi.</p> +<p>Parmi l'ensemble des conférences du matin, je retiens principalement +celle de Mathieu Leplatre, &quot;des cartes d'un autre monde&quot;, qui m'a réellement +bluffée quand à la facilité de créer des cartes avec <a class="reference external" href="http://mapbox.com/tilemill/">TileMill</a>, et qui me pousse à reconsidérer le fait que &quot;la +carto, c'est compliqué&quot;. <a class="reference external" href="https://www.youtube.com/watch?v=7NPQo54NbJ8">La vidéo est (déja !) disponible en ligne</a>, je vous invite à la regarder +(c'est une 15aine de minutes) pour vous faire un avis ;)</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 &quot;notre&quot; projet <a class="reference external" href="http://blog.notmyidea.org/carto-forms-fr.html">&quot;carto +forms&quot;</a>, qui à finalement pu se +redéfinir un peu plus et donner naissance à un <a class="reference external" href="https://github.com/spiral-project/daybed/blob/master/README.rst">README</a>. On en +à profité pour lui choisir un nouveau nom: &quot;daybed&quot;, en référence à couchdb.</p> +<p>Ça devrait se transformer en code d'ici peu. La curiosité aidant, on a pu +discuter du projet avec d'autres personnes et affiner les attentes de chacun +pour finalement arriver à quelque chose d'assez sympathique.</p> +<p>J'ai aussi pu me rendre compte que pas mal de monde utilise <a class="reference external" href="http://pelican.notmyidea.org">pelican</a>, le bout de code que j'ai codé pour générer ce +blog, et avoir des retours utiles ! Probablement des réflexions à venir +sur comment éviter qu'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 contributeurs.</p> +<p>Bien évidemment, c'était aussi l'occaz de rencontrer des gens qu'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 chouette.</p> +<p>Entres autres faits notoires, JMad a perdu au baby-foot face à Exirel, même +en m'ayant à ses cotés pour le déconcentrer (et je suis un joueur d'un autre +monde - en d'autres termes, je suis nul), David`bgk ne s'est pas levé pour +aller courir le dimanche matin (il avait dit 5 heures!), Les suisses ont essayé +de me convertir à coup d'abricotine, j'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'ils mentent avec leur soit disant +soleil).</p> +<p>Et c'est sans parler de <a class="reference external" href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la brasucade</a> …</p> +<p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une présentation +!)</p> +Bière maison !2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/biere-maison-fr.html<p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si …</p><p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si pire comme on dit !</p> +<p>Cette fois-çi, on s'est penché sur la confection d'une IPA (Indian Pale Ale, une +bière un peu plus amère que celle qu'on à l'habitude de trouver en France).</p> +<p>Elle est plus amère car elle comporte plus de houblon que les autres, et +(dans notre cas en tout cas) parce qu'on fait la première fermentation en +présence de houblon.</p> +<div class="section" id="comment-qu-on-fait-de-la-biere"> +<h2>Comment qu'on fait de la bière ?</h2> +<p>Machine arrière; n'allons pas trop vite: comment est-ce qu'on fait de la bière, +d'abord ?</p> +<p>En fin de compte, les quelques étapes nécessaire à la confection de la bière ne +sont pas bien sorcières; concassage de l'orge maltée, cuisson (libération de +l'amidon dans l'eau), infusion du houblon, refroidissement, première +fermentation, embouteillage et seconde fermentation.</p> +<p>L'idée principale est transformer l'amidon d'orge maltée en sucre, pour le +&quot;donner à manger&quot; à des levures. Vous ajoutez un peu de houblon au milieu pour +donner un petit goût amer et le tour est joué. Enfin presque.</p> +</div> +<div class="section" id="etape-par-etape"> +<h2>Étape par étape</h2> +<p>Première étape: <strong>le concassage</strong>. On avait 6kg d'orge maltée à concasser (plus +exactement 6kg de malt pâle <em>7EDC</em> et 500g de malt cara <em>50EDC</em>).</p> +<img alt="Image de concassage." src="images/concassage.jpg" style="width: 400px;" /> +<p>Attention, pas trop fin dis donc ! On ne veut pas de la poudre, on veut +simplement permettre à l'amidon de se dissoudre dans l'eau. Si on concasse le +malt trop fin, on se retrouve avec un dépôt dégeulasse au fond de toutes les +bouteilles (c'est l'expérience qui parle, notre première bière avait plus goût +de céréale que de bière…)</p> +<p>Contrairement aux fois précédentes où nous avions utilisé la technique du +marteau et du torchon (oui, comme vous pouvez l'imaginer, c'est assez long et +fastidieux), On a utilisé… un moulin à malt ! Qui nous à permis de concasser les +6kg en 30 minutes (heureusement qu'on était trois pour se relayer sur le +moulin, parce que nos petits muscles fatiguaient assez vite; vous pouvez +envisager de faire ça tout seul si vous êtes un tennisman).</p> +<img alt="C'est dur !" src="images/concasse.jpg" style="width: 700px;" /> +<p>La seconde étape, <strong>l'empatage</strong>. Il s'agit de faire chauffer notre orge maltée +à différentes températures. Les fois précédentes, on avait utilisé plusieurs +paliers de température, mais il semble que ça ne soit pas si nécessaire que ça, +selon les informations de l'ami Fred. On à donc tenté de faire chauffer notre +malt directement à 50°C. Une petite erreur sur la route, on à eu peur de la +contamination bactérienne et on à décidé de faire bouillir nos 26L d'eau pour +être sur que les bactéries s'enfuient en courant. Je dis erreur parce que ça +nous à pris pas loin de 3h30, inertie quand tu nous tiens!</p> +<p>On se rends compte de la taille de la marmite un peu là:</p> +<img alt="Une grosse marmite" src="images/marmite.jpg" style="width: 400px;" /> +<p>Une fois l'eau à température (54°C), il faut ajouter le malt et le laisser +durant 30mn à cette température, puis augmenter jusqu'à 65°C durant 1h.</p> +<p>La troisième étape, c'est <strong>le rinçage</strong>, l'idée est de récupérer l'amidon qui +s'est dissout dans l'eau et de mettre de côté l'orge maltée (la partie solide). +Pour ça, il faut faire chauffer de l'eau de rinçage. On a utilisé 10L d'eau de +rinçage qu'on a fait chauffer à 78°C, en comptant sur le fait qu'elle perdra de sa +température (20°C à peu près) en étant utilisée. On a filtré deux fois pour +être sûr de ne rien perdre.</p> +<img alt="Filtrage filtrage..." src="images/filtrage.jpg" style="width: 700px;" /> +<p>L'étape d'après (la quatrième, vous suivez), c'est <strong>le houblonnage</strong>. +On va faire infuser notre &quot;solution aqueuse&quot; (wouah, on dirait de la chimie !) +avec du houblon. Il faut porter l'eau à ébullition et laisser faire durant 1h.</p> +<p>Dernière étape: <strong>le refroidissement</strong>. On dirait que c'est tranquilou comme +ça, mais en fait ça ne l'est pas tant que ça: il faut réussir à passer notre +liquide qui était en ébullition à 54°C en un temps acceptable. Pour ça, on +a utilisé un serpentin confectionné main.</p> +<img alt="Notre refroidisseur fait main par Fred." src="images/refroidisseur.jpg" style="width: 400px;" /> +<p>Ça nous a permis de passer de 100°C à 54°C en… 35 minutes quand même ! (Nous avions essayé les fois précédentes +de gérer ça à coup de baignoire et de glaçons, les temps n'étaient absolument +pas au rendez-vous).</p> +<img alt="Décidement pas." src="images/refroidissement.jpg" style="width: 700px;" /> +<p>Je disais dernière étape, mais il ne faut pas oublier de rajouter les +levures, qui elles vont faire tout le travail et transformer tout ça en… alcool +! Dans notre cas, on ajoute aussi dans la cuve de fermentation du houblon +question de donner l'amertume dont on a envie.</p> +<p>On à mesuré une densité de 1046, ce qui veut dire 6° d'alcool. La cuve est +maintenant en train de buller tranquillement (les levures produisent du gaz qui +est évacué), et ça doit durer 15 jours approximativement.</p> +</div> +<div class="section" id="mise-en-bouteille"> +<h2>Mise en bouteille</h2> +<p>Une fois ces deux semaines passées, il faut mettre en bouteille. Dans notre cas +nous avons récupéré des bouteilles à bouchon mécanique (vous savez, les +bouteilles de limonades) qu'on à bien rincé et nettoyé.</p> +<p>On s'équipe d'un siphon (pensez à prendre un tuyau avec un diamètre assez +important, le notre était petit et c'était assez long) et après avoir ajouté du +sucre dans le mélange (pour réactiver les levures), on remplit les bouteilles +! Il s'agit de la seconde fermentation, celle qui va faire les bulles (la +première fermentation se charge de l'alcool, la seconde des bulles).</p> +<p>Et voilà ! Il ne reste plus qu'à mettre les bouteilles de coté durant deux +semaines de plus et… à déguster le moment venu.</p> +<p>On a donc pu tester notre bière la semaine dernière et, ma foi, elle est pas +mal du tout. Elle ne mousse pas trop et à un goût un peu amer. Malheureusement +pas assez à mon goût, mais ça viendra. En comparaison à nos précédents essais, +c'est plutôt positif: la première était ratée puisque trop de pression et trop +de dépôt (et donc un fort goût de levures) alors que la seconde (on avait tenté +d'ajouter de la lavande) avait un goût de lavande amère, pour ne pas dire de +savon.</p> +<p>Cette dernière bière a un goût de… de bière ! Il nous reste encore à 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 !</p> +</div> +Motivation, bénévolat et participation2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/motivation-benevolat-et-participation-fr.html<p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux …</p><p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux luttes +contre l'oligarchie et les profits d'une minorité aux dépends du reste du monde, +et à encore bien d'autres choses.</p> +<p>Pendant un bout de temps, j'ai parlé d'entraide, de collaboration, j'ai essayé +de sensibiliser autour de la question environnementale et aux alternatives +sociales. C'est d'ailleurs de cette manière que je me suis moi-même le plus +sensibilisé à ces questions qui me préoccupaient.</p> +<p>J'ai tenté de le faire sans tomber dans la critique des choix des uns et des +autres. Je respecte profondément la diversité des points de vues <strong>mais</strong> je +souhaite également que ces choix soient faits en connaissance de cause.</p> +<p>Une des choses difficile à supporter (pour les autres) quand on fait de la +sensibilisation, c'est le syndrôme du jeune con, du donneur de leçons.</p> +<p>On dirait qu'on parle de sauver le monde. &quot;Nous qui avons tout compris, on peut +vous aider à aller dans la <em>bonne direction</em>&quot;, mais c'est en oubliant que +la bonne direction pour l'un ne l'est pas nécessairement pour les autres…</p> +<div class="section" id="just-do-it"> +<h2>Just do it !</h2> +<p>Se battre <em>contre quelque chose</em> permet de facilement trouver des personnes qui +partagent les même craintes alors que se battre <em>pour</em> permet d'engager des +discussions avec des personnes qui partagent une vision commune.</p> +<p>Proposer des choses, trouver des personnes qui partagent des points de vue est +un bon point de départ pour le changer ce monde, a notre échelle. Le récent +documentaire <a class="reference external" href="http://justdoitfilm.com/">&quot;Just do it&quot;</a> porte un message assez +clair: toute initiative compte, aussi petite et insignifiante qu'elle puisse +sembler.</p> +<p>Des initiatives locales, il y en a, plein. Et si ce que nous avons dans notre +quotidien nous pèse (aller au supermarché, subir la sur-médiatisation +télévisuelle, ne pas parler à nos voisins de quartier…), qu'est-ce qui nous +empêche d'y substituer des modèles alternatifs ?</p> +<p>Monter une <a class="reference external" href="https://fr.wikipedia.org/wiki/AMAP">AMAP</a> (Association Pour le Maintien d'une Agriculture Paysanne) +n'est pas aussi compliqué qu'il y parait. Pour avoir fait l'expérience par deux +fois, j'ai été très agréablement surpris par la facilité des choses, pour peu +qu'on ne cherche pas à s'encombrer de l'inutile (tiens encore une fois on +parle de frugalité !): il est facile de vouloir faire trop, de recréer les +processus complexes auxquels nous sommes souvent confrontés.</p> +<p>Vous souhaitez partager des connaissances (cuisine, musique, danse, bricolage, +écriture), il suffit de le faire. En fait, pour la plupart des choses, il +suffit de tenter l'expérience, c'est rarement décevant. Surtout quand on +s'embarque dans des choses saugrenues ou personnellement inédites.</p> +<p>Pour moi, la frugalité, la simplicité volontaire, la sobriété heureuse, appelez-ça +comme vous le voulez, représente ce qui me convient et me permet d'être en +ligne avec les idées que je défends.</p> +</div> +<div class="section" id="faciliter-la-participation"> +<h2>Faciliter la participation</h2> +<p>Beaucoup de personnes sont à même de participer à des projets locaux, pour peu +qu'ils soient au courant mais pour autant peu franchissent le pas, et encore +moins persévèrent, pourquoi ?</p> +<p>Et pourquoi pas laisser les présents, les motivés, s'investir par eux-mêmes ? +Avoir des responsabilités est souvent pour ma part un frein à la réalisation +d'un projet lorsque je suis bénévole.</p> +<p>Décider à l'avance des choses qui semblent utiles et/ou importantes est parfois +indispensable, mais ne pas trop en faire permet de laisser libre court +à l'imagination (souvent débordante) des participants.</p> +<p>J'aime beaucoup l'idée de faire des camps de quelques jours, où rien n'est +réellement décidé à l'avance, mise à part un thème et quelques temps de +plénière ou il est possible à chacun de s'exprimer sur les projets qui +pourraient êtres réalisés.</p> +<p>Pas besoin de tant de formalisation: mettez une équipe de bidouilleurs ensemble +durant une semaine sans objectif commun à priori et sans distractions, vous +verrez bien ce qui en ressortira !</p> +</div> +Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique-fr.html<p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable …</p><p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable à lire que sa version papier, il reste quand même quelques problèmes, la plupart liés au format de distribution de l’œuvre.</p> +<p>J'avoue ne pas trop savoir quoi penser de tout ça. D'un coté le livre électronique permet de franchir les frontières plus facilement, et semble avoir un tas d'avantage (notamment le fait que se trimbaler avec l'ensemble de sa collection de bouquins est désormais possible).</p> +<p>A mon avis, ce qui pose vraiment problème, ce sont les formats sous lesquels ces livres sont mis à disposition, non pas les livres eux même. Encore une question de DRMs donc…</p> +<p>Encore une problématique liée au copyright et au fait que le copie privée pose des problèmes à l'industrie en place. Ça renvoie à des questions plus profondes, et principalement à la mise en perspective du producteur de contenu et du consomateur de ce même contenu. Exactement ce qu'on essaye de résoudre dans le milieu agricole par le biais des AMAPs.</p> +<p>Sauf qu'ici, on est face au simple problème de la dématérialisation. Est-ce qu'une responsabilisation des consommateurs ne pourrait pas résoudre ce problème de publication ?</p> +<p>Recemment, j'ai récupéré une version piratée d'un livre technique, simplement parce que je ne trouvais pas une version de ce livre en numérique qui me permette de faire une copie privée de celui ci. Un Epub, par exemple. J'ai fait en me disant que c'était un acte militant. Sauf que non, ce n'est pas une solution soutenable, et j'en viens maintenant presque à le regretter. On en discutait rapidement avec <a class="reference external" href="http://ziade.org">Tarek</a> il y à quelques jours et il pointait du doigt que ceux qui en patissent sont les auteurs des livres, non pas les éditeurs (qu'il ne faut pas non plus diaboliser selon moi, ils cherchent à trouver des manières de garder leur coeur de métier).</p> +<p>Or, avoir des auteurs, des personnes qui sont prêtes à partager leur savoir à de larges audiences me semble primordial pour que la répartition du savoir continue à se répendre. Certes, le blogging permet cela dans une faible mesure, mais de manière bien moins construite, et surtout, est fait de manière bénévole (à moins que certains bloggeurs aient trouvé des moyens de rémunération dont j'ignore l'existance ?), donc il est plus difficile pour les auteurs de se dégager du temps pour travailler sur de gros ouvrages (ceci est bien évidemment une généralisation).</p> +<p>Quelles sont nos solutions, donc ? Peut être se tourner vers des solution de publication alternatives, couplées à une résponsabilisation des lecteurs. Je ne pense pas necessairement aux plateformes alternatives comme <a class="reference external" href="http://framabook.org">framabook</a>, parce que je me demande toujours si cela est une solution viable pour les auteurs, du moins dans les premières années, mais au moins des éditeurs qui ne font pas le choix du grand verrou numérique.</p> +<p>On demande pas grand chose, pourtant… Peut être même que de telles initiatives existent déjà ?</p> +<p>Et vous, vous les achetez ou vos livres ?</p> +2012, first months2012-01-21T00:00:00+01:002012-01-21T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-21:/2012-first-months.html<p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services …</p><p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services able to scale out of +the box.</p> +<p>Our most visible and known project, so far, is Firefox Sync, which allows to synchronize +browsing data (tabs, passwords, history, etc.) among different instances of +Firefox. We are also building other things, such as a way to get metrics +easily, a web service based queue, etc. Our primary consumers are +people inside Mozilla, and we want to help them having a simple way to create, +deploy and scale their apps. The project is named &quot;sagrada&quot;, and you +can find some more information about it on <a class="reference external" href="https://wiki.mozilla.org/Services/Sagrada">our public wiki</a></p> +<p>All of what we do, we do it in the open. So you can have a look at <a class="reference external" href="http://github.com/mozilla-services">the +different pieces of code we wrote</a> +and use them / contribute if you want to.</p> +<p>I will not dig in to all the details of what I have been doing, but so far, this have been +a pretty amazing experience. Part of this is explainable by the fact that the +team is made of amazing folks, all with a strong experience in different +topics, so I'm learning things™.</p> +<p>I am currently practicing a bit my C++ to do crypto related things (I may or +may not talk about this later on this web-logs) and it's great (well, it +remembers me why I love python for so many things, but it makes me think closer +to the metal ;)). I love this job.</p> +<p>Second, I moved to Paris. Yes, Paris. Some of you who know me a bit may find +it unexpected, and that's the case. I'm usually not a big fan of big cities and +am a fairly strong defender of having and creating activities in the country side, +to face the rural exodus problem, into other thingS.</p> +<p>I didn't changed my opinion about that. However, I don't want to <em>start</em> by +working remote, especially when working with a remote team. Having offices kind +of help me to have a differentiation between my working place and home, which I +find to be important.</p> +<p>And, to be honest, I don't like Paris for unknown reasons: I +haven't been there, so it's a big over-generalisation to say that it's not +good for me. The reality is that I have no idea of what Paris is, and if I'll +like it or not.</p> +<p>I found a really nice house (yeah, a house!) in Paris and am sharing it with 3 +other persons. We have room, all like good food and… +they are not geeks, which is a big win for me: work is work and home is home.</p> +<p>So far, Paris had been really nice. A lot of things are going on in here, and I +kind of like the way it is possible to find alternative related things in here. +I found a <a class="reference external" href="http://en.wikipedia.org/wiki/Community-supported_agriculture">CSA</a>, +some people interested by agriculture related problems and I like where things +seems to be going.</p> +<p>So, new job, new house, new city, things are going forward and that's great.</p> +<p>Oh, and I will try to post some more technical articles soon, +I'm missing them :)</p> +Using JPype to bridge python and Java2011-11-06T00:00:00+01:002011-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-11-06:/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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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, 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 VM level. This means you need to start a VM +from your python script, but it does the job and stay fully compatible with +Cpython and its C extensions.</p> +<div class="section" id="first-steps-with-jpype"> +<h2>First steps with JPype</h2> +<p>Once JPype installed (you'll have to hack a bit some files to integrate +seamlessly with your system) you can access java classes by doing something +like that:</p> +<div class="highlight"><pre><span></span><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> +</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 them.</p> +</div> +<div class="section" id="interfacing-with-boilerpipe"> +<h2>Interfacing with Boilerpipe</h2> +<p>To install boilerpipe, you just have to run an ant script:</p> +<pre class="literal-block"> +$ cd boilerpipe +$ ant +</pre> +<p>Here is a simple example of how to use boilerpipe in Java, from their sources</p> +<div class="highlight"><pre><span></span><span class="kn">package</span> <span class="nn">de.l3s.boilerpipe.demo</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">java.net.URL</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">de.l3s.boilerpipe.extractors.ArticleExtractor</span><span class="o">;</span> + +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Oneliner</span> <span class="o">{</span> + <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="kd">final</span> <span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="kd">final</span> <span class="n">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="n">URL</span><span class="o">(</span><span class="s">&quot;http://notmyidea.org&quot;</span><span class="o">);</span> + <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ArticleExtractor</span><span class="o">.</span><span class="na">INSTANCE</span><span class="o">.</span><span class="na">getText</span><span class="o">(</span><span class="n">url</span><span class="o">));</span> + <span class="o">}</span> +<span class="o">}</span> +</pre></div> +<p>To run it:</p> +<div class="highlight"><pre><span></span>$ javac -cp dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar src/demo/de/l3s/boilerpipe/demo/Oneliner.java +$ java -cp src/demo:dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar de.l3s.boilerpipe.demo.Oneliner +</pre></div> +<p>Yes, this is kind of ugly, sorry for your eyes. +Let's try something similar, but from python</p> +<div class="highlight"><pre><span></span><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="k">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> +</pre></div> +<p>And you get what you want.</p> +<p>I must say I didn'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, nice!</p> +</div> +How are you handling your shared expenses?2011-10-15T00:00:00+02:002011-10-15T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.html<p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 …</p><p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 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 come.</p> +<p>I said yes and gave it some more thoughts: We probably aren'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, boooh!).</p> +<p>I then discussed with a friend of mine, who was excited about it and wanted to learn +python. Great! That'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 class="reference external" href="http://www.sneakernet.fr/">Arnaud</a> and Quentin!)</p> +<p>Since that, the project now support multiple languages and provides a REST API +(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's it (this was inspired by +doodle)!</p> +<img alt="Capture d'écran du site." src="images/ihatemoney.png" /> +<p>You can try the project at <a class="reference external" href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a> for now, and the +code lives at <a class="reference external" href="https://github.com/spiral-project/ihatemoney/">https://github.com/spiral-project/ihatemoney/</a>.</p> +<div class="section" id="features"> +<h2>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 once.</p> +<p>No, I don'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 way.</p> +<div class="section" id="no-user-registration"> +<h3>No user registration</h3> +<p>You don'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 you).</p> +</div> +<div class="section" id="keeping-things-simple"> +<h3>Keeping things simple</h3> +<p>&quot;Keep It Simple, Stupid&quot; 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're back from the +farmer's market on raw paper.</p> +</div> +<div class="section" id="no-categories"> +<h3>No categories</h3> +<p>Some people like to organise their stuff into different &quot;categories&quot;: +leisure, work, eating, etc. That's not something I want (at least to begin +with).</p> +<p>I want things to be simple. Got that? Great. Just add your bills!</p> +</div> +<div class="section" id="balance"> +<h3>Balance</h3> +<p>One of the most useful thing is to know what's your &quot;balance&quot; compared to +others. In other words, if you're negative, you owe money, if you'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 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 balance.</p> +</div> +<div class="section" id="api"> +<h3>API</h3> +<p>All of what's possible to do with the standard web interface is also available +through a REST API. I developed a simple REST toolkit for flask for this (and +I should release it!).</p> +</div> +</div> +<div class="section" id="interested"> +<h2>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't hesitate +a second! The project lives at <a class="reference external" href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p> +</div> +La simplicité volontaire contre le mythe de l'abondance2011-10-14T00:00:00+02:002011-10-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-14:/la-simplicite-volontaire-contre-le-mythe-de-labondance-fr.html<p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car …</blockquote><p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car il finira par nous poignarder, au moment ou nous pensions +justement pouvoir le vaincre… Entendons-nous bien, il ne s'agit pas +d'apprendre à &quot;positiver&quot; sous prétexte que l'on pourrait &quot;moraliser&quot; ou +repeindre en vert le capitalisme, il s'agit, bien au contraire, d'être aussi +intraitables lorsque nous créons cet autre monde, que lorsque nous étions +ces militants purs mais un peu durs à jouir, il s'agit d'être aussi +indomptables mais sans oublier que le capitalisme ne pourra être arrété que +par du non-capitaliste… c'est-à-dire en multipliant les expérimentations +sociales, en acceptant de faire au maximum sécession, en inventant +(réinventant?) une gauche buissonière et maquisarde, en faisant, au +quotidien, la part belle à la dérive, à des modes de comportement +expérimentaux. 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.</blockquote> +Using dbpedia to get languages influences2011-08-16T00:00:00+02:002011-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.html<p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 …</p><p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 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 technologies.</p> +<p>Well, you may have guessed it, the project in question in dbpedia, and exposes +information in the form of RDF triples, which are way more easy to work with +than simple HTML.</p> +<p>For instance, let's take the page about python: +<a class="reference external" 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 &quot;Influenced&quot; and &quot;InfluencedBy&quot;, 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 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 &quot;( +programming language)&quot;, which is the case for python.</p> +<p>So I've built <a class="reference external" 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 graphviz.</p> +<p>After a nice:</p> +<pre class="literal-block"> +$ python get_influences.py python dot | dot -Tpng &gt; influences.png +</pre> +<p>The result is the following graph (<a class="reference external" href="http://files.lolnet.org/alexis/influences.png">see it directly here</a>)</p> +<img alt="Graph des influances des langages les uns sur les autres." src="http://files.lolnet.org/alexis/influences.png" style="width: 800px;" /> +<p>While reading this diagram, keep in mind that it is a) not listing all the +languages and b) keeping a python 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 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 readable.</p> +<p>You can find the script <a class="reference external" href="https://github.com/ametaireau/experiments">on my github account</a>. Feel free to adapt it for +whatever you want if you feel hackish.</p> +Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html<p>Back in October, I released <a class="reference external" 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 class="reference external" 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 github.</p> +<p>And people started contributing. I wasn'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 requests.</p> +<p><strong>Which is clearly 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 fun.</p> +<p>Thank you, guys, you're why I like open source so much.</p> +Introducing Cornice2011-07-12T00:00:00+02:002011-07-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-12:/introducing-cornice.html<p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of …</p><p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of any kind.</p> +<p>The goal is to simplify your work, but we don't want to reinvent the wheel, so +it is easily pluggable with validations frameworks, such as <a class="reference external" href="http://docs.pylonsproject.org/projects/colander/en/latest/">Colander</a>.</p> +<div class="section" id="handling-errors-and-validation"> +<h2>Handling errors and validation</h2> +<p>Here is how it works:</p> +<div class="highlight"><pre><span></span><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.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> +</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 future)</p> +<p>As you might have seen, <cite>request.errors.add</cite> 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 &quot;body&quot;, +&quot;query&quot;, &quot;headers&quot; or &quot;path&quot;. <strong>name</strong> is the name of the variable causing +problem, if any, and <strong>description</strong> contains a more detailed message.</p> +<p>Let's run this simple service and send some queries to it:</p> +<pre class="literal-block"> +$ curl -v http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: */* +&gt; +* HTTP 1.0, assume close after body +&lt; HTTP/1.0 400 Bad Request +&lt; Content-Type: application/json; charset=UTF-8 +[{&quot;location&quot;: &quot;query&quot;, &quot;name&quot;: &quot;awesome&quot;, &quot;description&quot;: &quot;You lack awesomeness!&quot;} +</pre> +<p>I've removed the extra clutter from the curl's output, but you got the general idea.</p> +<p>The content returned is in JSON, and I know exactly what I have to do: add an +&quot;awesome&quot; parameter in my query. Let's do it again:</p> +<pre class="literal-block"> +$ curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;yay!&quot;} +</pre> +<p>Validators can also convert parts of the request and store the converted value +in <cite>request.validated</cite>. It is a standard dict automatically attached to the +requests.</p> +<p>For instance, in our validator, we can chose to validate the parameter passed +and use it in the body of the webservice:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>The output would look like this:</p> +<pre class="literal-block"> +curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;awesome yeah&quot;} +</pre> +</div> +<div class="section" id="dealing-with-accept-headers"> +<h2>Dealing with &quot;Accept&quot; headers</h2> +<p>The HTTP spec defines a <strong>Accept</strong> header the client can send so the response +is encoded the right way. A resource, available at an URL, can be available in +different formats. This is especially true for web services.</p> +<p>Cornice can help you dealing with this. The services you define can tell which +<cite>Content-Type</cite> values they can deal with and this will be checked against the +<strong>Accept</strong> headers sent by the client.</p> +<p>Let's refine a bit our previous example, by specifying which content-types are +supported, using the <cite>accept</cite> parameter:</p> +<div class="highlight"><pre><span></span><span class="nd">@service.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> +</pre></div> +<p>Now, if you specifically ask for XML, Cornice will throw a 406 with the list of +accepted <cite>Content-Type</cite> values:</p> +<pre class="literal-block"> +$ curl -vH &quot;Accept: application/xml&quot; http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: application/xml +&gt; +&lt; HTTP/1.0 406 Not Acceptable +&lt; Content-Type: application/json; charset=UTF-8 +&lt; Content-Length: 33 +&lt; +[&quot;application/json&quot;, &quot;text/json&quot;] +</pre> +</div> +<div class="section" id="building-your-documentation-automatically"> +<h2>Building your documentation 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 API in your docs.</p> +<div class="highlight"><pre><span></span><span class="p">..</span> <span class="ow">services</span><span class="p">::</span> + <span class="nc">:package:</span> <span class="nf">coolapp</span> + <span class="nc">:service:</span> <span class="nf">quote</span> +</pre></div> +<p>Here is an example of what a generated page looks like: <a class="reference external" href="http://packages.python.org/cornice/exampledoc.html">http://packages.python.org/cornice/exampledoc.html</a></p> +</div> +<div class="section" id="yay-how-can-i-get-it"> +<h2>Yay! How can I get it?</h2> +<p>We just cut a 0.4 release, so it's available at <a class="reference external" href="http://pypi.python.org/pypi/cornice">http://pypi.python.org/pypi/cornice</a> +You can install it easily using <cite>pip</cite>, for instance:</p> +<pre class="literal-block"> +$ pip install cornice +</pre> +<p>You can also have a look at the documentation at +<a class="reference external" href="http://packages.python.org/cornice/">http://packages.python.org/cornice/</a></p> +</div> +<div class="section" id="what-s-next"> +<h2>What's 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 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 class="reference external" href="https://github.com/mozilla-services/cornice">go grab them on github</a> +, commit and send us a pull request!</p> +</div> +Un coup de main pour mon mémoire!2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire-fr.html<p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de main.</p> +<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui connaissent +last.fm, je …</p><p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de 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'avis des personnes qui +ont des profils similaires au votre.</p> +<p>Le projet est loin d'ê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 &quot;tournée +générale&quot;).</p> +<p>J'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'enverra des +information sur les sites que vous visitez (si vous avez l'habitude d'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'un simple clic si vous souhaitez garder votre vie privée privée ;-)</p> +<p>Le site est par là: <a class="reference external" 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'est 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 correctement.</p> +<p>Merci pour votre aide !</p> +Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler-fr.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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un …</p><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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un brin!).</p> +<p>Bosser en extérieur est un réel plaisir et faire quelque chose de manuel +également. Je n'ai pas pour habitude de bricoler autre chose que du logiciel et +c'est vraiment quelque chose que j'apprécie.</p> +<p>J'avoue, je mens un peu quand je dis que j'étais complètement déconnecté: +j'ai vérifié mes mails assez régulièrement en utilisant mon téléphone +(merci Arnaud pour le prêt du gadget!) et j'ai limité ma présence web au strict +minimum. Je veux dire par là pas de twitter, pas d'IRC et autres mailing-lists.</p> +<p>Quand je dis hors-ligne, je ne dis pas que je n'ai pas travaillé sur mon +ordinateur. J'ai à fournir beaucoup plus de travail que ce que je ne pensait en +premier lieu pour la rédaction de mon mémoire et j'ai passé quelques heures par +ci par là à lire des articles et livres sur le sujet ainsi que rédigé une bonne +partie de mon mémoire durant ces 10 jours. Résultat ? Les heures que j'ai passées à travailler ont +été étonnement plus productives que celles que j'ai l'habitude de passer derrière +un écran. Je ne parles pas uniquement du fait de procrastiner; évidemment c'est +une des causes principales de ma perte de productivité, mais je pense également +au fait de laisser le cerveau reposer, au moins en ce qui concerne la partie +informatique. Bricoler demande de la concentration et de la réflexion mais +permet également de laisser son esprit vagabonder. J'ai pu donc avancer mes +sur certaines parties de mon mémoire alors que j'étais en train de poser le +bardage sur la garage par exemple.</p> +<p>Passer du temps sur autre chose (qui demandait également de la concentration +par ailleurs) m'a permis d'être réellement plus efficace lors de mes phases de +rédaction et de lecture.</p> +<p>Je me demande depuis quelques temps quel sera mon futur travail et quelle forme +il prendra. Éééh oui, la fin des études arrive pour la fin de l'année, c'est +pas une blague. Et je me pose sérieusement la question du travail aux 3/4 +temps. La raison principale étant que je ne souhaites pas passer la majeure +partie de mon temps à travailler derrière un écran et que la formation que j'ai +m'y rattache beaucoup. Ne me comprenez pas de travers: j'aime ce que je fais; +mais j'aime aussi ce que je fais à coté de l'informatique: associatif, projets +alternatifs, permaculture et autres.</p> +<p>Viens s'ajouter à ça le fait d'avoir une qualité de vie qui me semble pouvoir +passer par le fait de travailler moins (&quot;il est marant ce gamin, il à pas encore commencé +à travailler qu'il veut bosser moins, regarde moi cette feignasse!&quot;) et +travailler plus efficacement. Bien sur, on n'est jamais 100% productif et c'est +d'autant plus vrai pour moi, alors si gagner en productivité peut passer par +travailler moins, pourquoi pas s'y essayer !</p> +<p>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 ?</p> +Analyse users' browsing context to build up a web recommender2011-04-01T00:00:00+02:002011-04-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.html<p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full …</p><p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full time on my dissertation topic.</p> +<p>When I learned we'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's the good time to learn.</p> +<p>Since a long time, I'm being impressed by the <a class="reference external" href="http://last.fm">last.fm</a> +recommender system. They're <em>scrobbling</em> the music I listen to since something +like 5 years now and the recommendations they're doing are really nice and +accurate (I discovered <strong>a lot</strong> of great artists listening to the +&quot;neighbour radio&quot;.) (by the way, <a class="reference external" href="http://lastfm.com/user/akounet/">here is</a> +my lastfm account)</p> +<p>So I decided to work on recommender systems, to better understand what is it +about.</p> +<p>Recommender systems are usually used to increase the sales of products +(like Amazon.com does) which is not really what I'm looking for (The one who +know me a bit know I'm kind of sick about all this consumerism going on).</p> +<p>Actually, the most simple thing I thought of was the web: I'm browsing it quite +every day and each time new content appears. I've stopped to follow <a class="reference external" 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 class="reference external" href="http://twitter.com/ametaireau/">on +twitter</a>.</p> +<p>Too much information kills the 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're probably not interested by the same topics at different +times of the day, or depending on the computer you're using. We can also +probably make good use of the way you browse to create groups into the content +you're browsing (or even use the great firefox4 tab group feature).</p> +<p>There is a large part of concerns to have about user's privacy as well.</p> +<p>Here is my proposal (copy/pasted from the one I had to do for my master)</p> +<div class="section" id="introduction-and-rationale"> +<h2>Introduction and 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 articles.</p> +<p>A lot of people share the same interest to various topics, and the quantity of +information is such than it'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 perspective.</p> +<p>Machine learning is a branch of Artificial Intelligence (AI) 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 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'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 else.</p> +<p>Page contents are also interesting to analyse, because that'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 etc.)</p> +<p>The goal of this dissertation is to create a recommender system for web links, +including this context 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 system.</p> +</div> +<div class="section" id="background-review"> +<h2>Background 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 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's +browsers.</p> +<div class="section" id="data-preparation-and-extraction"> +<h3>Data preparation and 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 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, 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, 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 HTML pages so there is a need of tools to recognise 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 &quot;liked&quot; a resource, and +determine a mark for it, which can be used by information filtering a later +step (T. Segaran, 2007).</p> +<p>At this stage, structuring the data is required. Storing this kind of +information in RDBMS 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 querying.</p> +</div> +<div class="section" id="information-filtering"> +<h3>Information filtering</h3> +<p>To filter the information, three techniques can be used (Balabanovic et +Al, 1997):</p> +<ul class="simple"> +<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's about +establishing a profile for the user and compare new items against 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 to.</li> +<li>the hybrid approach, which appeared recently combine both of the previous +approaches, giving recommendations when items score high regarding user's +profile, or if a similar user already liked 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, 2007).</p> +<p>References:</p> +<ul class="simple"> +<li>Balabanović, M., &amp; Shoham, Y. (1997). Fab: content-based, collaborative +recommendation. Communications of the ACM, 40(3), 66–72. ACM. +Retrieved March 1, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp">http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp</a>;.</li> +<li>Berners-Lee, T., Hendler, J., &amp; Lassila, O. (2001). +The semantic web: Scientific american. Scientific American, 284(5), 34–43. +Retrieved November 21, 2010, from <a class="reference external" href="http://www.citeulike.org/group/222/article/1176986">http://www.citeulike.org/group/222/article/1176986</a>.</li> +<li>Castellano, G., Fanelli, A., &amp; Torsello, M. (2007). +LODAP: a LOg DAta Preprocessor for mining Web browsing patterns. Proceedings of the 6th Conference on 6th WSEAS Int. Conf. on Artificial Intelligence, Knowledge Engineering and Data Bases-Volume 6 (p. 12–17). World Scientific and Engineering Academy and Society (WSEAS). Retrieved March 8, 2011, from <a class="reference external" 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., &amp; Nejdl, W. (2010). Boilerplate detection using shallow text features. Proceedings of the third ACM international conference on Web search and data mining (p. 441–450). ACM. Retrieved March 8, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=1718542">http://portal.acm.org/citation.cfm?id=1718542</a>.</li> +<li>Myatt, G. J. (2007). Making Sense of Data: A Practical Guide to Exploratory +Data Analysis and Data Mining.</li> +<li>Segaran, T. (2007). Collective Intelligence.</li> +</ul> +</div> +</div> +<div class="section" id="privacy"> +<h2>Privacy</h2> +<p>The first thing that's come to people minds when it comes to process their +browsing data is privacy. People don't want to be stalked. That's perfectly +right, and I don't either.</p> +<p>But such a system don't have to deal with people identities. It's completely +possible to process completely anonymous data, and that's probably what I'm +gonna 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 !</p> +</div> +<div class="section" id="what-s-the-plan"> +<h2>What's the plan ?</h2> +<p>There is a lot of different things to explore, especially because I'm +a complete novice in that field.</p> +<ul class="simple"> +<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 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 db?</li> +<li>Process the data using well known recommendation algorithms. Compare the +results and criticize their value.</li> +</ul> +<p>There is plenty of stuff I want to try during this experimentation:</p> +<ul class="simple"> +<li>I want to try using Geshi to visualize the connexion between the links, +and the contexts</li> +<li>Try using graph databases such as Neo4j</li> +<li>Having a deeper look at tools such as scikit.learn (a machine learning +toolkit in python)</li> +<li>Analyse web pages in order to categorize them. Processing their +contents as well, to do some keyword based classification will be done.</li> +</ul> +<p>Lot of work on its way, yay !</p> +</div> +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:00Alexis Métaireautag: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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time …</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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time in a console while +developing, it's possible to work via ssh, from everywhere.</p> +<p>The only problem is the synchronisation of the source code, config files etc. +from my machine to the server.</p> +<p>Unison provides an interesting way to synchronise two folders, even over +a network. So let's do it !</p> +<div class="section" id="creating-the-jail"> +<h2>Creating the jail</h2> +<p>In case you don't use FreeBSD, you can skip this section.</p> +<div class="highlight"><pre><span></span><span class="c1"># I have a flavour jail named default</span> +$ ezjail-admin -f default workspace.notmyidea.org <span class="m">172</span>.19.1.6 +$ ezjail-admin start workspace.notmyidea.org +</pre></div> +<p>In my case, because the &quot;default&quot; flavour contains already a lot of interesting +things, my jail come already setup with ssh, bash and vim for instance, but +maybe you'll need it in your 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 <cite>/etc/pf.conf</cite>:</p> +<pre class="literal-block"> +workspace_jail=&quot;172.19.1.6&quot; +rdr on $ext_if proto tcp from any to $ext_ip port 20006 -&gt; $workspace_jail port 22 +</pre> +<p>Reload packet filter rules</p> +<div class="highlight"><pre><span></span>$ /etc/rc.d/pf reload +</pre></div> +</div> +<div class="section" id="working-with-unison"> +<h2>Working with unison</h2> +<p>Now that we'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 it</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> +$ make -C /usr/ports/net/unison-nox11 config-recursive +$ make -C /usr/ports/net/unison-nox11 package-recursive +</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 2.32.52.</p> +<p>Check that unison is installed and reachable via ssh from your machine</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> unison -version +unison version <span class="m">2</span>.27.157 +$ unison -version +unison version <span class="m">2</span>.27.57 +</pre></div> +</div> +<div class="section" id="let-sync-our-folders"> +<h2>Let sync our folders</h2> +<p>The first thing I want to sync is my vim configuration. Well, it's already <a class="reference external" href="http://github.com/ametaireau/dotfiles/">in +a git repository</a> but let's try to use +unison for it right now.</p> +<p>I have two machines then: <cite>workspace</cite>, the jail, and <cite>ecureuil</cite> my laptop.</p> +<div class="highlight"><pre><span></span>unison .vim ssh://notmyidea.org:20006/.vim +unison .vimrc ssh://notmyidea.org:20006/.vimrc +</pre></div> +<p>It is also possible to put all the informations in a config file, and then to +only run <cite>unison</cite>. (fire up <cite>vim ~/.unison/default.prf</cite>.</p> +<p>Here is my config:</p> +<pre class="literal-block"> +root = /home/alexis +root = ssh://notmyidea.org:20006 + +path = .vimrc +path = dotfiles +path = dev + +follow = Name * +</pre> +<p>My vimrc is in fact a symbolic link on my laptop, but I don't want to specify +each of the links to unison. That's why the <cite>follow = Name *</cite> is 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 2GB in 20mn ;)</p> +</div> +<div class="section" id="run-the-script-frequently"> +<h2>Run the script 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've wrote a tiny script to get some +feedback from the sync:</p> +<div class="highlight"><pre><span></span><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="bp">True</span> + <span class="n">error</span> <span class="o">=</span> <span class="bp">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; {0}&#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="bp">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 {0}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 {2} &quot;{0}&quot; &quot;{1}&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> +</pre></div> +<p>This is probably perfectible, but that does the job.</p> +<p>Last step is to tell you machine to run that frequently. That's what <cite>crontab</cite> +is made for, so let's <cite>crontab -e</cite>:</p> +<pre class="literal-block"> +$ * */3 * * * . ~/.Xdbus; /usr/bin/python /home/alexis/dev/python/unison-syncer/sync.py +</pre> +<p>The <cite>~/.Xdbus</cite> allows cron to communicate with your X11 session. Here is its +content.</p> +<div class="highlight"><pre><span></span><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 -u <span class="nv">$LOGNAME</span> -n 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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$nautilus_pid</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">exit</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="k">$(</span>tr <span class="s1">&#39;\0&#39;</span> <span class="s1">&#39;\n&#39;</span> &lt; /proc/<span class="nv">$nautilus_pid</span>/environ <span class="p">|</span> grep <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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$DBUS_SESSION_BUS_ADDRESS</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">echo</span> <span class="s2">&quot;Failed to find bus address&quot;</span> &gt;<span class="p">&amp;</span><span class="m">2</span> +<span class="nb">exit</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> DBUS_SESSION_BUS_ADDRESS +</pre></div> +<p>And it comes from <a class="reference external" 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 developments.</p> +</div> +Wrap up of the distutils2 paris' sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00Alexis Métaireautag: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've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what …</p><p>Finally, thanks to a bunch of people that helped me to pay my train and bus +tickets, I've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what we've been working on:</p> +<ul class="simple"> +<li>the <cite>datafiles</cite>, a way to specify and to handle the installation of files which +are not python-related (pictures, manpages and so on).</li> +<li><cite>mkgcfg</cite>, a tool to help you to create a setup.cfg in minutes (and with funny +examples)</li> +<li>converters from setup.py scripts. We do now have a piece of code which +reads your current <cite>setup.py</cite> file and fill in some fields in the <cite>setup.cfg</cite> +for you.</li> +<li>a compatibility layer for distutils1, so it can read the <cite>setup.cfg</cite> you will +wrote for distutils2 :-)</li> +<li>the uninstaller, so it's now possible to uninstall what have been installed +by distutils2 (see PEP 376)</li> +<li>the installer, and the setuptools compatibility layer, which will allow you +to rely on setuptools' based distributions (and there are plenty of them!)</li> +<li>The compilers, so they are more flexible than they were. Since that'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 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 use.</p> +<p>I'm really pleased to see how newcomers went trough the code, and started +hacking so fast. I must say it wasn't the case when we started to work on +distutils1 so that's a very good point: people now can hack the code quicker +than they could 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 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 +bears^Wbeers.</p> +<p>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 :-)</p> +PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00Alexis Métaireautag: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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +drawbacks.</p> +<p>Basically, if you want to use informations coming from the simple API, you will +have to parse web pages manually, to extract informations using some black +vodoo magic. Badly, magic have a price, and it's sometimes impossible to get +exactly the informations you want to get from this index. That's the technique +currently being used by distutils2, setuptools and pip.</p> +<p>On the other side, while XML/RPC is working fine, it'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's important to point out that, even if +PyPI have a mirroring infrastructure, it's only for the so-called <em>simple</em> API, +and not for the XML/RPC.</p> +<div class="section" id="couchdb"> +<h2>CouchDB</h2> +<p>Here comes CouchDB. CouchDB is a document oriented database, that +knows how to speak REST and JSON. It's easy to use, and provides out of the box +a replication mechanism.</p> +</div> +<div class="section" id="so-what"> +<h2>So, what ?</h2> +<p>Hmm, I'm sure you got it. I'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 HTTP request on the CouchDB server. You can also access the informations +from the index directly using a REST API, speaking json. Handy.</p> +<p>So PyPIonCouch is using the PyPI XML/RPC API to get data from PyPI, and +generate records in the CouchDB instance.</p> +<p>The final goal is to avoid to rely on this &quot;simple&quot; API, and rely on a REST +insterface instead. I have set up a couchdb server on my server, which is +available at <a class="reference external" 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've done the first import from PyPI yesterday and all +went fine: it's possible to access the metadata of all PyPI projects via a REST +interface. Next step is to write a client for this REST interface in +distutils2.</p> +</div> +<div class="section" id="example"> +<h2>Example</h2> +<p>For now, you can use pypioncouch via the command line, or via the python API.</p> +<div class="section" id="using-the-command-line"> +<h3>Using the command line</h3> +<p>You can do something like that for a full import. This <strong>will</strong> take long, +because it's fetching all the projects at pypi and importing their metadata:</p> +<pre class="literal-block"> +$ pypioncouch --fullimport http://your.couchdb.instance/ +</pre> +<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 http://couchdb.notmyidea.org/pypi/</strong>, to avoid +the duplication of nodes:</p> +<pre class="literal-block"> +$ pypioncouch --update http://your.couchdb.instance/ +</pre> +<p>The principal node is updated once a day by now, I'll try to see if it's +enough, and ajust with the time.</p> +</div> +<div class="section" id="using-the-python-api"> +<h3>Using the python API</h3> +<p>You can also use the python API to interact with pypioncouch:</p> +<pre class="literal-block"> +&gt;&gt;&gt; from pypioncouch import XmlRpcImporter, import_all, update +&gt;&gt;&gt; full_import() +&gt;&gt;&gt; update() +</pre> +</div> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I want to make a couchapp, in order to navigate PyPI easily. Here are some of +the features I want to propose:</p> +<ul class="simple"> +<li>List all the available projects</li> +<li>List all the projects, filtered by specifiers</li> +<li>List all the projects by author/maintainer</li> +<li>List all the projects by keywords</li> +<li>Page for each project.</li> +<li>Provide a PyPI &quot;Simple&quot; API 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 replication</li> +</ul> +<p>I also still need to polish the import mechanism, so I can directly store in +couchdb:</p> +<ul class="simple"> +<li>The OPML files for each project</li> +<li>The upload_time as couchdb friendly format (list of int)</li> +<li>The tags as lists (currently it's only a string separated by spaces</li> +</ul> +<p>The work I've done by now is available on +<a class="reference external" href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it's still +a work in progress, and everything can break at any time. However, any feedback +will be appreciated !</p> +</div> +Help me to go to the distutils2 paris' sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00Alexis Métaireautag: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 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 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 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 event.</p> +<p>You can find more informations about the sprint on the wiki page of the event +(<a class="reference external" 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'm unfortunately blocked in UK for money reasons. +The cheapest two ways I've found is about £80, which I can't afford. +Following some advices on #distutils, I'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 way.</p> +<p>I'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't make it to paris, I'll hang around on IRC to give some help +while needed.</p> +<p>If you want to contribute some money to help me go there, feel free to use this +chipin page: <a class="reference external" href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> +<p>Thanks for your support !</p> +Quels usages pour l'informatique ?2011-01-12T00:00:00+01:002011-01-12T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-01-12:/usages-informatique-fr.html<p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas …</p><p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas vous pourrir la vie. Oui, parce que de +l'informatique on en a partout, des &quot;geeks&quot; et des &quot;accros&quot; aussi, et que ça +vient s'immiscer dans nos vies même quand d'autres moyens ou médias sont plus +utiles ou pertinents.</p> +<p>Certes, l'informatique nous permet de communiquer et travailler plus efficacement, +Mais à quel prix ? Ce n'est pas parce qu'il est possible d'<a class="reference external" href="http://retourdactu.fr/2011/11/07/la-non-communication-nouveau-modele-de-societe/">industrialiser +l'éducation</a> +(ou l'agriculture !), que l'on doit le faire. Oui, ça me dérange d'être une des +nombreuses personnes à l'œuvre derrière cette soit disant &quot;révolution&quot;, qui +n'est pas toujours pour le meilleur. Attention, je ne remets pas l'informatique +et son intérêt en cause: je me pose des questions quand à la place que je veux +lui donner et la place que je souhaites occuper dans son évolution. Ce n'est +pas parce qu'on peut tuer avec un marteau (avec un peu de volonté) qu'il s'agit +d'un mauvais outil, mais si tout le monde se met à tuer avec des marteaux (y a +des malades partout, hein), alors se poser la question de son rôle, en tant que +fabricant de marteaux me semble nécessaire (oui, je vous l'accorde, on aura vu +des comparaisons plus perspicaces).</p> +<p>Donc: à partir de quel moment l'informatique cesse d'être un outil utile pour +transformer nos modes de vies d'une manière qui me dérange ? Peut être avec son +arrivée sur des périphériques mobiles ? Peut être quand elle se fait +l'instrument du consumérisme et de l'individualisme.</p> +<div class="section" id="et-alors-on-fait-quoi"> +<h2>Et alors, on fait quoi ?</h2> +<p>Mais si je continue à faire de l'informatique, il y a bien des raison. J'ai +d'ailleurs trouvé mon intérêt de par le coté collaboratif qui est permis et +développé par l'outil informatique, et notamment par le réseau des réseaux +(internet). Faisons ensemble, mes amis. Prouvons que la collaboration a de +meilleurs jours à vivre que la compétition. Le web, notamment, est une avancée +majeure en ce qui concerne la liberté d'expression et le partage de +connaissances (oui, kipédia). Je vous conseille d'ailleurs à ce propos +<a class="reference external" href="http://owni.fr/2011/11/30/vers-une-economie-de-la-contribution/">l'excellent discours tenu par Bernard Stiegler</a> paru +récemment sur <a class="reference external" href="http://www.owni.fr">owni</a>.</p> +<p>Et c'est cet avenir qu'il me plait de défendre: l'ouverture d'esprit, la +possibilité que chacun puisse contribuer et participer à une base de savoir +commune, en apprenant des autres. Mais par pitié, n'imposons pas la +technologie là où elle n'est pas nécessaire, et utilisons la avec tact quand +elle peut nous être profitable.</p> +<p>Il me plait de repenser l'informatique comme outil et non plus comme mode de +vie. Faisons le l'outil de la collaboration. À l'école, apprenons à nos enfants +à collaborer, à susciter le partage, pas uniquement avec l'outil informatique, +mais aussi avec celui ci, tout en leurs apprenant à avoir un regard critique +sur les informations qu'ils reçoivent.</p> +<p>En bref, questionner le rôle que l'on souhaite avoir dans notre société par le +biais de l'informatique est nécessaire. Comme d'autres, je suis arrivé +à l'informatique par le biais du premier ordinateur familial, il y a de ça une +bonne quinzaine d'années. Ça intrigue, on touche un peu à tout (on en fait des +conneries !) et on finit par apprendre/comprendre comment ça marche, petit +à petit. Cette curiosité n'est d'ailleurs pas le propre de l'informatique +puisqu'on la retrouve dans la cuisine, dans le bricolage et dans un tas de +domaines de notre vie quotidienne.</p> +<p>Finalement, c'est aimer bidouiller, et comprendre comment ça fonctionne, quitte +à sortir les compétences de leur domaine de prédilection (qui a dit que +l'informatique ne pouvait être artistique ?) Le mouvement hacker (bidouilleurs) +aime à sortir l'informatique de son carcan et l'appliquer ailleurs.</p> +<p>C'est de cette manière que j'ai envie de considérer mon métier, qui avant tout +est une passion. Je suis un bidouilleur, j'aime découvrir comment les choses +fonctionnent et avoir une panoplie d'outils qui me permettent de répondre à des +besoins réels.</p> +</div> +<div class="section" id="favoriser-la-collaboration"> +<h2>Favoriser la collaboration</h2> +<p>Et donc, en tant qu'individu, pourquoi faire de l'informatique ? Qu'est-ce qui +m'attire dans cet outil ?</p> +<p>Ce qu'on pourrait qualifier de &quot;recherche fondamentale&quot;, l'écriture de +bibliothèques logicielles, est important mais n'est pas tout. Ce qui importe ce +sont les usages qui en découlent. Je souhaite <strong>savoir écrire des outils qui +sont utiles</strong>, <strong>qui favorisent la collaboration et participent à l'ouverture +des esprits</strong>.</p> +<p>Je choisis de faire de l'informatique pour créer les outils qui répondent à des +problématiques réelles, pour trouver de meilleures manières de communiquer et +de travailler ensemble. Mais, comme me le disait David, d'<a class="reference external" href="http://outils-reseaux.org/PresentationProjet">Outils-Réseaux</a>, on ne crée pas de la +coopération: rien ne sert d'essayer de faire coopérer des gens qui ne veulent +pas. On peut, cependant, la faciliter, en utilisant les bons outils et en +formant les gens à leur utilisation, ainsi qu'aux pratiques collaboratives +(qui, je le répète, ne s'arrêtent pas du tout aux frontières informatique).</p> +<p>Le logiciel libre, avant d'être une force pour le marché logiciel, est une +application du partage. Une démonstration qu'il est possible de travailler +ensemble pour fabriquer quelque chose de fonctionnel et d'utile pour tous. Une +sorte d'antithèse de ce modèle capitaliste incarné par les brevets logiciel.</p> +<p>A plusieurs reprises, j'ai été bluffé par la réalité du logiciel libre. Oui, il +est facile de collaborer lorsqu'on crée un logiciel, pour peu qu'on explique +les tenants et les aboutissants aux participants. Les contributeurs sortent +d'on ne sait où, pour peu que le projet leur soit utile. Je ne parle pas +d'outils &quot;corpo compliant&quot; (bien que ça soit probablement aussi le cas), mais +d'outils que j'ai pu développer pour mon propre usage, et sur lesquels il a été +possible de collaborer avec d'autres.</p> +<p>Parce que l'informatique est utile dans bien des milieux, parce qu'elle peut +être (et elle l'est) un vecteur de participation et de collaboration, défendons +les valeurs qui nous sont chères (logiciels libres et ouverts!) et construisons +des ponts entre les initiatives qui nous parlent (fermes autogérées, +initiatives d'éducation populaire) et l'informatique.</p> +<p>Faisons en sorte de rendre l'informatique accessible et utile dans les milieux +ou elle peut apporter quelque chose !</p> +</div> +Fork you ! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html<p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to …</p><p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to share +our knowledge.</p> +<p>I say github, because it seems to be the more mainstream, but I think it's +something strongly related to the <a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_revision_control">DVCS</a> principles: the &quot;only&quot; thing github have +made is to turn that into a social network, and to reveal the awesomeness of the +DVCSes to the masses.</p> +<p>What is really interesting is to see how this platform is addictive: it's +automatically updating a webpages with the more accurate informations about the +projects you're involved in, and add a bit of magic to that using webhooks, +allowing you to update your website each time you push to you repository, for +instance.</p> +<p>Quite nothing, indeed, but, I don't know why, I find this fascinating.</p> +<p>I haven't had the privilege to see my projects forked from github by strangers, +but I've forked others repository to give an hand some times, when I wanted to, +and the main reason is &quot;because it's <strong>fun</strong>&quot; to do so.</p> +<p>Yeah, you're probably right, you have to be a nerd to find fun to fork others. +The good point is that geeks are a kind of nerds, and some geeks are coders :)</p> +<div class="section" id="new-ways-to-contribute"> +<h2>New ways to contribute</h2> +<p>In addition, it seems that he community, or the communities, are there, on those +new social networks for coders. It's really handy to drop an eye on interesting +projects, to report bugs, propose new features, and check what new projects this +or this person have made.</p> +<p>Well, &quot;it's not new&quot;, you may think. That's true, because it's been a while that +SVN was there and even CVS before that. But, it was a bit messy to &quot;fork&quot; a +project, isn't it ? And I'm not talking about all the hell SVN involved with it +(who have not had issues with those messy .svn folders raises an hand !).</p> +<p>It have not been so easy to share code and thoughts about code, to propose +changes on existing code, than now. You think it's better to implement this or +that in a different way ? Clone it (fork it), make your changes and publish +them, and then ask projects owners about it. For sure you'll have answers.</p> +<p>Even if they don't want it, you can easily keep your changes, and keep getting +their updates!</p> +<p>Also, lot of <em>fashionables</em> projects tend to move on DVCS. +Personally, if I know I can fork on a DVCS instead of from a &quot;simple&quot; VCS, +I'll probably be quicker to fork/clone, and to publish changes on my own copy, +than if I had to do so on the upstream repository (and I'll likely dont have +the rights to push to it), because I will not be afraid to break things.</p> +<p>DVCSes makes the contribution easier.</p> +</div> +<div class="section" id="release-early-release-often"> +<h2>Release early, release often</h2> +<p>Maybe have you read <a class="reference external" href="http://www.catb.org/~esr/writings/cathedral-bazaar/">The cathedral and the bazaar</a>, by Eric Steven Raymond ? +(If not, consider doing so, it's a really interesting reading)</p> +<p>Among a lot of others interesting things, one hint he gives is <em>release early, +release often</em>.</p> +<p>I understand it as: if you want to get contributors, release your code early, +even if it's not perfect, and don't be afraid to publish your changes each +time it's needed.</p> +<p>Without notifying it, that's basically what I was doing for my own projects. +I guess that's because Social coding platforms encourages those practices, +partially cause of the possible impact publishing each of your changes can have +on your final solution.</p> +<p>If you have considered publishing your projects, code snippets, or whatever +(code related) but did not done it, considering them not yet ready, maybe +should you think about it twice: you can get feedback and probably start some +interesting discussions about it, if you write code that's readable, of course!</p> +</div> +<div class="section" id="a-step-further-for-open-source-softwares"> +<h2>A step further for open source softwares</h2> +<p>Well, DVCSes are a honking great idea, and they're starting to be really +powerful when applied to free softwares. I mean: if you can't see a project, +it will be hard to contribute to it. And, I don't think anyone wants to +contribute to something closed/proprietary, <em>just for fun</em>. Or maybe am I +missing something.</p> +<p>Maybe it's a kind of revolution, about free and open source softwares (<a class="reference external" href="http://en.wikipedia.org/wiki/Free_and_open_source_software">FOSS</a>), +that is going on. I really like to know I have my word to say about the changes +in the tools I use, and to know that I can make them evolve.</p> +<p>Let's take an example. Imagine I'm using a web framework on daily basis, as a +part of my job as a web developer. I do like using an open source software +because I know how it's working, and because I know that I can interact with the +authors of the framework while they're doing the changes on it.</p> +<p>That's communication, nothing more, and of course I can do that with an internal +proprietary solution, but it will cost me <strong>a lot</strong> more time, for a dead-simple +reason: a company is not as big and powerful as a community can be: it will cost +time to work on this framework, resources to maintain it, fix bugs etc.</p> +<p>Well, I'm starting advocating here about Free and Open Source Softwares use on +companies, what is a bit beyond the scope of this article, so let's back to +our DVCSes and new social related tools.</p> +<p>If I find a bug in this framework, while working, I have the possibility to +go and talk with the creators of the framework, to open a ticket, and even to +make a fix for it, because I've access to the source code. If I want to create a +new feature, I just have to fork it, hack it, and then publish my code to have +feedback of the community.</p> +<p>My fix/work will benefit to all the people (and maybe others companies) working +with this framework, and it's a way to prove the community that my company is +enough skilled to make code-fixes to the framework, so that's all good !</p> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I hope those social coding platforms are only the begining of a new area. I hope +they will make people realize what the power of the community is, and how easily +they can becomes part of it.</p> +<p>If you're not using them right now, maybe you should do so: have a +look 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 !</p> +</div> +How to reboot your bebox using the CLI2010-10-21T00:00:00+02:002010-10-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.html<p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using …</p></div><p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using directly the +command line tools curl, grep and tail (but really harder to read).</p> +<div class="highlight"><pre><span></span>curl -X POST -u joel:joel 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 -d <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="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> +</pre></div> +</div> +<div class="section" id="the-python-version"> +<h2>The Python version</h2> +<p>Well, that's not the optimal solution, that's a bit &quot;gruik&quot;, but it works.</p> +<div class="highlight"><pre><span></span><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="bp">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> +</pre></div> +</div> +Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html<p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some …</p><p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some time ago, I've made a little python script to ease that, and you can now +use it too. It's named &quot;gnome-background-generator&quot;, and you can install it via +pip for instance.</p> +<div class="highlight"><pre><span></span>$ pip install gnome-background-generator +</pre></div> +<p>Then, you have just to use it this way:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator -p ~/Images/walls -s +/home/alexis/Images/walls/dynamic-wallpaper.xml generated +</pre></div> +<p>Here is a extract of the <cite>--help</cite>:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator --help +usage: gnome-background-generator <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-p PATH<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> + <span class="o">[</span>-t TRANSITION_TIME<span class="o">]</span> <span class="o">[</span>-d DISPLAY_TIME<span class="o">]</span> <span class="o">[</span>-s<span class="o">]</span> + <span class="o">[</span>-b<span class="o">]</span> + +A simple <span class="nb">command</span> line tool to generate an XML file to use <span class="k">for</span> gnome +wallpapers, to have dynamic walls + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -p PATH, --path PATH Path to look <span class="k">for</span> the pictures. If no output is + specified, will be used too <span class="k">for</span> outputing the dynamic- + wallpaper.xml file. Default value is the current + directory <span class="o">(</span>.<span class="o">)</span> + -o OUTPUT, --output OUTPUT + Output filename. If no filename is specified, a + dynamic-wallpaper.xml file will be generated in the + path containing the pictures. You can also use <span class="s2">&quot;-&quot;</span> to + display the xml in the stdout. + -t TRANSITION_TIME, --transition-time TRANSITION_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> transitions must last <span class="o">(</span>default value + is <span class="m">2</span> seconds<span class="o">)</span> + -d DISPLAY_TIME, --display-time DISPLAY_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> a picture must be displayed. Default + value is <span class="m">900</span> <span class="o">(</span>15mn<span class="o">)</span> + -s, --set-background <span class="s1">&#39;&#39;</span><span class="err">&#39;</span>try to <span class="nb">set</span> the background using gnome-appearance- + properties + -b, --debug +</pre></div> +How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html<p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr …</pre><p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr/ports/lang/php5-extensions +$ make package-recursive -C /usr/ports/lang/php5-extensions + +# install nginx +$ make config-recursive -C /usr/ports/www/nginx-devel +$ make package-recursive -C /usr/ports/www/nginx-devel +</pre> +<p>Now we have all the dependencies installed, we need to configure a bit the +server.</p> +<p>That's a simple thing in fact, but it could be good to have something that will +work without effort over time.</p> +<p>Here's a sample of my configuration:</p> +<pre class="literal-block"> +server { + server_name ndd; + set $path /path/to/your/files; + root $path; + + location / { + index index.php; + } + + location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { + access_log off; + expires 30d; + } + + location ~ .php$ { + fastcgi_param SCRIPT_FILENAME $path$fastcgi_script_name; + fastcgi_pass backend; + include fastcgi_params; + } +} + +upstream backend { + server 127.0.0.1:9000; +} +</pre> +<p>And that's it !</p> +Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html<p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple tool to generate your …</p><p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" 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's easy to extend, +and has a template support (via jinja2).</p> +<p>I'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's needs.</p> +<p>Need an example ? You're looking at it ! This weblog is using pelican to be +generated, also for the atom feeds.</p> +<p>I've released it under AGPL, since I want all the modifications to be profitable +to all the users.</p> +<p>You can find a repository to fork at <a class="reference external" href="https://github.com/getpelican/pelican/">https://github.com/getpelican/pelican/</a>. +feel free to hack it !</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 (<cite>pelican --help</cite>)</p> +<div class="highlight"><pre><span></span>$ pip install pelican +</pre></div> +<div class="section" id="usage"> +<h2>Usage</h2> +<p>Here's a sample usage of pelican</p> +<div class="highlight"><pre><span></span>$ pelican . +writing /home/alexis/projets/notmyidea.org/output/index.html +writing /home/alexis/projets/notmyidea.org/output/tags.html +writing /home/alexis/projets/notmyidea.org/output/categories.html +writing /home/alexis/projets/notmyidea.org/output/archives.html +writing /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 ! +</pre></div> +<p>You also can use the <cite>--help</cite> option for the command line to get more +informations</p> +<div class="highlight"><pre><span></span><span class="nv">$pelican</span> --help +usage: pelican <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-t TEMPLATES<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> <span class="o">[</span>-m MARKUP<span class="o">]</span> <span class="o">[</span>-s SETTINGS<span class="o">]</span> <span class="o">[</span>-b<span class="o">]</span> + path + +A tool to generate a static blog, with restructured text input files. + +positional arguments: + path Path where to find the content files <span class="o">(</span>default is + <span class="s2">&quot;content&quot;</span><span class="o">)</span>. + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -t TEMPLATES, --templates-path TEMPLATES + Path where to find the templates. If not specified, + will uses the ones included with pelican. + -o OUTPUT, --output OUTPUT + Where to output the generated files. If not specified, + a directory will be created, named <span class="s2">&quot;output&quot;</span> in the + current path. + -m MARKUP, --markup MARKUP + the markup language to use. Currently only + ReSTreucturedtext is available. + -s SETTINGS, --settings SETTINGS + the settings of the application. Default to None. + -b, --debug +</pre></div> +<p>Enjoy :)</p> +</div> +An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html<p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the …</p><p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the PyPI +testing infrastructure. You could find what each person have done +on +<a class="reference external" 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 shape.</p> +<p>Then, I'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've been introducing myself to +python in the late 2009.</p> +<p>I'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've traveled +since I wrote it.</p> +<p>This summer was awesome because I've learned about python good +practices, now having some strong +<a class="reference external" href="http://mercurial.selenic.com/">mercurial</a> knowledge, and I've +seen a little how the python community works.</p> +<p>Then, I would like to say a big thanks to all the mentors that have +hanged around while needed, on IRC or via mail, and especially my +mentor for this summer, <a class="reference external" 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 work!</p> +<div class="section" id="why"> +<h2>Why ?</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 way.</p> +<p>Now, we have PEPs that describes some format we agreed on (see PEP +345), and we wanted to have a tool on which users can base their +code on, that's <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>.</p> +</div> +<div class="section" id="my-job"> +<h2>My job</h2> +<p>I had to provide a way to crawl the PyPI indexes in a simple way, +and do some installation / uninstallation scripts.</p> +<p>All the work done is available in +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket repository</a>.</p> +<div class="section" id="crawling-the-pypi-indexes"> +<h3>Crawling the PyPI indexes</h3> +<p>There are two ways of requesting informations from the indexes: +using the &quot;simple&quot; index, that is a kind of REST index, and using +XML-RPC.</p> +<p>I've done the two implementations, and a high level API to query +those twos. Basically, this supports the mirroring infrastructure +defined in PEP 381. So far, the work I've done is gonna be used in +pip (they've basically copy/paste the code, but this will change as +soon as we get something completely stable for distutils2), and +that's a good news, as it was the main reason for what I've done +that.</p> +<p>I've tried to have an unified API for the clients, to switch from +one to another implementation easily. I'm already thinking of +adding others crawlers to this stuff, and it was made to be +extensible.</p> +<p>If you want to get more informations about the crawlers/PyPI +clients, please refer to the distutils2 documentation, especially +<a class="reference external" 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 class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> source code .</p> +</div> +<div class="section" id="installation-uninstallation-scripts"> +<h3>Installation / Uninstallation scripts</h3> +<p>Next step was to think about an installation script, and an +uninstaller. I've not done the uninstaller part, and it's a smart +part, as it's basically removing some files from the system, so +I'll probably do it in a near future.</p> +<p><a class="reference external" 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 +METADATA (1.2) (See, the PEP 345), but I'm working on a +compatibility layer for the old metadata, and for the informations +provided via PIP requires.txt, for instance.</p> +</div> +<div class="section" id="extra-work"> +<h3>Extra work</h3> +<p>Also, I've done some extra work. this includes:</p> +<ul class="simple"> +<li>working on the PEP 345, and having some discussion about it +(about the names of some fields).</li> +<li>writing a PyPI server mock, useful for tests. you can find more +information about it on the +<a class="reference external" href="http://distutils.notmyidea.org">documentation</a>.</li> +</ul> +</div> +</div> +<div class="section" id="futures-plans"> +<h2>Futures plans</h2> +<p>As I said, I've enjoyed working on distutils2, and the people I'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 usable.</p> +<p>I'm not plainly satisfied by the work I've done, so I'll probably +tweak it a bit: the installer part is not yet completely finished, +and I want to add support for a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +index in the future.</p> +<p>We'll talk again of this in the next months, probably, but we +definitely need a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +API for <a class="reference external" href="http://pypi.python.org">PyPI</a>, as the &quot;simple&quot; index +<em>is</em> an ugly hack, in my opinion. I'll work on a serious +proposition about this, maybe involving +<a class="reference external" href="http://couchdb.org">CouchDB</a>, as it seems to be a good option +for what we want here.</p> +</div> +<div class="section" id="issues"> +<h2>Issues</h2> +<p>I've encountered some issues during this summer. The main one is +that'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 emails.</p> +<p>I've finally managed to work in an office, so good point for +home/office separation.</p> +<p>I'd not planned there will be so a high number of emails to read, +in order to follow what'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 !).</p> +</div> +<div class="section" id="thanks"> +<h2>Thanks !</h2> +<p>A big thanks to <a class="reference external" href="http://www.graine-libre.fr/">Graine Libre</a> and +<a class="reference external" 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're a student, if you're +interested about FOSS, dont hesitate any second, it's a really good +opportunity to work on interesting projects!</p> +</div> +Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html<p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my …</p><p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my weekly +summaries in +<a class="reference external" href="http://wiki.notmyidea.org/distutils2_schedule">a dedicated wiki page</a>.</p> +<div class="section" id="general-feelings"> +<h2>General feelings</h2> +<p>First, and it's a really important point, the GSoC is going very +well, for me as for other students, at least from my perspective. +It's a pleasure to work with such enthusiast people, as this make +the global atmosphere very pleasant to live.</p> +<p>First of all, I've spent time to read the existing codebase, and to +understand what we're going to do, and what's the rationale to do +so.</p> +<p>It's really clear for me now: what we'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 PEP about packaging.</p> +<p>With distutils2, it will be simpler to make &quot;things&quot; 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 so.</p> +</div> +<div class="section" id="tasks"> +<h2>Tasks</h2> +<p>My main task while working on distutils2 is to provide an +installation and an un-installation command, as described in PEP +376. For this, I first need to get informations about the existing +distributions (what's their version, name, metadata, dependencies, +etc.)</p> +<p>The main index, you probably know and use, is PyPI. You can access +it at <a class="reference external" href="http://pypi.python.org">http://pypi.python.org</a>.</p> +</div> +<div class="section" id="pypi-index-crawling"> +<h2>PyPI index crawling</h2> +<p>There is two ways to get these informations from PyPI: using the +simple API, or via xml-rpc calls.</p> +<p>A goal was to use the version specifiers defined +in`PEP 345 &lt;<a class="reference external" href="http://www.python.org/dev/peps/pep-0345/">http://www.python.org/dev/peps/pep-0345/</a>&gt;`_ and to +provides a way to sort the grabbed distributions depending our +needs, to pick the version we want/need.</p> +<div class="section" id="using-the-simple-api"> +<h3>Using the simple API</h3> +<p>The simple API is composed of HTML pages you can access at +<a class="reference external" 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's why I've preferred to pick up +the good ideas, and some implementation details, plus re-thinking +the global architecture.</p> +<p>The rules are simple: each project have a dedicated page, which +allows us to get informations about:</p> +<ul class="simple"> +<li>the distribution download locations (for some versions)</li> +<li>homepage links</li> +<li>some other useful informations, as the bugtracker address, for +instance.</li> +</ul> +<p>If you want to find all the distributions of the &quot;EggsAndSpam&quot; +project, you could do the following (do not take so attention to +the names here, as the API will probably change a bit):</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>We also could use version specifiers:</p> +<div class="highlight"><pre><span></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 (&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> +</pre></div> +<p>Internally, what's done here is the following:</p> +<ul class="simple"> +<li>it process the +<a class="reference external" href="http://pypi.python.org/simple/FooBar/">http://pypi.python.org/simple/FooBar/</a> +page, searching for download URLs.</li> +<li>for each found distribution download URL, it creates an object, +containing informations about the project name, the version and the +URL where the archive 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 &quot;final&quot; distribution (rather +than beta, alpha etc. ones)</li> +</ul> +<p>So, nothing hard or difficult 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're curious, please browse the +<a class="reference external" href="http://distutils2.notmyidea.org/">distutils2 documentation</a>.</p> +</div> +<div class="section" id="using-xml-rpc"> +<h3>Using xml-rpc</h3> +<p>We also can make some xmlrpc calls to retreive informations from +PyPI. It's a really more reliable way to get informations from from +the index (as it's just the index that provides the informations), +but cost processes on the PyPI distant server.</p> +<p>For now, this way of querying the xmlrpc client is not available on +Distutils2, as I'm working on it. The main pieces are already +present (I'll reuse some work I've made from the SimpleIndex +querying, and +<a class="reference external" 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's on what I'm actually working on.</p> +</div> +</div> +<div class="section" id="processes"> +<h2>Processes</h2> +<p>For now, I'm trying to follow the &quot;documentation, then test, then +code&quot; path, and that seems to be really needed while working with a +community. Code is hard to read/understand, compared to +documentation, and it's easier to change.</p> +<p>While writing the simple index crawling work, I must have done this +to avoid some changes on the API, and some loss of time.</p> +<p>Also, I've set up +<a class="reference external" 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 +...)</p> +</div> +Sprinting on distutils2 in Tours2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/sprinting-on-distutils2-in-tours.html<p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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 …</p><p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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'd really enjoyed this +time, because Éric knows a lot of things about mercurial and python +good practices, and I'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 had.</p> +<div class="section" id="documentation"> +<h2>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'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 those:</p> +<ul class="simple"> +<li><strong>Packagers</strong> who want to distribute their softwares.</li> +<li><strong>End users</strong> who need to understand how to use end user +commands, like the installer/uninstaller</li> +<li><strong>packaging coders</strong> who <em>use</em> distutils2, as a base for +building a package 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 API +description ? etc. That's maybe seems to be not so important, but I +guess the readers would appreciate to have the same structure all +along distutils2 documentation.</p> +</div> +<div class="section" id="mercurial"> +<h2>Mercurial</h2> +<p>I'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'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've not used them so far, so consider this as +a personal note.</p> +<ul class="simple"> +<li>hg histedit, to edit the history</li> +<li>hg crecord, to select the changes to 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 class="reference external" 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 ... Great. I'm a powerful merger now !</p> +</div> +<div class="section" id="on-using-tools"> +<h2>On using 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've +discovered vimdiff and hgtk, which will completely change the way I +navigate into the mercurial history. We aren't &quot;power users&quot;, so we +have learned from each other about vim tips. You can find +<a class="reference external" href="http://github.com/ametaireau/dotfiles">my dotfiles on github</a>, +if it could help. They're not perfect, and not intended to be, +because changing all the time, as I learn. Don't hesitate to have a +look, and to propose enhancements if you have !</p> +</div> +<div class="section" id="on-being-pythonic"> +<h2>On being 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 class="reference external" 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 do.</p> +</div> +<div class="section" id="conclusion"> +<h2>Conclusion</h2> +<p>It was really great. Next time, we'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'll probably do +another sprint in a few weeks, stay tuned !</p> +</div> +Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html<p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 …</p><p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 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 class="reference external" href="http://docutils.sourceforge.net/rst.html">restructured text</a>, so +I've wrote a simple file containing our different bullet points. In +fact, there is quite nothing to do then, to have a working +presentation.</p> +<p>So far, I've used +<a class="reference external" href="http://code.google.com/p/rst2pdf/">the rst2pdf program</a>, and a +simple template, to generate output. It's probably simple to have +similar results using latex + beamer, I'll try this next time, but +as I'm not familiar with latex syntax, restructured text was a +great option.</p> +<p>Here are +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.pdf">the final PDF output</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.rst">Rhe ReST source</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/slides.style">the theme used</a>, +and the command line to generate the PDF:</p> +<pre class="literal-block"> +rst2pdf couchdb.rst -b1 -s ../slides.style +</pre> +first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html<p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I've not worked as much as I +wanted, and this will continues until the end of …</p><p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I'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 class="reference external" 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 class="reference external" href="http://pypi.python.org/">PyPI</a>), and there is at +least two ways to retreive informations from here: XML-RPC and the +&quot;simple&quot; API.</p> +<p>So, I've been working on porting some +<a class="reference external" href="http://bitbucket.org/tarek/distribute/">Distribute</a> related +stuff to <a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a>, cutting +off all non distutils' things, as we do not want to depend from +Distribute's internals. My main work has been about reading the +whole code, writing tests about this and making those tests +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've taken some time to improve the work +<a class="reference external" href="http://bitbucket.org/konrad">Konrad</a> makes about this mock.</p> +<div class="section" id="a-pypi-server-mock"> +<h2>A PyPI Server 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 class="reference external" href="http://wsgi.org">WSGI</a> and +<a class="reference external" 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 class="reference external" 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 +Distutils2).</p> +<p>So, we switched to +<a class="reference external" href="http://docs.python.org/library/basehttpserver.html">BaseHTTPServer</a> +and +<a class="reference external" href="http://docs.python.org/library/simplehttpserver.html">SimpleHTTPServer</a>, +and updated our tests accordingly. It's been an opportunity to +realize that <a class="reference external" href="http://wsgi.org">WSGI</a> has been a great step +forward for making HTTP servers, and expose a really simplest way +to discuss with HTTP !</p> +<p>You can find +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/changesets">the modifications I made</a>, +and the +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/src/tip/docs/source/test_framework.rst">related docs</a> +about this on +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket distutils2 clone</a>.</p> +</div> +<div class="section" id="the-pypi-simple-api"> +<h2>The PyPI Simple API</h2> +<p>So, back to the main problematic: make a python library to access +and request information stored on PyPI, via the simple API. As I +said, I've just grabbed the work made from +<a class="reference external" 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 tests.</p> +</div> +<div class="section" id="the-work-to-come"> +<h2>The work to come</h2> +<p>So, once all use cases covered with tests, I'll rewrite a bit the +grabbed code, and do some software design work (to not expose all +things as privates methods, have a clear API, and other things like +this), then update the tests accordingly and write a documentation +to make this clear.</p> +<p>Next step is to a little client, as I've +<a class="reference external" href="http://github.com/ametaireau/pypiclient">already started here</a> +I'll take you updated !</p> +</div> +A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html<p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python …</blockquote><p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python application (pip, setuptools, distribute, distutils, etc.) +so&nbsp;there is a huge effort to make in order to make all this +packaging stuff interoperable, as pointed out by +the&nbsp;<a class="reference external" href="http://www.python.org/dev/peps/pep-0376/">PEP 376</a>.</blockquote> +<p>In more details, I'm going to work on the Installer / Uninstaller +features of Distutils2, and on a PyPI XML-RPC client for distutils2. +Here are the already defined tasks:</p> +<ul class="simple"> +<li>Implement Distutils2 APIs described in PEP 376.</li> +<li>Add the uninstall command.</li> +<li>think about a basic installer / uninstaller script. (with deps) +-- similar to pip/easy_install</li> +<li>in a pypi subpackage;</li> +<li>Integrate a module similar to setuptools' package_index'</li> +<li>PyPI XML-RPC client for distutils 2: +<a class="reference external" href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> +</ul> +<p>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.</p> +Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y-fr.html<p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un …</p><p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un répis +d'une semaine, pour récupérer des folies organisatrices (c'est ça +qui fait du bien, ceci dit -- les folies, pas le repos), je me +retrouve de nouveau sur ces mêms réflexions, grâce aux journées +organisées par +<a class="reference external" href="http://www.fne.asso.fr/">France Nature Environnement</a>, qui +proposaient ce jeudi soir une projection de &quot;Le temps des grâces&quot;, +un documentaire sur l'agriculture.</p> +<p>Parce que depuis 60 ans, il est pratiqué le remembrement des +parcelles à gogo, parce que nos sols deviennent completement morts +à cause des tonnes d'intrants qu'on leur fait absorber, et parce +que les exploitations s'agrandissent sans en finir pour tenter de +réagir façe à un marché financier toujours plus insaisissable, mené +de très loin par la PAC, il fallait un film pour en parler. C'est +ce que fait &quot;le temps des grâçes&quot;, avec un bon sens et une facilité +à faire passer des messages, qu'on ne peut qu'applaudir.</p> +<p>Malheureusement il s'agissait de la dernière diffusion à +<a class="reference external" href="http://www.cinemas-utopia.org/toulouse/">L'Utopia de Toulouse</a>... +Si vous en avez l'occasion, sautez dessus et profitez le temps de +ces 2 heures, ou vous pourrez écouter à la fois des discours +d'agronomes, d'agriculteurs, de chercheurs et bien d'autres, qui +dressent un constat pas si brillant de notre agriculture. On n'est +pas sorti de l'auberge, enfin, c'est l'expression.</p> +<p>Je vous laisse avec le synopsis et une bande annonce.</p> +<blockquote> +Une enquête documentaire sur +le monde agricole français aujourd'hui à travers de nombreux récits +: agriculteurs, chercheurs, agronomes, écrivains... Un monde qui +parvient à résister aux bouleversements qui le frappent - +économiques, scientifiques, sociaux - et qui, bon gré mal gré, +continue d'entretenir les liens entre générations. Un monde au +centre d'interrogations majeures sur l'avenir.</blockquote> +<p>Ainsi qu'un commentaire que je ne peux m'empécher de relayer, +trouvé sur allocine.fr (oui, vous savez, ce site rempli de pubs).</p> +<blockquote> +Le temps des grâces c'est je pense le plus grand film traitant de +l'écologie en tant que documentaire ou en sujet principal, on y +apprend une multitude de choses, on en ressort en colère contre le +système, le film propose différents points de vues, ici on a pas de +voix off moralisatrice à deux balles avec des gros titres bien +surlignés pour que même les beaufs matant TF1 puissent comprendre, +ici même si ça reste accessible au citoyen lambda, le film ne fait +pas de compromis avec le monde agroalimentaire, il ose dénoncer les +filière d'agronomie qui apprennent pas les bonnes choses à leurs +étudiants, aux lobbys de cette agro-industrie qui n'en fait qu'à sa +tête pour amasser de l'argent, cette tendance à tout uniformiser et +détruire… Franchement j'ai trouvé ça génial de bout en bout, +captivant, on explore cette campagne française, on comprend les +dilemmes des paysants. Le film n'étant pas opposé à la modernité, +ni même réactionnaire, il propose juste un constat alarmant du +monde agricole français, tout en proposant des alternatives qui +pourraient être utilisée, si les pouvoirs publics lâchaient un peu +la main des lobbys. Passionnant, vraiment.</blockquote> +<p>Courrez-y, je vous dis.</p> +Semaine de l’environnement: La consommation étudiante2010-02-24T00:00:00+01:002010-02-24T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-02-24:/semaine-de-lenvironnement-la-consommation-etudiante-fr.html<p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres …</p><p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres), et a tout un tas d'autres associations que je ne peux pas citer ici exhaustivement... Ce sont eux qui sont porteurs de messages alternatifs, et qui sont les initiateurs de débats publics, qui permettent de faire avancer des thématiques aussi importantes que le logiciel libre ou la protection de l'environnement.</p> +<p>Dans cette optique, depuis près de 3 ans (déjà !), au sein du +<a class="reference external" href="http://www.reseaugrappe.org">réseau GRAPPE</a>, on <em>essaye</em> +d'aborder des thématiques qui touchent de près ou de loin à +l'environnement, parce que c'est un sujet qui nous importe et nous +passionne. L'année dernière, c'était l'alimentation étudiante, ce +qui à abouti à la publication de +<a class="reference external" href="http://public.reseaugrappe.org/alimentation.pdf">la revue &quot;les étudiants se mettent à table&quot;</a>. +Cette année c'est la consommation étudiante qui est au programme.</p> +<div class="section" id="la-consommation-etudiante"> +<h2>La consommation étudiante ?</h2> +<p>L'idée principale de cette étude est de tenter de faire une analyse +de la &quot;société de consommation&quot;, souvent questionnée par les +étudiants et par d'autres, et de jeter un œil sur le rapport des +étudiants à cette société: Quoi et comment consomment-ils ? Les +universités et les écoles ne poussent-elles pas d’une certaine +manière les étudiants à la consommation ? Quelles sont les +alternatives face aux dérives de surconsommation ?</p> +<blockquote> +Analyse des pratiques, réflexions et mobilisations des étudiants en +termes de consommation seront réalisés pour comprendre leur modes +de vie, mais aussi leurs attentes, leurs propositions sur cette +thématique</blockquote> +</div> +<div class="section" id="la-semaine-de-l-environnement"> +<h2>La semaine de l'environnement !</h2> +<p>A travers l'ensemble des villes du réseau, +des projections de films et des débats auront donc lieu sur ce +thème, lors de la semaine de l'environnement 2010, qui se déroulera +d'ailleurs durant le mois de Mars +<a class="reference external" href="http://www.reseaugrappe.org/la-semaine-de-lenvironnement-programme/">partout en france</a>, +et <strong>du 6 au 14 Mars sur Toulouse</strong>. +<a class="reference external" href="http://docs.notmyidea.org/sde/prog-toulouse.pdf">Jetez un oeil au programme</a> +! Avec pour objectif de sonder un peu le ressenti des étudiants en +terme de consommation, nous avons mis en place +<a class="reference external" href="http://spreadsheets.google.com/viewform?formkey=dHV2bVllS2lWbzhyV3NBN3NUbi1TM2c6MA">un questionnaire en ligne</a>, +que vous pouvez compléter en une petite 10aine de minutes, +n'hésitez pas ! +<a class="reference external" href="http://www.reseaugrappe.org/consommation/">La page sur la consommation étudiante sur le site du GRAPPE</a></p> +</div> +Python ? go !2009-12-17T00:00:00+01:002009-12-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-12-17:/python-go-fr.html<p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à …</p><p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à l'esprit à propos de Python, sont &quot;logique&quot; et +&quot;simple&quot;. Et pourtant puissant pour autant. Je ne manque d'ailleurs +pas une occasion pour faire un peu d'<em>évangélisation</em> auprès des +quelques personnes qui veulent bien m'écouter.</p> +<div class="section" id="the-zen-of-python"> +<h2>The Zen of Python</h2> +<p>Avant toute autre chose, je pense utile de citer Tim Peters, et +<a class="reference external" href="http://www.python.org/dev/peps/pep-0020/">le PEP20</a>, qui +constituent une très bonne introduction au langage, qui prends la +forme d'un <em>easter egg</em> présent dans python</p> +<div class="highlight"><pre><span></span>&gt;&gt;&gt; import this +The Zen of Python, by Tim Peters + +Beautiful is better than ugly. +Explicit is better than implicit. +Simple is better than complex. +Complex is better than complicated. +Flat is better than nested. +Sparse is better than dense. +Readability counts. +Special cases 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 Dutch. +Now is better than never. +Although never is often better than *right* now. +If the implementation is hard to explain, 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="k">do</span> more of those! +</pre></div> +<p>J'ai la vague impression que c'est ce que j'ai toujours cherché à +faire en PHP, et particulièrement dans +<a class="reference external" href="http://www.spiral-project.org">le framework Spiral</a>, mais en +ajoutant ces concepts dans une sur-couche au langage. Ici, c'est +directement de <em>l'esprit</em> de python qu'il s'agit, ce qui signifie +que la plupart des bibliothèques python suivent ces concepts. Elle +est pas belle la vie ?</p> +</div> +<div class="section" id="comment-commencer-et-par-ou"> +<h2>Comment commencer, et par ou ?</h2> +<p>Pour ma part, j'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'est bien évidemment pas exhaustive et vos +commentaires sont les bienvenus) :</p> +<ul class="simple"> +<li><a class="reference external" href="http://diveintopython.adrahon.org/">Dive into python</a></li> +<li><a class="reference external" href="http://www.swaroopch.com/notes/Python_fr:Table_des_Matières">A byte of python</a></li> +<li><a class="reference external" href="http://www.amazon.fr/Python-Petit-guide-lusage-développeur/dp/2100508830">Python: petit guide à l'usage du développeur agile</a> +de <a class="reference external" href="http://tarekziade.wordpress.com/">Tarek Ziadé</a></li> +<li><a class="reference external" href="http://docs.python.org/index.html">La documentation officielle python</a>, +bien sûr !</li> +<li><a class="reference external" 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 :)</li> +</ul> +<p>J'essaye par ailleurs de partager au maximum les ressources que je +trouve de temps à autres, que ce soit +<a class="reference external" href="http://www.twitter.com/ametaireau">via twitter</a> ou +<a class="reference external" href="http://delicious.com/ametaireau">via mon compte delicious</a>. +Allez jeter un œil +<a class="reference external" href="http://delicious.com/ametaireau/python">au tag python</a> sur mon +profil, peut être que vous trouverez des choses intéressantes, qui +sait!</p> +</div> +<div class="section" id="un-python-sexy"> +<h2>Un python sexy</h2> +<p>Quelques fonctionnalités qui devraient vous mettre l'eau à la +bouche:</p> +<ul class="simple"> +<li><a class="reference external" 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 condition)</li> +<li>Assignation de valeurs multiples (il est possible de faire a,b,c += 1,2,3 par exemple)</li> +<li><a class="reference external" href="http://docs.python.org/tutorial/datastructures.html">Les listes</a> +sont simples à manipuler !</li> +<li>Les <a class="reference external" 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 simple.</li> +<li>Les +<a class="reference external" 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 exemples.</li> +<li>Les +<a class="reference external" 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 construisent</li> +<li>Python est +<a class="reference external" 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'est ce qui m'agaçait avec PHP qui est un langage à typage faible +dynamique.</li> +</ul> +<p>Cous pouvez également aller regarder +<a class="reference external" href="http://video.pycon.fr/videos/free/53/">l'atelier donné par Victor Stinner durant le Pyconfr 09</a>. +Have fun !</p> +</div> +AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e-fr.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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à …</p><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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à expliquer que justement, l'AMAP c'est +avant tout, pour nous, une notion de solidarité envers les +agriculteurs, malgré le fait que le message soit plus profond que +simplement aller acheter du bio (ça, c'est possible aussi en +supermarché), malgré le fait qu'il s'agisse en fait d'une remise en +cause plus profonde de la société, les journalistes n'ont choisi de +prendre que les quelques secondes qui leurs convenaient, celles qui +ne faisaient pas tache, celle ou je dis que &quot;l'AMAP permet aux +étudiants de réapprendre à cuisiner, plutôt que de manger des +nouilles et de se faire des plats réchauffés&quot;. Bien sur, je l'ai +dit et je le pense d'ailleurs, là n'est pas le problème, mais mon +message n'était pas celui là.</p> +<p>Jamais, dans les quelques minutes du reportage, on ne dit ce que +AMAP signifie: Association de <strong>Maintien</strong> d'une Agriculture +<strong>Paysanne</strong>. On ne parles même pas des agriculteurs ! C'est +simplement plus facile pour les étudiants de venir récupérer leurs +paniers, puisque les points de distribution sont sur les facs, et +en plus ça ne coute que 5 euros ! ...</p> +<p>Alors je crois bon de rappeler que L'AMAP n'est pas seulement un +service, c'est un engagement. Sur 5 mois, un engagement solidaire, +c'est la donnée principale de l'équation, celle sans quoi ça ne +peut fonctionner. Par le biais de cette AMAP, on essaye de montrer +que d'autres agricultures sont possibles, que la solidarité c'est +bien réel, et qu'il est possible de sortir du +<em>tout, tout de suite</em>.</p> +<p>Mais bon, apparemment, ça passe pas bien à la télé.</p> + \ No newline at end of file diff --git a/feeds/alexis-metaireau.rss.xml b/feeds/alexis-metaireau.rss.xml new file mode 100644 index 0000000..2d21ac5 --- /dev/null +++ b/feeds/alexis-metaireau.rss.xml @@ -0,0 +1,455 @@ + +Carnets Web - Alexis Métaireauhttps://blog.notmyidea.org/Wed, 03 Jul 2019 00:00:00 +0200Ourshttps://blog.notmyidea.org/ours.html<p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>De manière plus large, est-ce normal …</p>Alexis MétaireauWed, 03 Jul 2019 00:00:00 +0200tag:blog.notmyidea.org,2019-07-03:/ours.htmlvelotafhttps://blog.notmyidea.org/velotaf.html<p>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 …</p>Alexis MétaireauThu, 27 Jun 2019 00:00:00 +0200tag:blog.notmyidea.org,2019-06-27:/velotaf.htmlUn espace des communs Rennais ?https://blog.notmyidea.org/un-espace-des-communs-rennais.html<p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le …</p>Alexis MétaireauWed, 26 Jun 2019 00:00:00 +0200tag:blog.notmyidea.org,2019-06-26:/un-espace-des-communs-rennais.htmlDe Mozilla à la Brasserie du Vieux Singehttps://blog.notmyidea.org/de-mozilla-a-la-brasserie-du-vieux-singe.html<p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que …</em></p>Alexis MétaireauSun, 27 May 2018 00:00:00 +0200tag:blog.notmyidea.org,2018-05-27:/de-mozilla-a-la-brasserie-du-vieux-singe.htmlGroupement d'achats & partage d'expériencehttps://blog.notmyidea.org/groupement-dachats-partage-dexperience.html<p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers …</p>Alexis MétaireauSat, 03 Mar 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.htmlWebnoteshttps://blog.notmyidea.org/webnotes.html<p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière …</p>Alexis MétaireauSun, 25 Feb 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-02-25:/webnotes.htmlFaire moinshttps://blog.notmyidea.org/faire-moins.html<p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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 …</p>Alexis MétaireauMon, 19 Feb 2018 00:00:00 +0100tag:blog.notmyidea.org,2018-02-19:/faire-moins.htmlNEIPA #3https://blog.notmyidea.org/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les …</li></ul>Alexis MétaireauFri, 29 Dec 2017 00:00:00 +0100tag:blog.notmyidea.org,2017-12-29:/neipa-3.htmlNEIPA #2https://blog.notmyidea.org/neipa-2.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le …</li></ul>Alexis MétaireauMon, 18 Dec 2017 00:00:00 +0100tag:blog.notmyidea.org,2017-12-18:/neipa-2.htmlUn club des brasseurs amateurs Rennaishttps://blog.notmyidea.org/un-club-des-brasseurs-amateurs-rennais.html<p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante …</p>Alexis MétaireauMon, 06 Nov 2017 00:00:00 +0100tag:blog.notmyidea.org,2017-11-06:/un-club-des-brasseurs-amateurs-rennais.htmlL'arrivée du trouble (ou comment faire des NEIPA ?)https://blog.notmyidea.org/larrivee-du-trouble-ou-comment-faire-des-neipa.html<p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir …</p>Alexis MétaireauTue, 17 Oct 2017 00:00:00 +0200tag:blog.notmyidea.org,2017-10-17:/larrivee-du-trouble-ou-comment-faire-des-neipa.htmlBrasserie 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'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour …</p>Alexis MétaireauMon, 26 Jun 2017 00:00:00 +0200tag:blog.notmyidea.org,2017-06-26:/brasserie-du-vieux-singe-installation-en-cours.htmlComment est-ce que vous générez vos formulaires ?https://blog.notmyidea.org/comment-est-ce-que-vous-generez-vos-formulaires.html<p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est …</em></p>Alexis MétaireauTue, 31 May 2016 00:00:00 +0200tag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.htmlCloisonnement des activités ?https://blog.notmyidea.org/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en …</p>Alexis MétaireauSun, 29 May 2016 00:00:00 +0200tag:blog.notmyidea.org,2016-05-29:/cloisonnement-des-activites.htmlAvez 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'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop …</p>Alexis MétaireauFri, 25 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-25:/avez-vous-confiance-en-ssl.htmlFocusing on what mattershttps://blog.notmyidea.org/focusing-on-what-matters.html<p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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>Alexis MétaireauThu, 17 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.htmlfocustime-managementRetours 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'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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 …</p>Alexis MétaireauThu, 17 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-17:/retours-sur-un-atelier-zeronet.htmlL'horizonhttps://blog.notmyidea.org/lhorizon.html<blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont …</p>Alexis MétaireauWed, 02 Mar 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-03-02:/lhorizon.htmlLet's Encrypt + HAProxyhttps://blog.notmyidea.org/lets-encrypt-haproxy.html<blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début …</p>Alexis MétaireauThu, 11 Feb 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.htmlAteliers d'autodéfense numériquehttps://blog.notmyidea.org/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de …</li></ul></blockquote>Alexis MétaireauThu, 14 Jan 2016 00:00:00 +0100tag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.htmlRencontres python francophones, 2015https://blog.notmyidea.org/rencontres-python-francophones-2015.html<p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation …</p>Alexis MétaireauMon, 02 Nov 2015 00:00:00 +0100tag:blog.notmyidea.org,2015-11-02:/rencontres-python-francophones-2015.htmlPyconFR 2015 — Assemblée généralehttps://blog.notmyidea.org/pyconfr-2015-assemblee-generale.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes …</p></div>Alexis MétaireauSun, 18 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-assemblee-generale.htmlPyconFR 2015 — Hospital - des tests en prodhttps://blog.notmyidea.org/pyconfr-2015-hospital-des-tests-en-prod.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et …</p>Alexis MétaireauSun, 18 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-hospital-des-tests-en-prod.htmlPyconFR 2015 — We don't need your loophttps://blog.notmyidea.org/pyconfr-2015-we-dont-need-your-loop.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer …</p>Alexis MétaireauSun, 18 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-we-dont-need-your-loop.htmlPyconFR 2015 — Cliquethttps://blog.notmyidea.org/pyconfr-2015-cliquet.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous …</p></div>Alexis MétaireauSat, 17 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-cliquet.htmlPyconFR 2015 — Geoalchemyhttps://blog.notmyidea.org/pyconfr-2015-geoalchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des …</p>Alexis MétaireauSat, 17 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-geoalchemy.htmlPyconFR 2015 — SQL Alchemyhttps://blog.notmyidea.org/pyconfr-2015-sql-alchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent …</li></ul>Alexis MétaireauSat, 17 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-sql-alchemy.htmlPyconFR 2015 — Table ronde diversitéhttps://blog.notmyidea.org/pyconfr-2015-table-ronde-diversite.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et …</strong></p>Alexis MétaireauSat, 17 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-table-ronde-diversite.htmlWeb distribution signinghttps://blog.notmyidea.org/web-distribution-signing.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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>Alexis MétaireauMon, 12 Oct 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.htmlRôleshttps://blog.notmyidea.org/roles.html<blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de …</p></blockquote>Alexis MétaireauMon, 29 Jun 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-06-29:/roles.htmlLes problèmes de PGPhttps://blog.notmyidea.org/les-problemes-de-pgp.html<blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois …</p>Alexis MétaireauMon, 25 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.htmlTravail et créativitéhttps://blog.notmyidea.org/travail-et-creativite.html<blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui …</p>Alexis MétaireauThu, 21 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.htmlSimplifier les preuves d'identitéshttps://blog.notmyidea.org/simplifier-les-preuves-didentites.html<p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la …</p>Alexis MétaireauMon, 11 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.htmlPhrases de passe et bonnes pratiqueshttps://blog.notmyidea.org/phrases-de-passe-et-bonnes-pratiques.html<blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi …</p></blockquote>Alexis MétaireauSat, 09 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.htmlChiffrementhttps://blog.notmyidea.org/chiffrement.html<blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise …</strong></li></ul></blockquote>Alexis MétaireauFri, 08 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-08:/chiffrement.htmlLanguagehttps://blog.notmyidea.org/language.html<blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux …</p></blockquote>Alexis MétaireauFri, 01 May 2015 00:00:00 +0200tag:blog.notmyidea.org,2015-05-01:/language.htmlLe secret du bonheurhttps://blog.notmyidea.org/le-secret-du-bonheur.html<p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village …</p>Alexis MétaireauThu, 20 Nov 2014 00:00:00 +0100tag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.htmlWhat's Hawk and how to use it?https://blog.notmyidea.org/whats-hawk-and-how-to-use-it.html<p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original …</p>Alexis MétaireauThu, 31 Jul 2014 00:00:00 +0200tag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.htmlQuel métier, quelle utilité ?https://blog.notmyidea.org/quel-metier-quelle-utilite.html<p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est …</p>Alexis MétaireauTue, 29 Jul 2014 00:00:00 +0200tag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.htmlRetours sur deux ans à Mozillahttps://blog.notmyidea.org/retours-sur-deux-ans-a-mozilla.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud …</p>Alexis MétaireauTue, 29 Jul 2014 00:00:00 +0200tag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.htmlLe revenu de basehttps://blog.notmyidea.org/le-revenu-de-base.html<iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra …</p>Alexis MétaireauThu, 03 Oct 2013 00:00:00 +0200tag:blog.notmyidea.org,2013-10-03:/le-revenu-de-base.htmlDes carnets d'esquissehttps://blog.notmyidea.org/des-carnets-desquisse-fr.html<p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir …</p>Alexis MétaireauFri, 16 Aug 2013 00:00:00 +0200tag:blog.notmyidea.org,2013-08-16:/des-carnets-desquisse-fr.htmlNotes: Économie libidinale et économie politiquehttps://blog.notmyidea.org/notes-economie-libidinale-et-economie-politique.html<p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un …</p>Alexis MétaireauSat, 06 Jul 2013 00:00:00 +0200tag:blog.notmyidea.org,2013-07-06:/notes-economie-libidinale-et-economie-politique.htmlNew year python meme, 2012https://blog.notmyidea.org/new-year-python-meme-2012.html<p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this …</p>Alexis MétaireauMon, 01 Jul 2013 00:00:00 +0200tag:blog.notmyidea.org,2013-07-01:/new-year-python-meme-2012.htmlFrançois Elie : Quelle école pour la société de l’information ?https://blog.notmyidea.org/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html<p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens …</p></blockquote>Alexis MétaireauFri, 14 Jun 2013 00:00:00 +0200tag:blog.notmyidea.org,2013-06-14:/francois-elie-quelle-ecole-pour-la-societe-de-linformation.htmlDes profils de confiance partout et pour tout ?https://blog.notmyidea.org/confiance-fr.html<p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site …</p>Alexis MétaireauTue, 02 Apr 2013 00:00:00 +0200tag:blog.notmyidea.org,2013-04-02:/confiance-fr.htmlImplementing CORS in Cornicehttps://blog.notmyidea.org/cross-origin-in-cornice.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In …</p>Alexis MétaireauTue, 02 Apr 2013 00:00:00 +0200tag:blog.notmyidea.org,2013-04-02:/cross-origin-in-cornice.htmlStatus boardhttps://blog.notmyidea.org/status-board-fr.html<p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org …</cite></p>Alexis MétaireauSat, 29 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-29:/status-board-fr.htmlHabitat 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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais …</p>Alexis MétaireauFri, 28 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-28:/habitat-collectif.htmlLanguageshttps://blog.notmyidea.org/languages.html<p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe>Alexis MétaireauFri, 28 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-28:/languages.htmlnoteTricothttps://blog.notmyidea.org/tricot.html<p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu …</p>Alexis MétaireauFri, 28 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-28:/tricot.htmlnoteAstuces SSHhttps://blog.notmyidea.org/astuces-ssh.html<div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s …</pre></div>Alexis MétaireauThu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/astuces-ssh.htmlnoteGnome 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'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial …</a></li></ul>Alexis MétaireauThu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/gnome-3-extensions.htmlnote"Groovy"https://blog.notmyidea.org/groovy.html<p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>C'est pour ça que j'ai du …</p>Alexis MétaireauThu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/groovy.htmlnoteNotre dame des landeshttps://blog.notmyidea.org/notre-dame-des-landes.html<p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre …</p>Alexis MétaireauThu, 27 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-27:/notre-dame-des-landes.htmlSemences paysanneshttps://blog.notmyidea.org/semences-paysannes.html<p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité …</p>Alexis MétaireauThu, 20 Dec 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-12-20:/semences-paysannes.htmlLifestylehttps://blog.notmyidea.org/lifestyle-fr.html<p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre …</p>Alexis MétaireauMon, 05 Nov 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-11-05:/lifestyle-fr.htmlCheese & code - Wrap-uphttps://blog.notmyidea.org/cheese-code-wrap-up.html<p>This week-end I hosted a <em>cheese &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. Bad.</p> +<p>We were not enough to get rid of all the cheese and the awesome …</p>Alexis MétaireauMon, 22 Oct 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.htmlCheese & Code party: October 20-21https://blog.notmyidea.org/afpy-computer-camp-october-20-21.html<p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing …</p>Alexis MétaireauThu, 20 Sep 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-09-20:/afpy-computer-camp-october-20-21.htmlCircus sprint at PyconFRhttps://blog.notmyidea.org/circus-sprint-at-pyconfr.html<p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're …</p>Alexis MétaireauMon, 17 Sep 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.htmlPourquoi Mozilla?https://blog.notmyidea.org/pourquoi-mozilla-fr.html<p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi …</p>Alexis MétaireauMon, 16 Jul 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla-fr.htmllogiciel-librevaleursRefactoring Cornicehttps://blog.notmyidea.org/refactoring-cornice.html<p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> routing system, +allowing to register services in …</p>Alexis MétaireauMon, 14 May 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-05-14:/refactoring-cornice.htmlpythonCornicerefactoringBidouillehttps://blog.notmyidea.org/bidouille-fr.html<p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de …</p>Alexis MétaireauMon, 30 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-30:/bidouille-fr.htmldiyélectroniquehackbidouilleDjangocong 2012https://blog.notmyidea.org/djangocong-2012-fr.html<p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une …</p>Alexis MétaireauMon, 16 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-16:/djangocong-2012-fr.htmlBière maison !https://blog.notmyidea.org/biere-maison-fr.html<p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si …</p>Alexis MétaireauTue, 10 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-10:/biere-maison-fr.htmlMotivation, bénévolat et participationhttps://blog.notmyidea.org/motivation-benevolat-et-participation-fr.html<p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux …</p>Alexis MétaireauTue, 10 Apr 2012 00:00:00 +0200tag:blog.notmyidea.org,2012-04-10:/motivation-benevolat-et-participation-fr.htmlLes dangers du livre numériquehttps://blog.notmyidea.org/les-dangers-du-livre-numerique-fr.html<p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable …</p>Alexis MétaireauMon, 23 Jan 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique-fr.html2012, first monthshttps://blog.notmyidea.org/2012-first-months.html<p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services …</p>Alexis MétaireauSat, 21 Jan 2012 00:00:00 +0100tag:blog.notmyidea.org,2012-01-21:/2012-first-months.htmlUsing 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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +contents.</p> +<p>Boilerpipe is written in Java. Two solutions then: using java from python or +reimplement boilerpipe …</p>Alexis MétaireauSun, 06 Nov 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-11-06:/using-jpype-to-bridge-python-and-java.htmlpythonjavaHow are you handling your shared expenses?https://blog.notmyidea.org/how-are-you-handling-your-shared-expenses.html<p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 …</p>Alexis MétaireauSat, 15 Oct 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.htmlpythonflaskbudget-managerLa simplicité volontaire contre le mythe de l'abondancehttps://blog.notmyidea.org/la-simplicite-volontaire-contre-le-mythe-de-labondance-fr.html<p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car …</blockquote>Alexis MétaireauFri, 14 Oct 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-10-14:/la-simplicite-volontaire-contre-le-mythe-de-labondance-fr.htmlUsing dbpedia to get languages influenceshttps://blog.notmyidea.org/using-dbpedia-to-get-languages-influences.html<p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 …</p>Alexis MétaireauTue, 16 Aug 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.htmldbpediasparqlpythonPelican, 9 months laterhttps://blog.notmyidea.org/pelican-9-months-later.html<p>Back in October, I released <a class="reference external" 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>Alexis MétaireauMon, 25 Jul 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.htmlpelicanpythonopen sourcenice storyIntroducing Cornicehttps://blog.notmyidea.org/introducing-cornice.html<p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of …</p>Alexis MétaireauTue, 12 Jul 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-07-12:/introducing-cornice.htmlUn coup de main pour mon mémoire!https://blog.notmyidea.org/un-coup-de-main-pour-mon-memoire-fr.html<p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de main.</p> +<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui connaissent +last.fm, je …</p>Alexis MétaireauWed, 25 May 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire-fr.htmlTravailler moins pour mieux travailler ?https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler-fr.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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un …</p>Alexis MétaireauThu, 19 May 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler-fr.htmlAnalyse users' browsing context to build up a web recommenderhttps://blog.notmyidea.org/analyse-users-browsing-context-to-build-up-a-web-recommender.html<p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full …</p>Alexis MétaireauFri, 01 Apr 2011 00:00:00 +0200tag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.htmlrecommendationsbrowsersusersWorking 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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time …</p>Alexis MétaireauWed, 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.htmlfreebsdunisonWrap 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've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what …</p>Alexis MétaireauTue, 08 Feb 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-02-08:/wrap-up-of-the-distutils2-paris-sprint.htmlPyPI 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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +drawbacks.</p> +<p>Basically, if you want to …</p>Alexis MétaireauThu, 20 Jan 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-01-20:/pypi-on-couchdb.htmlHelp 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 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 event.</p> +<p>You can find more …</p>Alexis MétaireauSat, 15 Jan 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-01-15:/help-me-to-go-to-the-distutils2-paris-sprint.htmlQuels usages pour l'informatique ?https://blog.notmyidea.org/usages-informatique-fr.html<p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas …</p>Alexis MétaireauWed, 12 Jan 2011 00:00:00 +0100tag:blog.notmyidea.org,2011-01-12:/usages-informatique-fr.htmlFork 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 class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to …</p>Alexis MétaireauFri, 05 Nov 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.htmlHow to reboot your bebox using the CLIhttps://blog.notmyidea.org/how-to-reboot-your-bebox-using-the-cli.html<p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using …</p></div>Alexis MétaireauThu, 21 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.htmlDynamically change your gnome desktop wallpaperhttps://blog.notmyidea.org/dynamically-change-your-gnome-desktop-wallpaper.html<p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some …</p>Alexis MétaireauMon, 11 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.htmlHow to install NGINX + PHP 5.3 on FreeBSD.https://blog.notmyidea.org/how-to-install-nginx-php-53-on-freebsd.html<p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr …</pre>Alexis MétaireauSun, 10 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.htmlPelican, a simple static blog generator in pythonhttps://blog.notmyidea.org/pelican-a-simple-static-blog-generator-in-python.html<p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple tool to generate your …</p>Alexis MétaireauWed, 06 Oct 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.htmlAn amazing summer of code working on distutils2https://blog.notmyidea.org/an-amazing-summer-of-code-working-on-distutils2.html<p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the …</p>Alexis MétaireauMon, 16 Aug 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.htmlIntroducing the distutils2 index crawlershttps://blog.notmyidea.org/introducing-the-distutils2-index-crawlers.html<p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my …</p>Alexis MétaireauTue, 06 Jul 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.htmlSprinting on distutils2 in Tourshttps://blog.notmyidea.org/sprinting-on-distutils2-in-tours.html<p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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 …</p>Alexis MétaireauTue, 06 Jul 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-07-06:/sprinting-on-distutils2-in-tours.htmlUse Restructured Text (ReST) to power your presentationshttps://blog.notmyidea.org/use-restructured-text-rest-to-power-your-presentations.html<p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 …</p>Alexis MétaireauFri, 25 Jun 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.htmlfirst week working on distutils2https://blog.notmyidea.org/first-week-working-on-distutils2.html<p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I've not worked as much as I +wanted, and this will continues until the end of …</p>Alexis MétaireauFri, 04 Jun 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.htmlA Distutils2 GSoChttps://blog.notmyidea.org/a-distutils2-gsoc.html<p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python …</blockquote>Alexis MétaireauSat, 01 May 2010 00:00:00 +0200tag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.htmlLe temps des grâces, courrez-y !https://blog.notmyidea.org/le-temps-des-graces-courrez-y-fr.html<p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un …</p>Alexis MétaireauSun, 28 Mar 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y-fr.htmlSemaine de l’environnement: La consommation étudiantehttps://blog.notmyidea.org/semaine-de-lenvironnement-la-consommation-etudiante-fr.html<p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres …</p>Alexis MétaireauWed, 24 Feb 2010 00:00:00 +0100tag:blog.notmyidea.org,2010-02-24:/semaine-de-lenvironnement-la-consommation-etudiante-fr.htmlPython ? go !https://blog.notmyidea.org/python-go-fr.html<p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à …</p>Alexis MétaireauThu, 17 Dec 2009 00:00:00 +0100tag:blog.notmyidea.org,2009-12-17:/python-go-fr.htmlAMAP + Média = Paniers bio à 5e ?!https://blog.notmyidea.org/amap-media-paniers-bio-a-5e-fr.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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à …</p>Alexis MétaireauWed, 11 Nov 2009 00:00:00 +0100tag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e-fr.html \ No newline at end of file diff --git a/feeds/all-en.atom.xml b/feeds/all-en.atom.xml new file mode 100644 index 0000000..1170101 --- /dev/null +++ b/feeds/all-en.atom.xml @@ -0,0 +1,5854 @@ + +Carnets Webhttps://blog.notmyidea.org/2019-07-03T00:00:00+02:00Ours2019-07-03T00:00:00+02:002019-07-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-07-03:/ours.html<p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>De manière plus large, est-ce normal …</p><p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>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 ?</p> +<p>Suis-je en train de devenir un ours ?</p>velotaf2019-06-27T00:00:00+02:002019-06-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-27:/velotaf.html<p>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 …</p><p>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 personelle et le taf à la brasserie.</p>Un espace des communs Rennais ?2019-06-26T00:00:00+02:002019-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-26:/un-espace-des-communs-rennais.html<p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le …</p><p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le sujet des <em>communs</em>; +2. Monter une structure Rennaise pour proposer de l’hébergement de services web.</p> +<p>Élaborons un peu...</p> +<h2>1. Un espace pour fédérer</h2> +<p>L'idée qui à été développée est celle d'avoir un espace (un ou des lieux, à différents moments dans l'année) pour que les rencontres entre les projets <em>du libre</em> à Rennes puissent se dérouler. Le constat est qu'il existe différentes structures actuellement en place, mais que a) certaines personnes ne se retrouvent pas dans ces espaces et b) la porosité entre ces différents groupes est assez faible.</p> +<p>Pour l'instant pas d'idée précise de ce qui pourrait être proposé, mais quelques pistes ont été évoquées. l'envie est de faire un document d'intention et de proposer à d'autres de rejoindre le collectif en création.</p> +<h3>Fréquence</h3> +<p>Deux pistes ont été évoquées:</p> +<ul> +<li> +<p><strong>Faire des rencontres suffisamment espacées les unes des autres</strong>, pour que leur caractère « exceptionnel » soit une force. Si la fréquence des réunions est assez faible, alors l'incitation pour y prendre part est peut-être plus grande ?</p> +</li> +<li> +<p>ou au contraire, <strong>avoir des rencontres avec une fréquence assez forte</strong>, pour qu'en cas d'incapacité à participer il n'y ait pas trop longtemps à attendre ?</p> +</li> +</ul> +<h3>Charte éthique</h3> +<p>Le fait d'avoir un <em>code de conduite</em> pour de tels évènements à été discuté, un des arguments évoqués étant le fait qu'un tel code n'est pas considéré nécessaire par certaines personnes, puisque les règles évoquées tiennent du bon sens.</p> +<p>Il a été précisé que l'établissement de ce type de document a pour objectif de: +- Faire que des minorités et/ou oppressés se sentent protégés et considérés, et donc bienvenues à ce type d'évènements; +- En cas de situations considérées comme problématiques, des personnes référentes soient désignées pour aider à leur résolution</p> +<h3>Gouvernance</h3> +<p>Le sujet de la gouvernance à été également abordé : pour avoir de tels rendez-vous, peu importe leur nature, il faut que ceux-cis soient organisés. La possibilité d'avoir des organisat·rices·eurs· tournantes à été proposé.</p> +<p>Pour :</p> +<ul> +<li>Cela permet de ne pas reposer uniquement sur quelques personnes;</li> +<li>Faire des fiches explicatives qui permettent à tou·te·s de s'impliquer</li> +</ul> +<p>Contre : </p> +<ul> +<li>Quand tout le monde est responsable, personne ne l'est.</li> +</ul> +<p>Peut-être que des solutions intermédiaires sont à trouver, en désignant d'une fois sur l'autre les personnes qui s’occupent du prochain rendez-vous, par exemple.</p> +<h2>2. Hébergement de services Web</h2> +<p>On a discuté très rapidement de la possibilité de monter une structure pour faire de l’hébergement de services web sur Rennes. Le sujet n'a pas été vraiment développé, mais la question de la relation entre avoir un espace pour fédérer (le 1.) et être un hébergeur de service (le 2.) a été rapidement abordé.</p> +<p>Faut-il avoir une seule et même structure / groupe de personnes pour ces deux projets ? Dans le cas ou l'un s'arrête, entraînerait-il l'autre dans sa « chute » ? Est-il logique de lier les deux ?</p> +<h2>Et donc ?</h2> +<p>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 :-)</p>De Mozilla à la Brasserie du Vieux Singe2018-05-27T00:00:00+02:002018-05-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2018-05-27:/de-mozilla-a-la-brasserie-du-vieux-singe.html<p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que …</em></p><p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que d'autres ont pris plus de place que prévu. J'avais donc envie de reprendre mes notes pour les transformer en billet de blog, question d'élaborer sur le sujet.</em></p> +<hr> +<p>J'ai toujours été motivé par mes passions. Quand j'ai commencé à travailler professionnellement, je me suis rendu compte que même si je faisais quasiment la même chose qu'auparavant, ça n'avait plus le même goût. J'étais maintenant <em>obligé</em> de le faire, et je n'en tirais pas le même plaisir.</p> +<p>Quand j'étais plus jeune au lycée j'écrivais des programmes en <em>Visual Basic</em> que je partageais en ligne sur mon site en <code>.free.fr</code>. Programmes que probablement personne n'a lu, mais l'intention était bel et bien celle de partager mes créations, et d'échanger à leur propos.</p> +<p>Cette culture du partage — celle du logiciel libre — est celle qui m'anime.</p> +<p>Quelques années plus tard, je découvre le langage de programmation Python, et avec lui toute une communauté, mue par ces mêmes valeurs de partage et d'amélioration de nos pratiques. Puis je rencontre le Logiciel Libre, avec l'écriture d'un programme (<a href="https://getpelican.com">pelican</a>) qui reste encore largement utilisé aujourd'hui. Autant dire que c'est une bonne claque que de voir des inconnus contribuer à un bout de code qu'eux aussi jugent utile.</p> +<p>À la fin de mes études, alors que je reste passionné par le développement logiciel, je ne veux ni travailler pour l'industrie, ni pour la finance. Je songe même déjà à cette époque à changer de métier (avant même d'avoir commencé !). Coup de bol, une structure qui m'est chère cherche des développeurs Python: Mozilla. Sans trop y croire, je passe une série d'entretiens qui se déroulent bien (!) et je commence quelques mois plus tard à travailler pour cette organisation incroyable, porteuse d'espoir et de toute une symbolique pour moi.</p> +<p>Je bosse sur du Logiciel Libre, en Python, en télétravail parfois, avec une bonne paie, sans parler du côté prestigieux. Grisant.</p> +<p>Mais au fur et à mesure je découvre l'envers du décors: une méritocratie ancrée et assumée, une hiérarchie de plus en plus importante, menant à une lourdeur administrative assez présente. À ajouter à la barrière de la langue, et aux différences culturelles. Finalement tout n'est pas rose ici.</p> +<p>Je décide alors de (je pense) faire un de mes meilleurs choix de vie à ce jour: passer aux 4/5èmes. Je récupère tous mes vendredis. Des weekends de 3 jours, toutes les semaines. Un espace précieux pour me reposer, et pour rêver un peu.</p> +<p>C'est à ce moment que Fred, un ami de longue date, en revenant du Québec (ou les brasseries sont légion), me propose de faire de la bière avec lui. Moi qui ne savais même pas qu'il était <em>possible</em> de faire de la bière. On tente donc l'expérience, et nos premières expériences sont des journées bien <em>funky</em>, à faire toutes les erreurs possibles.</p> +<p>Peu à peu, on découvre un nouveau monde: celui des brasseurs amateurs. De nouvelles compétences sont nécessaires, de la physique à la biochimie. On se met à rencontrer des professionnels, des passionnés, à échanger sur les forums. On se forme, petit à petit. Tout comme il y a la communauté des gens qui font du Python, il y a la communauté des gens qui font de la bière. Pas encore autant fédérés, ça semble balbutiant alors mais la passion elle est bien présente.</p> +<p>Tout comme le monde du Logiciel Libre est constitué autour d'un ennemi commun (les GAFA), le monde de la bière artisanale à la sien: les brasseries industrielles, qui uniformisent les goûts et les processus.</p> +<p>Je continue en parallèle mon travail chez Mozilla, pendant 4 années. Et puis un jour, une annonce d'arrêt d'un projet sur lequel je travaillais me fait réaliser que cette situation m'épuise. La fameuse goutte de trop.</p> +<p>Je décide alors de partir, de faire une pause, sans trop savoir ce que l'avenir me réserve. Une petite période de blanc de deux mois. Le regard des autres est parfois culpabilisant. Mes parents me demandent si « je ne veux pas attendre encore un peu ». La transition me fait peur, mais je choisis quand même de troquer mon confort matériel pour de la cohérence.</p> +<p>Petit à petit, l'idée de monter ce qui est maintenant devenu <a href="https://www.vieuxsinge.com">La Brasserie du Vieux Singe</a> se pose en évidence. Mais monter une brasserie ce n'est pas uniquement faire de la bière: c'est se mettre d'accord sur des valeurs, trouver comment les défendre, monter un projet pour, et tenir le cap.</p> +<p>Quelques mois après mon départ, on se retrouve donc à parler de ces valeurs de partage, de documentation, de goût. De gouvernance et de collaboration aussi. +Dans nos pratiques courantes, on décide d'intégrer du temps pour documenter la vie de la brasserie.</p> +<p>À titre d'exemple, nos étiquettes contiennent l'ensemble des ingrédients que l'on utilise de la manière la plus détaillée possible. On travaille aussi sur un projet de laveuse de fûts, qui sera publié sous licence libre, avec l'idée de pouvoir, petit à petit, constituer un ensemble d'outils utiles à tous les brasseurs, et peut être même réussir à favoriser les échanges entre toutes ces personnes.</p> +<p>Nous sommes deux brasseurs, deux chefs d'entreprise, mais aussi deux développeurs. Nos compétences de développeurs nous sont utiles quotidiennement: pour notre laveuse de fûts, pour nos créations de recettes (j'ai découvert la puissance des tableurs !), pour notre site de préventes, notre site Web, nos outils du quotidien. On se rend compte qu'il s'agit de compétences précieuses.</p> +<p>Mais monter une entreprise, c'est aussi assumer une partie administrative. Vous vous rappelez cette histoire de réactions face aux activités subordonnées ? Et bien quand je fais mes déclarations aux douanes, ce n'est pas de gaîté de cœur. Je sais par contre pourquoi je le fais: ce sont les règles du jeu. Des obligations, mais peut-être moins de coercition. J'y trouve plus de sens.</p> +<p>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.</p> +<p>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. </p>Groupement d'achats & partage d'expérience2018-03-03T00:00:00+01:002018-03-03T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.html<p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers …</p><p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers et une 60aine de 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'expérience et quelques astuces / outils, au cas où l'envie vous prenne à vous aussi :)</p> +<h1>Organisation</h1> +<p>On organise environs trois ou quatre distributions par an. Le <em>modus operandi</em> est le suivant:</p> +<ul> +<li>chaque product·eur·rice à un·e référent·e, qui s'occupe de faire le lien;</li> +<li>une personne est désignée pour coordonner la distribution;</li> +<li>4 semaines avant la distribution, les référent·e·s mettent à jour les prix / produits dans le tableau de commandes;·e·</li> +<li>3 semaines avant la distribution, les commandes sont ouvertes;</li> +<li>2 semaines avant la distribution, les commandes sont closes;</li> +<li>Les référent·e·s ont ensuite deux semaines pour récupérer les commandes pour la distribution</li> +</ul> +<h1>Quels produits ?</h1> +<p>On essaye d'avoir uniquement des produits qui se conservent (on a également quelques autres produits plus frais, mais avec d'autres modalités).</p> +<p>Entre autres: bières, légumes secs, conserves, jus, miel, pâtes, semoule, café, vinaigres, pommes de terre, oignons, huiles, 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'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'est pas animé par la même éthique !).</p> +<h1>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'attendre la date de la distribution pour l'encaissement. La plupart des producteurs acceptent d'être payés sous quinzaine.</p> +<p>Le jour de la distribution, tout le monde apporte son chéquier. Nous avons mis +en place une moulinette qui s'occupe de faire la répartition des chèques automatiquement, chaque membre se retrouve à faire en moyenne un ou deux chèques.</p> +<p>Chaque référent·e est ainsi remboursé·e de la somme avancée, et chaque +membre du groupement d'achat paye ce qu'il doit payer. Nous n'avons +volontairement pas de structure juridique et pas de compte en banque. Les +paiements s'effectuent directement entre nous.</p> +<h1>Transports</h1> +<p>Chaque référent·e commande les produits, puis ensuite s'occupe de les rapatrier. À Rennes, on a la chance d'avoir pas mal de producteurs aux alentours, donc c'est assez simple.</p> +<p>Le mieux est de ramener les produits juste un peu avant la distribution au lieu de distribution, ça permet d'éviter de les stocker trop longtemps, et d'éviter aux producteurs d'attendre trop longtemps avant d'encaisser les chèques.</p> +<p>Pour les grosses commandes, les voitures se remplissent bien, mais ma petite Clio suffit, que ce soit dit !</p> +<h1>La distribution</h1> +<p>Un peu en amont de la distribution, il faut organiser l'espace. Des tas par membre sont constitués pour faciliter les choses le jour de la 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 pour:</p> +<ul> +<li>discuter de la date de la prochaine distribution;</li> +<li>trouver une nouvelle personne pour la coordonner;</li> +<li>discuter de nouveaux produits;</li> +<li>refaire le monde;</li> +<li>changer de référents pour les producteurs.</li> +</ul> +<p>Et c'est reparti pour un tour ;)</p> +<h1>Nos outils</h1> +<p>On utilise un tableur en ligne pour partager les prix et prendre les commandes. On a essayé d'utiliser <em>ethercalc</em> au début mais ça ne fonctionnait pas pour nous à l'époque (trop de petits bugs). On a donc préféré utiliser Google docs (ouch).</p> +<p>Il est d'ailleurs possible d'y intégrer de nouvelles fonctionnalités assez facilement, du coup Fred et Rémy ont planché sur un moyen d'automatiser la répartition des chèques (qu'on faisait dans un premier temps à la main - assez péniblement).</p> +<p>Le système n'est pas parfait mais fonctionne quand même assez bien !</p> +<p>Quelques ressources, donc:</p> +<ul> +<li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des 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'en faire une copie !).</li> +</ul> +<p>Bon groupement d'achat ;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière …</p><p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c'est à dire:</p> +<ul> +<li>enregistrer une sélection de texte ainsi que son contexte: heure, site web.</li> +<li>fonctionner sur Firefox;</li> +<li>stocker mes notes à un endroit que je contrôle (ce sont mes données, après tout !)</li> +<li>rester en dehors de mon chemin: je suis en train de lire, pas en train d'organiser mes notes.</li> +<li>automatiquement partager les notes sur une page web.</li> +</ul> +<p>J'ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j'ai baptisé « Webnotes ». C'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'est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué !</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 !</p>Faire moins2018-02-19T00:00:00+01:002018-02-19T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-19:/faire-moins.html<p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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 …</p><p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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'occasion de contribuer à éviter notre société d'experts.</p> +<p>Le hic, c'est que trop, c'est trop. J'ai donc décidé d'arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j'ai même arreté de faire des choses que j'avais commencé à faire (par exemple de l'escalade), me libérant du temps.</p> +<p>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.</p> +<p>Et surtout, c'est se retrouver à contrôler son engagement.</p>NEIPA #32017-12-29T00:00:00+01:002017-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-29:/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les trouvailles des deux premières versions;</li> +<li>Hop stand de 40mn;</li> +<li>Contrôle du pH à 5.2;</li> +<li>Refroidissement dans l'évier;</li> +<li>Ajouter plus d'avoine;</li> +<li>Faire un mash out;</li> +<li>Augmenter un peu la quantité de grain.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1055 (atteint) +pH: 5.2 (5.4 mesuré)</p> +<h2>Grains:</h2> +<ul> +<li>75% de Pale Ale</li> +<li>12.5% de blé</li> +<li>12.5% flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Mosaic (Hop Stand 40mn)</li> +<li>2g/L Citra (Hop Stand 40mn)</li> +<li>4g/L Citra à cru (en deux fois)</li> +<li>4g/L Mosaic à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li> +<h2>Gypse: 1g</h2> +<dl> +<dd>1.8g (=4.05ml)</dd> +</dl> +</li> +<li>Acide lactique: 0.4ml</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>68°C durant 40mn;</li> +<li>75°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>GigaYeast «Vermont Ale». Le nombre de cellules n'est pas indiqué sur le packaging, ni en ligne.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>12h50: empâtage à 68°C</li> +<li>pH = 5.5. Ajout de 0.2 d'acide.</li> +<li>Pas mal de mesures du pH:<ul> +<li>5.2@23°C (13h05)</li> +<li>5.4@18°C (13h05)</li> +<li>5.2@27°C (13h15)</li> +<li>5.3@19°C (13h20)</li> +<li>5.4@25°C (13h30)</li> +</ul> +</li> +<li>13h33: Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: OK</li> +<li>14h11: 1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>31/12/2017 - Fermentation à 20°C</li> +<li>01/01/2018 - Ajout de 12g de Citra et 12g de Mosaic après deux jours.</li> +<li>10/01/2018 - 1.040 SG = 1.008 corrigé</li> +<li>15/01/2018 - Ajout de 12g de Citra et 12g de Mosaic</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>En mettant 1.5ml d'acide, si on mesure le pH de l'eau, il est à 3.5. Ça nous à pas mal effrayé, puisque on a pas trop l'habitude de monitorer le pH. On refait: 0.4ml d'acide = pH de 4.1. Au final, cela ne semble pas utile de mesurer le pH de l'eau avant de mettre son grain.</li> +<li>Je le savais déjà, mais travailler à deux en discutant n'est pas vraiment une bonne idée: sur les opérations un peu technique, un manque de concentration se fait tout de suite ressentir.</li> +<li>BeerSmith semble proposer un outil pour calculer les modifications de pH, je devrais l'utiliser la prochaine fois.</li> +<li>Baisser le ration d'empâtage: On s'est retrouvé avec beaucoup trop d'eau de rincage, alors qu'on était sur une bière assez faible en densité.</li> +<li>Au final, ajouter l'acide au départ est problématique pour le pH de l'eau qui baisse énormement. Après quelques recherches, il semble qu'il faille faire confiance au logiciel, et prendre une seule mesure de pH à 10mn (cela devrait être stable). Le pHmetre est aussi peut-être en cause.</li> +<li>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 ?</li> +</ul>NEIPA #22017-12-18T00:00:00+01:002017-12-18T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-18:/neipa-2.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le fermenteur</li> +<li>Ne pas se laisser avoir par la baisse de température durant l'empâtage.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1060 (1050 mesuré) +pH: 5.2 (atteint)</p> +<h2>Grains:</h2> +<ul> +<li>90% Pils</li> +<li>10% Flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Wakatu (au Whirlpool)</li> +<li>2g/L Motueka (au Whirlpool)</li> +<li>4.5g/L Wakatu à cru (en deux fois)</li> +<li>2.5g/L Motueka à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li>Gypse: 0.9g</li> +<li>CaCl2: 3.4g</li> +<li>Acide lactique: Au batch précédent, j'avais mesuré 5.6, donc: ajout de +2ml d'acide (=2.4g).</li> +<li>Utilisation d'Irish Moss (2g) pour coaguler les protéines.</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>65°C durant 90mn (68°C au départ, 65 visé)</li> +<li>78°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>London Ale III.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>18h36 - empatage à 65°C</li> +<li>19h16- pH = 5.2</li> +<li>Densité 1er moût: 1070</li> +<li>Ébullition importante pour atteindre 6,2L avec la bonne densité.</li> +<li>Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: NOK</li> +<li>1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>18/12/2017 - Fermentation à 18°C</li> +<li>21/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Passage à 10°C.</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>Je change de technique, et mets l'acide lactique directement dans l'eau.</li> +<li>Je concasse moins fin mais reteste quand même l'avoine. Aucun souci de filtration (mais l'avoine n'est pas concassé).</li> +<li>1g de CaCl2 ~= 2.25ml en solution à 33%.</li> +<li>Les deux thermomètres n'affichent pas la même température. Super :(.</li> +<li>Au final, j’empâte dans une casserole pour pouvoir faire un mash-out.</li> +<li>Le pH oscille pas mal durant l'empâtage. J'ai mesuré des pH de 4.9 à certains moments, mais au final la dernière lecture est de 5.2, ce qui me semble bon.</li> +<li>Le système que j'utilise (refroidisseur en cuivre) pour refroidir mon moût n'est pas génial parce que ça mélange pas mal ce qu'on veut voir se déposer au fond de la cuve. Refroidir directement dans l'évier est vachement plus simple (c'est pratique de faire du 6L pour çà !)</li> +<li>Le teste à l'iode était positif: tout n'était pas converti. Mais à 90mn de mash, je ne crois pas pouvoir faire grand chose de plus.</li> +<li>Idée en vrac, à voir à la dégustation, mais ajouter un peu de cara pourrait être sympa.</li> +<li>L'irish moss à vraiment bien fonctionné. Je me demande si je ne devrais pas même laisser décanter un peu plus longtemps durant le whirlpool pour avoir un effet encore plus impressionnant.</li> +<li>Je trouve que l'efficacité de cette brasserie est vraiment pourrie.</li> +<li>Un peu d'eau est venue diluer le moût (DI = 1050 au lieu de 1060 souhaité)</li> +<li>Au goût, le moût à vraiment un goût qui m'assèche la gorge. Trop de modifications de l'eau ? A voir si l'effet persiste après fermentation.</li> +<li>A priori, d'après un article de Scott Janish, empâter avec de l'avoine cru ne fonctionne que si on empate haut. Ca à un impact sur l'efficacité générale (2h pour conversion totale, c'est peut-être pour ça que mon teste à l'iode était positif)</li> +<li>Sur l'avoine toujours, il faut <strong>dépasser 18%</strong> pour avoir un côté moelleux. Certains mettent jusqu'à 40% !</li> +</ul>Un club des brasseurs amateurs Rennais2017-11-06T00:00:00+01:002017-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-11-06:/un-club-des-brasseurs-amateurs-rennais.html<p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante …</p><p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante autour de la brasserie artisanale dans le coin.</p> +<p>En six mois, on est maintenant une grosse trentaine de personnes à être inscrits sur les listes et à se retrouver de temps à autres.</p> +<p>On en profite pour s'échanger des bons plans, déguster nos créations, (essayer de) faire des commandes groupées de malt, et pour se rencontrer pour papoter entre passionnés.</p> +<p>On a pas mal d'idées de trucs sympa a faire, entre autres:</p> +<ul> +<li>brasser une fois en gros puis se séparer le batch en plein de petits fermenteurs pour essayer différentes levures, différents houblons en <em>dry hop</em>, etc.</li> +<li>A la dernière rencontre, on s'est mis d'accord sur un style de bière pour se lancer un petit défi: tous brasser <a href="https://blog.notmyidea.org/larrivee-du-trouble-ou-comment-faire-des-neipa.html">une NEIPA</a> pour ensuite comparer nos résultats.</li> +</ul> +<p>Bref, c'est plutôt chouette ! Je me suis rendu compte qu'on avait quasiment aucune existence en dehors des réseaux sociaux, alors je me permet de publier ce petit bout d'article avec quelques liens…</p> +<p>Si tu es dans le coin et que tu souhaite nous rencontrer, n'hésite pas à rejoindre <a href="https://www.facebook.com/groups/899071153568179/">notre groupe de discussion Facebook</a> et notre <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">liste de diffusion mail</a>.</p> +<p>A bientôt ;)</p>L'arrivée du trouble (ou comment faire des NEIPA ?)2017-10-17T00:00:00+02:002017-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-10-17:/larrivee-du-trouble-ou-comment-faire-des-neipa.html<p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir …</p><p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir leur propre bataille qui divise au moins autant: une IPA peut elle être aussi trouble qu'une hefeweizen ? En provenance du coin Nord Est des  États-Unis, l'IPA trouble est en passe de devenir culte depuis quelques années. Mais la mode ne vient pas sans contrecoup. En fait, tout le monde y va de son opinion chez les brasseurs artisanaux. Pour ceux qui apprécient ce type d'IPA, l'apparence trouble signifie que les gorgées qui suivent seront extrèmenent riches en huiles de houblons; pour les autres, l'apparence est un affront à des principes ancestraux. Que vous les appeliez des rince-bouches, des soupes boueuses, brillantes ou horribles, ne vous faites pas de fausse idée: ces ales troubles sont là pour rester.</p> +<p>Pour commencer cette histoire, revenons un peu au début des années 1990. La scène brassicole artisanale était en train de vivre son premier boom et les nouvelles brasseries faisaient leur apparition dans tous les coins des États-Unis. Menée par Sierra Nevada Brewing Company, les American Pale Ale et les American IPA étaient en train d’émerger en tant que styles populaires parmi les amateurs de bière, pour leurs caractéristiques riches en houblon.</p> +<p>Le niveau d'amertume était un trait notoire, et avoir la bonne morsure d'amertume était essentiel pour une IPA. L'innovation a ensuite commencée à arriver sur la cote Ouest des États Unis à la fin des années 1990, et au début des années 2000, quand quelques doubles ou impériales IPA telles que Pliny the Elder de Russian River et Ruination IPA de Stone Brewing ont commencées à sortir des fermenteurs. Alors que celles ci contenaient énormement de « morsure du houblon», ce qui séparaient ces bières de beaucoup d'autres versions du style était le fait que le nez et la saveur du houblon semblaient éclater de la bière.</p> +<p>Du point de vue du brasseur, les huiles essentielles de ces houblons étaient bien plus présents que les acides alpha. En utilisant un profil de malt neutre et une souche de levure neutre, ces bières laissaient la part belle aux houblons. Ces brasseurs utilisaient aussi des houblons souvent critiqués, forts en acides alpha, tels que Columbus, Centennial, Simcoe et Chinook à la fin de l'ébullition ou en houblonnage à cru... et en grosses quantitées. Cela peut sembler comme une pratique courante pour une IPA actuellement, mais il y a à peine 15 ans, la plupart de la littérature évitaient d'utiliser ces variétés de houblon pour une utilisation autre que de l'amérisant. Lévolution d'une nouvelle American IPA était en train de prendre forme, sur la cote Ouest des étants unis, un style que les buveurs de bière ont nommé la « West Coast IPA».</p> +<h1>La phase de démarrage</h1> +<p>De retour sur la cote Est des États-Unis, dans un petit brewpub de Burlington à Vermont, deux brasseurs commencent innocemment à développer un type d'American IPA avec des objectifs similaires que les brasseurs de la côte Ouest, mais en utilisant une stratégie différente. Crée en 1988 par Greg Noonan et Steve Polewacyk, le « Vermont Pub &amp; Brewery » deviendra le berceau d'une nouvelle révolution autour des IPA.</p> +<p>Souvent citée comme étant les premiers brasseurs des Black IPA modernes ainsi que des New England IPA, offrant une variété de bières qui était extrèmement rare à cette époque, le « Vermont Pub &amp; Brewery » a des racines provenant de la connaissance du brassage et de la chimie de Greg Noonan, ainsi que son flair pour la créativité.</p> +<p>Se reposant sur la révolution de la bière mondiale (menée par Michael Jackson), Greg Noonan à exploré des styles de bières qui étaient en dehors des sentiers battus, même pour les brasseurs qui étaient déjà en avance sur leur temps.</p> +<p>Arrive John Kimmich, qui, en 1994 à déménagé dans le Vermont avec l'objectif de brasser sous la tutelle de Greg Noonan. John à travaillé un temps à Pittsburg (en Pennsylvanie) dans un <em>home brewshop</em> nommé Country Wines. Il a travaillé avec Alexis Hartung et sa grande bibliothèque sur le brassage maison et a eu son premier éclair de génie brassicole en lisant le livre de Greg Noonan « New Brewing Lager Beer ». Un an plus tard, il commence à travailler au « Vermont Pub &amp; Brewery ». En quelques mois, Greg commence à avoir confiance dans les capacités de son nouveau protégé. Avec chaque bière que John travaillait, le mentor était impressionné. Après douze mois, Greg donne la liberté à John d’expérimenter seul sur les recettes.</p> +<p>En 1997, John part du « Vermont Pub &amp; Brewery » et cofonde avec sa femme Jen un brewpub en 2003, le « Alchemist Pub &amp; Brewery », situé 30mn à l'est de Burlington à Waterbury dans le Vermont. A cette époque, Waterbury était un petit village dormant du New England, n'attirant pas grand monde autre que quelques touristes. Il était par contre assez bien situé, à un croisement des chemins, juste à la sortie d'une autoroute majeure, Waterbury est facilement accessible par à la fois les voyageurs en route pour les endroits touristiques et pour les locaux en allant / revenant du travail ou pour leurs excursions shopping. Grâce à ces quelques éléments, Waterbury s'est donc révélé êre un excellent spot pour Jen et John.</p> +<p>Une caractéristique unique des bières houblonnées de Kimmich était que lorsque servies fraîches et non filtrées, elles étaient souvent assez troubles. Il trouvait que filtrer ses bières pouvait introduire de l'oxygène non souhaité, enlevant de la bière beaucoup d'aspects intéressants. Il utilisait une souche nommée Conan (VPB1188), une levure que son mentor a développé et que maintenant beaucoup connaissent. Avec les dérivés Anglais, la souche de levure Conan, les bonnes connaissances en brassage de John, ainsi que son habitude à expérimenter avec les houblons, on se retrouve avec une combinaison gagnante pour une révolution du brassage sur la côte est.</p> +<h1>La phase de croissance</h1> +<p>En 2007, alors que j'allais au festival des brasseurs du Vermont, la queue pour accéder au stand de The Alchemist était d'au moins 20 minutes pour un verre. Certaines personnes remplissaient leurs verres et retournaient faire la queue pour avoir la chance de goûter une autre de ces bières tant acclamées, en particulier pour Heady Topper. Pour la première fois brassée en 2003, Heady Toper retenait alors l'attention, alors qu'elle n'était réellement qu'une parmi les nombreuses IPA acclamées de chez The Alchemist. Des histoires circulaient comme quoi certaines personnes amenaient leurs pintes aux toilettes pour remplir des bouteilles, les capsuler et les ramener chez eux, puisque le bar ne proposait pas de remplir de Growlers à l'époque, ni ne vendait de bouteilles. Je pensais alors que l'engouement pour ces IPAs avait atteint une sorte de paroxysme. Je n'avais pas encore compris que le feu était seulement en train de se construire.</p> +<p>J'ai récemment demandé à Shaun Hill, de la brasserie « Hill Farmsted » à Greensborrow Bend dans le Vermont, classée « meilleure brasserie du monde » 3 des 4 dernières années sur RateBeer.com, quel était sa relation avec John Kimmich à l'époque. Shaun brassait à l'époque 30mn plus loin, à Stowe, dans un brewpub appelé « The Shed».</p> +<p>« En 2005, je ne tarissais pas d'éolges pour les bières de John me faisait le plaisir de critiquer mes bières » me dit Hill, « Cette relation à évoluée avec le temps, plus specialement lorsque j'ai déménagé au Danemark et que cette conversation est devenue une conversation entre pairs, poussant l'autre dans de nouvelles directions.». Avec le decès de Greg Noonan en 2009, l'ancien protégé est devenu le nouveau mentor. Lors d'un échange avec Joel Mahaffey de Foundation brewing Co, à Portland à propos des IPAs influentes pour cette nouvelle révolution, il dit de The Alchemist « Quiconque réponds à cette question et oublie Heady Topper, ils sont à coté de la plaque. Il s'agit de la première IPA trouble, et à laissée une marque sur la communauté brassicole.»</p> +<p>Ce qui à emergé dans le coin nord-est des états unis est une explosion de nouvelles brasseries produisant des Pale Ale, des IPA et des double IPA basées sur la non filtration, l'explosion de saveurs, et un corps doux, un style que Greg Noonan et John Kimmich ont découvert, et qu'ensuite Shaun Hill à continué à affiner. John et Shaun ont séparemment pointé du doigt le fait qu'ils brassaient juste des bières à leur convenance, et qu'ils appréciaient le produit fini. Le terme « Juicy IPA » s'est retrouvé être un nom pour ces bières, et la texture est souvent aussi importante que le nez et le gout de houblons. Et comme les IPA de la côte Ouest se sont répendues en 2008, les bières troubles, non filtrées, les New England IPA se répendent en 2016.</p> +<h1>C'est parti !</h1> +<p>Il est maintenant temps de passer à la brasserie et de regarder comment faire pour brasser une IPA, New England style. Shaun Hill dit « soyez vous mêmeet faites une bière qui goute, sent et ressemble à ce que vous voulez qu'elle soit », JC Tetreault de Trillum à Boston dans le Massachussetts ajoute « la réponse courte… tout est important ! Vous devez vous concentrer sur chaque aspect pour arriver à la bière que vous souhaitez. » L'objectif est d'arriver à une bière douce, un peu ronde, presque tropicale, à la texture ressemblant presque à un jus de fruit, laissant une morsure subtile sur la langue en fin de bouche graçe au houblon.</p> +<h2>Les malts</h2> +<p>Tout comme les IPAs de la cote Ouest, les NEIPA sont relativement simples en malts. Le style évite les malts qui ajoutent des saveurs de pain et de crackers. Les malts cristals et autres malts au dessus de 20°L (ndt: 52 EBC) sont d'une manière générale évités. Ces bières peuvent bénéficier de certains ajouts de malts cristal clairs, mais gardez les à l’œil. Des flocons d'avoine, d'orge, de blé et autres peuvent être ajoutés pour contribuer au corps, mais ne pensez pas qu'ils soient une necessité. J'ai pu jouer avec des pourcentages de 15% de flocons dans mes recettes, et les résultats étaient presque excessifs. JC Tetreault dit que « à propos des ajouts de céréales non maltés et de flocons… nous ne les utilisons pas dans toutes nos bières basées sur le houblon. En fait, une proportion plutôt petite de nos bières basées sur le houblon en font usage». Les ajouts de sucre tels que les dextrose, saccharose et sucres crus augmentent la densité du moût pour s'assurer de la sécheresse dans les versions plus alcoolisées. Si vous choisissez d'ajouter du sucre cru, encore une fois, faites en sorte que l'ajout soit modeste; j'ai trouvé que certaines saveurs de mélasses avaient tendance à arriver à partir de 10% du total du grain. L'objectif est de garder les houblons comme caractéristique principale de la bière, tout en ayant une base de malt douce mais présente.</p> +<h2>Les levures</h2> +<p>Et c'est ici que les NEIPA dérivent des IPA de la cote Ouest. L'ajout des levures ainsi que le traitement à partir de la fermentation semble être la plus grosse différence entre les deux styles. D'abord, regardons comment ces bières sont fermentées. La plupart des NEIPA ne sont pas clarifiées dans le fermenteur avec des agents clarifiant tels que de la gélatine, du Biofine® ou du Polyclar™, et elles ne sont pas filtrées ou centrifugées plus tard pour clarifier la bière. La pensée derrière ce process est qu'enlever les levures de la bière à également pour effet d'enlever les huiles essentielles ainsi que d'autres nuances subtiles qui permettent à la bière d'avoir son caractère propre. Cela permet de garder un niveau d'huiles assez elevé dans le produit fini. Deuxièmement, les brasseurs de New England fermentent en utilisant une souche de levure d'origine anglaise. Ashton Lewis, l'éditeur technique de Brew Your Own précise « D'après des études ADN, la levure California Ale (White Labs WLP001, Wyeast 1056 et les autres souches de Chico) viendraient plutôt de Cologne, en Allemagne ». Ces souches américaines ont été choisies pour leur capacité à produire des bières claires, transparentes et amères sans ajouter de caractère. Les souches de levure utilisées par les brasseurs de New England IPA sont utilisées pour ajouter des esters, qui aident à produire le profil juteux de ces bières. Les IPAs brassées avec ces souches ne semblent pas être aussi transparentes que les souches Americaines lorsqu'elles sont exposées à des niveaux d'huiles elevés. Ceci vient en désaccord avec la plupart de la littérature sur les souches Anglaises. Si vous lisez la description de la plupart des souches de levures utilisées pour produire ces IPA troubles, la plupart sont considéeées « hautement floculantes », alors que la souche Chico, souvent utilisée pour les IPA de la cote Ouest annonce plutôt une floculation moyenne à faible. Pourquoi alors ces bières ne se clarifient pas lorsqu'elles sont sujettes à des hautes doses de houblon en fin d'ébullition ou en houblonnage à cru ? Cela reste encore une zone floue, j'ai donc demandé à quelques personnes dans l'industrie à propos de ce flou. Certains brasseurs pointent du doigt le fait que ces souches de levures floculent trop rapidement. Cela ne laisse pas le temps aux polyphénols de s'attacher aux levures, laissant ces composés ainsi que d'autres composés dérivés du houblon dans la solution plutôt que des les en enlever. Ashton Lewis nous rappelle aussi que le trouble trouvé dans les hefeweizen est principalement causé par les interactions entre les protéines et les polyphénols, et non pas par les levures.</p> +<p>Donc, quelles sont les souches de levure que vous devriez utiliser ? Le choix est en fait assez large, pour ceux qui souhaitent brasser ces types de American IPA, referez vous donc aux suggestions données dans les recettes jointes pour quelques idées.</p> +<h2>L'eau</h2> +<p>L'eau joue un rôle prépondérant dans le développement des New England IPA. Concentrez vous sur les niveaux de dureté de votre eau. Si vous avez une eau assez douce, alors vous avez un bon point de départ. Si vous avez une eau plutôt dure, obtenez un relevé d'eau (ndt: allez faire un tour sur le site « Eau du bassin Rennais » !). Si vous n'avez pas ces relevés d'eau, vous pouvez aussi faire analyser votre eau par des laboratoires, ou vous pouvez le faire vous même grâce à des kits de test de l'eau. Peu importe ce que vous choisissez, utiliser de l'eau distillée ou osmosée peut vous fournir une bonne base pour construire le profil d'eau que vous souhaitez obtenir. Essayez de garder votre niveau de bicarbonate en dessous de 50 PPM pour votre eau d’empâtage et votre eau de rinçage.</p> +<p>La prochaine chose sur laquelle se concentrer est vos sulfates et vos chlorures. Ceci est parfois controversé, mais encore une fois peut potentiellement être un facteur différenciant entre les IPA de la côte Est et les IPA de la côte Ouest. Quand j'ai commencé à jouer avec la composition de mon eau, j'ai traité l'eau de mes IPA pour atteindre un rapport 2:1 de sulfates / chlorures, ce qui s'est traduit par 100:50 PPM. J'ai produit plusieurs bières qui pouvaient rivaliser (selon moi) avec certaines que mes idoles produisaient. Mais, dans l'esprit du brassage amateur, j'ai continué à expérimenter. J'ai changé l'équilibre de sulfate / chlorures à 200:50PPM sans que je perçoive un changement. J'ai ensuite essayé 100:100 et trouvé que ça me plaisait un peu plus. Mes trouvailles ne sont pas la seule preuve anecdotique que booster le niveau de chlorures peut bénéficier à ce style de bières. Si vous cherchez à ajuster vos sulfates et for chlorures pour votre eau d'empâtage et de rincage, je vous encourage à jeter un oeil à l'article de Scott Janish du 7 Mars 2016 intitulé « Mouthfeel softness ». Scott y parle des effets négatifs d'un taux de sulfates elevé et des aspects positifs d'un niveau de chlorures elevé.</p> +<h2>Les houblons</h2> +<p>Généralement, l'amertume des houblons dans ce type d'IPA joue un rôle support, qui vient équilibrer le corps et la douceur des malts. Premièrement, gardez l'ajout de houblons amérisants modéré à faible. Vous pouvez expérimenter avec l'ajout de houblons amérisants mais je n'ai jamais eu l'occasion de trouver qu'une utilisation importante de houblons amérisants menait à une meilleure New-England IPA. Utilisez des houblons hauts en alpha tels que Magnum, Warrior™ ou Bravo si vous choisissez d'utiliser des houblons en cône ou en pellets, et je recommande de garder les ajouts d'amérisants assez faibles. D'habitude, j'essaye houblonner pour un rapport de 1:3 BU:GU (amertume sur densité). Cela signifie que quand je vise une densité cible de 1.066, l'ajout de houblons à 60mn est de 22 IBUs. Cela est fait pour éviter d'ajouter une dureté qui peut provenir d'une ébullition d'une quantité plus elevée de houblons. L'autre option est d'utiliser des extraits de houblon, qui peuvent contribuer les acides alpha nécessaires pour obtenir la bonne amertume, sans ajouter de polyphénols, que certains brasseurs pensent être à l'origine d'une certaine dureté.</p> +<p>Les ajouts de houblons en fin d'ébullition jouent un rôle beaucoup plus important pour la production de New-England IPA. Des apports copieux à la fin de l'ébullition ou au <em>flame-out</em> sont utiles pour tout type d'IPA hautement aromatique. Cela ajoutera des IBUs pour compléter votre apport en houblons amérisants et commencera à créer votre profil d'huiles. Je trouve que des variétés plus mordantes / piquantes comme le Simcoe®, Columbus, Chinook et Apollo fonctionnent bien à cette étape. Chaque brasseur semble trouver sa technique ici, qu'il s'agisse de faire plusieurs ajouts à 20mn ou moins puis de baisser à une température précise pour faire un <em>hop stand</em>, ou bien de simplement ajouter tous les houblons au <em>flame-out</em> et de les laisser durant 20 minutes ou plus. Il ne semble pas qu'il y ait de mauvaise manière de faire, juste plusieurs manières d'extraire les huiles essentielles des houblons à une température pas trop haute.</p> +<p>Le houblonnage à cru est votre prochain objectif. J'aimerais me concentrer sur les techniques plutôt que sur les quantités ou variétés puisque la technique semble être le plus important ici. Ceci dit, une chose est sure, ne soyez pas trop timide avec les ajouts durant le houblonnage à cru. 7.5g/L est certainement un bon point de départ. Vous pouvez ajuster en fonction de vos résultats. Les brasseurs Scott Janish et Michael Tonsmeir ajoutent que mettre ces bières en fûts à quelques avantages. Houblonner dans le fût, purger au CO2 et le fait de ne pas avoir de période prolongée de carbonatation sont déjà deux des avantages des fûts sur les bouteilles.</p> +<p>Alors, quand est le meilleur moment pour faire son houblonnage à cru ? Biern que ce ne soit pas une necessité, le fait de faire son houblonnage à cru en deux fois semble être un bon choix pour ce genre d'IPA. Prenez ce que vous pensiez ajouter lors du houblonnage à cru et séparez le en deux. Le premier ajout se fera durant la phase active de fermentation alors que le second se fera quand la fermentation se sera calmée et que les levures auront flocculées. Le premier ajout peut se faire à différents stades de la fermentation primaire; certains brasseurs les ajoutent au même moment qu'ils ensemencent, certains autres lorsque le krausen est haut, alors que la plupart l'ajoutent vers la fin de la fermentation. Je préfère faire le premier ajout une fois que le krausen est redescendu. Les hétérosides et les bio-transformations sont des éléments importants dans cette discussion à propos de comment la levure intéragit avec les huiles des houblons et les autres dérivés du houblon. Je trouve que les houblons ajoutés à la fin de l'ébullition vont apporter des caractéristiques similaires que les huiles de houblons ajoutés durant le ébut de la fermentation. Pour ce qui est du second ajout, l'objectif est d'attendre que la fermentation se soit calmée. Le timing n'est pas vraiment un facteur important ici, mais l'introduction d'oxygène est un point crutial. Prenez bien soin d'introduire le moins possible d'oxygène dans la bière à ce moment çi.</p> +<p>Dernièrement, quelque chose qui est nouveau pour moi: le houblonnage à cru sous pression. Cela vous demandera de l'équipement supplémentaire, principalement quelque chose apellée une « Spunding Valve». Il s'agit d'une valve qui permet de garder une certaine pression dans le fermenteur. Si la pression dépasse la valeur cible, alors la valve s'ouvre pour faire redescendre le fermenteur à la valeur souhaité. Mais, en quoi cela pourrait-être interéssant pour nous ? Parce que nous cherchons à garder un maximum de houblons aromatiques, en évitant d'en perdre. Les brasseurs amateurs ainsi que les brasseurs pros se sont penchés sur la question des spuinding valve de plus en plus dernièrement pour la fermentation primaire et pour le houblonnage à cru.</p> +<p>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.</p> +<p>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 !</p>Brasserie du Vieux Singe — Installation en cours.2017-06-26T00:00:00+02:002017-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-06-26:/brasserie-du-vieux-singe-installation-en-cours.html<p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour …</p><p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour être à portée de main.</p> +<p>La chose la plus frappante, c'est la vitesse à laquelle passent les journées: j'ai <em>vraiment</em> l'impression d'avoir quitté Mozilla hier. Si les collègues me +manquent, je ne ferais machine arrière pour rien au monde: je trouve finalement ce sens qui me manquait cruellement.</p> +<p>Après quelques hésitations au départ, j'ai décidé de mettre de côté mes activités liées à l'informatique: difficile à assumer quand on croise les copin.e.s avec qui on avait l'habitude de discuter énormement de ces sujets, mais ça permet de laisser plus de place pour l'humain. Plus de place pour les «Au fait, comment ça va toi ?» quand j'ai l'occasion de les recroiser, ce qui n'est pas plus désagréable :)</p> +<p>Les journées sont donc organisées autour de la brasserie: beaucoup plus de planification que ce que j'imaginais au départ. Peut-être que c'est aussi du au fait que nous soyons tous les deux des ex-informaticiens un peu perfectionnistes sur les bords. On se voit très souvent pour avancer sur des sujets de fond tout comme sur du pratico-pratique. Pour vous donner un ordre d'idée des questionnements: Quelle taille d'entreprise ? Quelles valeurs communes ? Quelles bières ? Quelle image donner ? Quelle place donner au confort ? Comment éviter la compétitivité ? Comment réussir à impacter les producteurs (houblon / malt) de manière positive ? Quels salaires se donner ?</p> +<p>Un peu de production quand même (pour les amis) mais on se garde la grosse partie pour le lancement.</p> +<h2>Apprentissage</h2> +<p>Je profite de ces quelques mois pour apprendre: autour de la fabrication et de la dégustation de bière bien sûr (encore un milieu en constante évolution !), mais pas que. J'ai maintenant quelques bases de gestion d'entreprise, en comptabilité, en biologie et en chimie. J'ai bien dit quelques <em>bases</em>, mais qu'est-ce que c'est agréable !</p> +<p>C'est assez agréable de se remettre dans une posture d'apprenant, et d'avoir le temps pour cet apprentissage.</p> +<h2>Questionner la posture de «Chef d'entreprise» et son rapport au temps</h2> +<p>Décider de créer sa boîte, c'est aussi se poser la question de comment organiser son temps: combien de temps travailler ? Quel temps donner aux loisirs ?</p> +<p>Je trouve rassurant de voir ces interrogations abordées avant-même le démarrage de l'entreprise. La plupart des personnes qui nous suivent et nous guident partent du postulat qu'il faudra bosser énormement, là ou nous essayons de trouver un modèle qui soit viable dans le temps, notre souhait est de bosser à 80% (4 jours par semaine).</p> +<p>Certes, il faut travailler pour que ça tourne, mais il faut aussi s'accorder des temps de respiration pour être d'autant plus efficace quand on bosse. C'est d'autant plus intéressant de prévoir ces aspects lors de la phase de <em>design</em> de l'activité: on organise le temps autrement ! Ceux qui me lisent de temps à autre savent que c'est une constante de mes réflexions, on verra si ça fonctionne dans les faits.</p> +<h2>Les projets collectifs</h2> +<p>Un autre point important est la place que le <em>collectif</em> prends dans cette nouvelle expérience. Au départ, quand j'imaginais le projet sur le court-terme, je mettais la composante collective au second plan dans l'immédiat (au delà des intéractions avec Fred, mon associé). L'occasion de travailler à la construction d'un espace collectif s'est présentée, et on y travaille actuellement.</p> +<p>C'est à la fois riche (en partage de points de vue, en entre-aide) et à la fois difficile (beaucoup d'heures de réunions, il faut apprendre à communiquer de manière efficace, il faut parfois faire face à des conflits). Dans l'ensemble, je ne regrette pas ce choix même si il est important de ne pas perdre de vue les objectifs de la brasserie dans l'histoire.</p> +<p>Et puis la collaboration ne s'arrête pas qu'au collectif d'activité: le milieu brassicole est en mutation, et les valeurs de partage font bel et bien partie du lot de changements. Les rencontre avec les brasseurs du coin de Rennes le montrent bien: l'esprit est plus à l'entraide qu'à la concurrence, au vu de la demande qui est toujours croissante. Tant mieux, on a autre chose à faire qu'à se tirer dans les pâtes ;)</p> +<h2>Besoin de concret</h2> +<p>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…</p> +<p>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 ?</p>Comment est-ce que vous générez vos formulaires ?2016-05-31T00:00:00+02:002016-05-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.html<p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est …</em></p><p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est passé par pas mal d'é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'organisateurs d'é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'est +pas libre et que les données sont stockées chez 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'ils puissent y répondre. +Je reviens ensuite plus tard pour voir la liste des réponses apportées.</p> +<p><img alt="Capture de l'interface de création du formulaire" src="{filename}/static/formbuilder-build.png"></p> +<h2>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'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 à +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'opération terminée.</p> +<p><img alt="Capture de l'écran avec les URLs générées" src="{filename}/static/formbuilder-created.png"> +<img alt="Capture d'écran d'un exemple de formulaire" src="{filename}/static/formbuilder-form.png"></p> +<h3>Pas de compte</h3> +<p>Vous n'avez pas besoin d'avoir un compte sur le site pour commencer à l'utiliser. +Vous créez simplement un nouveau formulaire puis envoyez le lien à vos amis pour +qu'eux puissent à leur tour le remplir.</p> +<p><img alt="Capture de la page d'accueil, ou aucun compte n'est requis" src="{filename}/static/formbuilder-welcome.png"></p> +<h3>Gardez la main sur vos 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="{filename}/static/formbuilder-results.png"></p> +<h3>API</h3> +<p>L'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 HTTP. Ce qui fait qu'il est très facile de +réutiliser les formulaires que vous avez construits (ou leurs réponses) depuis +d'autres outils.</p> +<h3>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'instance qui est mise à votre disposition sur +<a href="https://www.fourmilieres.net">wwww.fourmilieres.net</a>, mais vous pouvez +également l'héberger vous même très +simplement, et vous êtes d'ailleurs fortement encouragés à le faire ! Notre +objectif n'est pas de stocker l'ensemble des formulaires du monde, mais de +(re)donner le contrôle aux utilisateurs !</p> +<h2>On commence petit…</h2> +<p>Cette <em>release</em> n'est (bien sur) pas parfaite, et il reste encore pas mal de +travail sur cet outil, mais je pense qu'il s'agit d'une base de travail +intéressante pour un futur où Google n'a pas la main sur toutes nos données.</p> +<p>La liste des champs supportés est pour l'instant assez faible (Texte court, +Texte long, Oui/Non, choix dans une liste) mais elle à vocation à s'étendre, en +fonction des besoins de chacun.</p> +<p>J'ai d'ailleurs créé <a href="https://www.fourmilieres.net/#/form/cfd878264cec4ed2">un formulaire pour que vous puissiez me faire part de vos +retours</a>, n'hésitez pas !</p> +<h2>Et, euh, comment ça marche ?</h2> +<p>Le <em>formbuilder</em>, comme j'aime l'appeler se compose en fin de compte de deux +parties 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 HTTP</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'envoyer les données sur les <em>APIs</em> coté + 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'il génère en fin de compte du +<a href="http://jsonschema.net/">JSON Schema</a>, un format de validation de données <em>JSON</em>.</p> +<p>Donc, reprenons! Vous arrivez sur la page d'accueil puis cliquez sur +"Create a new form", puis vous vous retrouvez face à une interface ou vous pouvez +ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez sur +"Create the form".</p> +<ul> +<li>Le JSON Schema est alors envoyé au serveur Kinto, qui l'utilisera pour valider + les données qu'il recevra par la suite.</li> +<li>Ce JSON Schema sera aussi utilisé lors de l'affichage du formulaire aux + personnes qui le remplissent.</li> +<li>Un jeton d'accès est généré et ajouté à l'URL, il s'agit de l'identifiant du + formulaire.</li> +<li>Un second jeton d'accès administrateur et généré, il vous faut le garder de + coté pour avoir accès aux 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 !</p>Cloisonnement des activités ?2016-05-29T00:00:00+02:002016-05-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-29:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en …</p><p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en faire +un plaisir. Oh, et des fois on parle un peu de technique aussi.</p> +<h1>Alors, brasserie ou code ?</h1> +<p>Ces quelques jours ont été fort inspirants. Alors que je suis en train de +changer de métier (vers celui de brasseur) c'était un moyen de me rendre compte +que bien que je ne souhaite plus faire du Web mon métier <em>la, tout de suite, +maintenant</em>, je reste un passionné par la chose.</p> +<p>En partant de Rennes, je ne savais pas trop quoi penser de cette situation. +Prendre un week-end pour échanger avec les gens sur quelque chose dont je +m'éloigne ? C'est pas une perte de temps ?</p> +<p>Si je passe du temps à écrire des bouts de code, des logiciels, à reflechir +à comment solutionner certains problemes, ce n'est pas parce que je suis payé +pour le faire, mais bel et bien parce que je me sens bien lorsque je le fais, +parce que j'y trouve un équilibre et une utilité.</p> +<p>Alors que je ne trouvais plus cet équilibre dans mon travail, j'ai choisi d'en +changer, mais il n'empèche que je continue à avoir des rèves d'un +monde meilleur, dans lequel l'informatique a sa place. Juste à voir les +discussions (ux, sécurité informatique, décentralisation, architecture +logicielle) que j'ai pu avoir ce weekend, il n'y a pas l'ombre d'un doute !</p> +<p>Jusqu'ici je me suis dit que je devais choisir. J'ai pensé naivement +que je ne pouvais pas être <em>et</em> un brasseur <em>et</em> un developpeur, mais la +réalité c'est que c'est exactement ce que je suis: les deux.</p> +<p>Je ne suis pas pour autant dupe sur le temps necessaire à lancer une activité +brassicole, il va falloir fournir de l'énergie et avancer sur le projet, mais +il n'empèche que même si je décide de faire de la bière mon metier, mes +passions pour le reste sont bien vivantes.</p> +<p>Bref, merci sudweb pour m'avoir accompagné dans ces reflexions, à l'année +prochaine, je ramène des futs ?</p>Avez vous confiance en SSL?2016-03-25T00:00:00+01:002016-03-25T00:00:00+01:00Alexis Métaireautag: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'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop …</p><p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop, c'est parti pour:</p> +<ul> +<li>un tour d'horizon du fonctionnement de SSl</li> +<li>quelques moyens contourner cette "protection" en faisant une attaque en pratique</li> +<li>un tour des solutions existantes actuellement et de pourquoi je ne les trouve + pas vraiment satisfaisantes.</li> +</ul> +<h2>Comment fonctionne SSL?</h2> +<p>Pour expliquer les problèmes de SSL, j'ai d'abord besoin d'expliquer comment +tout ça fonctionne.</p> +<p>SSL repose sur l'utilisation de certificats, qui sont générés par des autorités +de certification (<em>Certificate Authority</em> que je nomme <em>CA</em> dans la suite de +l'article).</p> +<p>Les certificats SSL permettent deux 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 même.</li> +<li>De garantir que le site sur lequel vous vous connectez est bien celui que + vous imaginez.</li> +</ul> +<p>Le navigateur, lors d'une visite d'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>CA</em> en qui il a confiance.</p> +<p>Imaginons maintenant qu'une des <em>CA</em> essaye de savoir ce qui s'échange entre +mon navigateur et le site de ma banque (protégé par SSL). Comment cela se +passerait il ?</p> +<p>N'importe quel <em>CA</em> peut donc générer des certificats pour n'importe quel site, +et le navigateur vérifierait, lui, que le certificat a bien été généré par une +<em>CA</em>.</p> +<p>Tout cela ne poserait pas de soucis si les <em>CA</em> étaient gérés de manière fiable, +mais il s'agit d'un travail compliqué, et certains <em>CA</em> ont par le passé montré +des faiblesses.</p> +<p>Par exemple, <a href="https://en.wikipedia.org/wiki/DigiNotar">DigiNotar</a> (un <em>CA</em> des Pays-Bas) +a été compromise et les attaquant.e.s ont pu générer des certificats SSL +frauduleux, ce qui leur a permis d'attaquer des sites tels que Facebook ou GMail.</p> +<p>Vous pouvez retrouver une liste des risques et menaces autour des <em>CA</em> <a href="http://wiki.cacert.org/Risk/History">sur le +wiki de CACert</a>.</p> +<h2>Attaque de l'homme du milieu avec SSL</h2> +<p>A force de dire que c'était très facile à faire, j'ai eu envie d'essayer +d'espionner des connections protégées par SSL, et effectivement c'est +carrément flippant tellement c'est simple.</p> +<p>En l'espace de quelques minutes, il est possible de faire une <em>attaque de +l'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'ensemble du trafic SSL, j'ai simplement eu à lancer quelques +commandes et avoir un <em>CA</em> dans lequel le navigateur de la victime a confiance. +Je l'ai ajouté dans le navigateur cible pour simuler que je l'avais déjà +(c'est le cas si un des 1200 CA se fait pirater, ce qui me semble une surface +d'attaque assez large).</p> +<p>Je les colle ici si ça vous intéresse:</p> +<div class="highlight"><pre><span></span>$ sudo aptitude install mitmproxy +$ mitm-proxy -T --host +</pre></div> + + +<p>Il faut faire croire à votre victime que vous êtes la passerelle vers +l'extérieur et à la passerelle que vous êtes la victime:</p> +<div class="highlight"><pre><span></span>arpspoof -i wlan0 -t victime gateway +arpspoof -i wlan0 -t gateway victime +</pre></div> + + +<p>Puis dire à notre fausse passerelle de rediriger le trafic des ports 80 et 443 +vers notre proxy:</p> +<div class="highlight"><pre><span></span>sudo sysctl -w net.ipv4.ip_forward<span class="o">=</span><span class="m">1</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">443</span> -j REDIRECT --to-port <span class="m">4443</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">80</span> -j REDIRECT --to-port <span class="m">4443</span> +</pre></div> + + +<p>Et paf, <strong>on voit tout ce qui passe entre la machine et le serveur SSL</strong>. On peut +d'ailleurs même imaginer faire tourner ces quelques commandes sur un +raspberry pi, pour aller encore plus vite…</p> +<h3>Key-pinning dans les navigateurs</h3> +<p>Actuellement, n'importe quel <em>CA</em> peut générer des certificats pour +n'importe quel site, et c'est en grande partie ce qui pose souci. Une des +manières de faire évoluer la situation est d'épingler les certificats de +certains sites directement dans les 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>HTTP Public Key Pinning (HPKP)</h3> +<p><a href="https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning"><em>HTTP Public Key Pinning</em></a> +est également une solution de <em>pinning</em> qui permet d'établir une confiance lors +de la première connexion avec le site. C'est ce qu'on appelle du <em>Trust on First +Use</em> ou <em>TOFU</em>.</p> +<p>Le navigateur va alors mettre ces informations dans un cache et vérifiera que +les certificats correspondent bien lors des prochaines visites.</p> +<p><em>HPKP</em> est disponible dans Firefox depuis Janvier 2015 et dans Chrome +depuis Octobre 2015.</p> +<h3>Certificate transparency: des journaux 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 SSL certificates open to scrutiny by +domain owners, CAs, and domain users.</p> +<p>-- <a href="https://www.certificate-transparency.org/what-is-ct">Certificate Transparency</a></p> +</blockquote> +<p>Autrement dit, avec ce système les <em>CA</em> doivent rendre public le fait qu'ils +aient signé de nouveaux certificats intermédiaires. La signature est ajoutée à +un journal sur lequel il n'est possible que d'écrire.</p> +<p>Les navigateurs vont alors vérifier que les certificats utilisés sont bien des +certificats qui ont été ajoutés au journal.</p> +<p>Ici, toute l'intelligence est dans la vérification de ces journaux, qui +permettent donc de valider/invalider des certificats racines ou intermédiaires.</p> +<p>Il me semble donc qu'il serait possible d'ajouter un certificat frauduleux le +temps d'une attaque (et celui ci serait détecté et supprimé ensuite).</p> +<p><em>Certificate-Transparency</em> n'est donc pas une solution contre une écoute +globale mise en place par les gouvernements par exemple.</p> +<p>Si vous lisez bien l'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 écrite.</p> +<h3>DANE + DNSSEC</h3> +<blockquote> +<p>The DANE working group has developed a framework for securely +retrieving keying information from the DNS [RFC6698]. This +framework allows secure storing and looking up server public key +information in the DNS. 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 service.</p> +<p>-- <a href="https://datatracker.ietf.org/wg/dane/charter/">Dane WG</a></p> +</blockquote> +<p>Une autre solution est appelée "DANE" et repose par dessus le protocole +<em>DNSSEC</em>.</p> +<p>Je connais assez mal <em>DNSSEC</em> donc j'ai passé un peu de temps à lire des +documents. L'impression finale que ça me laisse est que le problème est +exactement le même que pour SSL: 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 confiance.</p> +<blockquote> +<p>Secure DNS (DNSSEC) uses cryptographic digital signatures signed with a +trusted public key certificate to determine the authenticity of data. +-- https://en.wikipedia.org/wiki/DNS_spoofing</p> +</blockquote> +<p>Et aussi:</p> +<blockquote> +<p>It is widely believed[1] that securing the DNS is critically important for +securing the Internet as a whole, but deployment of DNSSEC specifically has +been hampered (As of 22 January 2010) by several difficulties:</p> +<ul> +<li>The need to design a backward-compatible standard that can scale to the + size of the Internet</li> +<li>Prevention of "zone enumeration" (see below) where desired</li> +<li>Deployment of DNSSEC implementations across a wide variety of DNS servers + and resolvers (clients)</li> +<li>Disagreement among implementers over who should own the top-level domain + root keys Overcoming the perceived complexity of DNSSEC and DNSSEC + deployment</li> +</ul> +</blockquote> +<h2>Solutions basées sur la blockchain</h2> +<p>Une dernière piste semble être l'utilisation de la <em>blockchain</em> pour distribuer +des clés par site.</p> +<p>La solution <em>DNSChain</em> me paraissait tout d'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'ont fait changer d'avis.</p> +<p>Reste encore la piste de <em>Namecoin Control</em> que je n'ai pas encore creusée. +Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la +bienvenue sur ces sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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><p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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, away from news and +agitation.</p> +<p>Working remotely is sometimes hard. Hard because you need to at the same time +be in the discussions channels and work on the interesting projects. A real +myth.</p> +<p>In practice, I'm really bad at multi-tasking. I tried a few times the <em>Pomodoro</em> +technique, which forces me to focus on a task for 25mn, but this split of my day +into slices of 25mn breaks my natural flow.</p> +<p>So, what do I need? I tried to change my tools, it helped a bit. Still, I'm not +focused like I would like to be.</p> +<p>Maybe that's just me who needs some more persuasion over myself, but the best +way I found to work is to unplug the cable. Literally. At work, at some point I +was using a RJ45 cable to connect to the Internet. When I wanted to work on +something, I could just unplug this cable.</p> +<p>And that's amazing how you find yourself in the process to &quot;check&quot; +something on the web. Mails, irc… well, you got the idea. You're litterally, +without even noticing, switching to your browser an opening a new tab…</p> +<p>Of course, that Web isn't filled only with lolcats and twitter messages +(even if I would <strong>love</strong> to see a pie chart with the repartition of lolcats +VS the rest of the web's content), so sometimes you need some precious bit of +information that's there. Fair enough. plug the cable, do what you <strong>need</strong> to +do, and unplug. Alexis, unplug!</p> +<p>It also helps to have some fair bit of documentation available directly on my +machine (I used to have the python docs, I should get it back!)</p> +<p>I'm feeling adventurous, so I'll try something new starting tomorrow, and I'll +report back in here my findings. Here's the challenge:</p> +<ul class="simple"> +<li><strong>Check emails only once a day</strong>. Do <strong>not</strong> do it in the morning, before +working, to keep my mind clear. I would say at 2pm (after lunch). +(This doesn't mean I will not send mails tho)</li> +<li>Stay away from the Internet during the morning. I'll not connect if I don't +need to.</li> +</ul> +<p>Let's see how it goes :)</p> +Retours sur un atelier ZeroNet2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag: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'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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 …</p><p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> +dans les locaux de l'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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'éviter la censure.</p> +<p>Avant toute autre chose, merci énormément à l'équipe de la bibliothèque de +l'INSA pour l'organisation de cet évènement qui à une réelle portée politique.</p> +<h2>Un peu d'histoire</h2> +<p>Il me semble que Tim Bernes Lee (l'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 accéder.</p> +<p>Avec ce fonctionnement, impossible alors d'accéder à des sites si leur auteur +n'est pas en ligne. Qu'à cela ne tienne, on s'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'utilisateurs des sites.</p> +<h2>Un Web 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'une visite d'un +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 site.</li> +<li>Vous validez que les fichiers servis sont bien les bons (en vérifiant la + signature attachée).</li> +</ol> +<p>N'importe quel visiteur devient alors un <em>pair</em>, qui sert le site aux autres +visiteurs.</p> +<p>Parmi les nombreux avantages de cette approche, je note particulièrement que:</p> +<ul> +<li>Il est très difficile de censurer un site — Il est sur l'ensemble des machines + des visiteurs.</li> +<li>Les attaques par <em>fingerprinting</em> sont impossibles: le navigateur Web se + connecte à un serveur <em>proxy</em> local.</li> +<li>Vous détenez directement vos données et (par design) ne les donnez pas à des + silos (Facebook, Google, etc.)</li> +</ul> +<p>Si vous êtes interessés par une démonstration rapide, j'ai enregistré une vidéo +de 10 minutes où je parle en anglais avec une voix très grave.</p> +<video controls="" src="http://alexis.notmyidea.org/zeronet.webm" width=800></video> + +<h2>Atelier</h2> +<p>Pour l'atelier, j'ai choisi de faire une présentation rapide du projet (<a href="{filename}/static/zeronet-presentation-fr.pdf">j'ai +traduit les slides</a> anglais +pour l'occasion — <a href="https://docs.google.com/presentation/d/158C_-V1ueNaaKHMBMBgGOVhunb9xrXzB3hC_g1N53c0/edit?usp=sharing">accès aux sources</a>) +avant d'installer ZeroNet sur les machines et de l'utiliser pour publier un +site.</p> +<h3>Partager sur le réseau 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'avais pas prévu le coup.</p> +<p>Voici donc comment faire pour contourner le 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'est packagé pour debian pour l'instant</a>) + J'ai choisi d'installer <a href="http://erdgeist.org/arts/software/opentracker/#build-instructions">OpenTracker</a></li> +<li>Ensuite lancer ZeroNet avec des options spécifiques.</li> +</ol> +<div class="highlight"><pre><span></span>$ python zeronet.py --trackers udp://localhost:6969 --ip_external <span class="m">192</span>.168.43.207 +$ python zeronet.py --trackers udp://192.168.43.207:6969 --ip_external <span class="m">192</span>.168.43.172 +</pre></div> + + +<p>Il est nécessaire de spécifier l'adresse IP externe que chaque nœud expose pour +éviter qu'elle n'essaye d'aller la trouver par elle même: nous voulons l'adresse +du réseau local, et non pas l'adresse internet.</p> +<p>La prochaine fois je tenterais de venir avec un HotSpot Wifi et un tracker +BitTorrent dans la poche!</p> +<h2>Questions / Réponses</h2> +<p>Il y avait quelques questions intéressantes auxquelles je n'ai pas toujours su +répondre sur le moment. Après quelques recherches, je rajoute des détails ici.</p> +<h3>Torrent + Tor = brèche de sécu ?</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'utilisation de BitTorrent par dessus Tor</a>.</p> +<blockquote> +<p>Dans certains cas, certains clients torrents (uTorrent, BitSpirit, etc) +écrivent directement votre adresse IP dans l'information qui est envoyée +au tracker et/ou aux autres pairs. +— 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'est pas le cas de ZeroNet</a>, ce qui évacue le souci.</p> +<h3>ZeroMail, c'est lent non ?</h3> +<p>Une des applications de démo, <em>ZeroMail</em>, propose un mécanisme qui permet de +s'envoyer des messages chiffrés sur un réseau pair à pair. L'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 siens.</p> +<p>Cela permet de ne <strong>pas</strong> fuiter de méta-données, <a href="{filename}../crypto/2015.05.pgp-problemes.rst">à l'inverse de PGP</a>.</p> +<p>Je n'ai en fait pas de réponse claire à donner à cette question: l'auteur de +ZeroNet me disait que 10MB (la limite de taille d'un site, par défaut) +correspondait à beaucoup de place pour stocker des messages, et qu'il était +possible de supprimer les anciens messages une fois qu'ils sont lus par 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'un +utilisateur peut recevoir.</p> +<p>Je vois plusieurs problèmes avec le design actuel de ZeroMail (il me semble +assez facile d'y faire un déni de service par exemple). A creuser.</p> +<h3>Comment héberger des très gros sites ?</h3> +<p>Par exemple, comment faire pour héberger Wikipedia ?</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 demande)</p> +<h3>Est-ce qu'on à vraiment besoin d'un tracker ?</h3> +<p>Le support d'une DHT <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, +mais pour l'instant pas encore implémenté. L'utilisation de la DHT BitTorrent +n'est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas UDP</a>.</p>L'horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-02:/lhorizon.html<blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont …</p><blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont +eu lieu juste avant une descente de cave en Bourgogne avec Tarek pour +y déguster quelques saveurs de vins différentes.</p> +<p>Quatre ans plus tard, je me retrouve à coder sur Daybed, mon petit projet +perso, devenu <a class="reference external" href="http://kinto.readthedocs.org/">Kinto</a> avec une équipe de +personnes plus talentueuses et sympathiques les unes que les autres (Niko, +Rémy, Mat, si vous me lisez…).</p> +<p>Mozilla a bien évolué en quelques années: les petits bureaux ou j'avais atterri +se sont transformés en palace où il est possible d'accueillir des membres de la +communauté du logiciel libre de manière quotidienne.</p> +<p>De 14 personnes dans les bureaux Parisiens, nous sommes passés à une 40aine (et +de ~500 salariés à 1100 dans le monde).</p> +<p>Grandir autant en si peu de temps est un challenge difficile à tenir, qui +nécessite des réorganisations et bien souvent dans une structure de cette +taille, de la hiérarchisation. En 4 ans j'ai eu au moins 5 changements de +supérieurs, pour finalement arriver à une situation plutôt convenable (mais +quand même !)</p> +<p>J'ai choisi de rejoindre Mozilla parce que j'ai besoin de causes à défendre, +qui me saisissent et qui me guident. Aujourd'hui, une des visions qui m'anime, +c'est celle que d'autres ont déjà ouverte: celle de données et de vie privée +qui sont rendues à leurs utilisateurs.</p> +<p>Et je veux faire en sorte de réaliser ces «rêves d'un monde meilleur», ce qui +veut dire pour moi qu'il est temps de partir vers des horizons plus propices +à cette vision.</p> +<p>Lesquels ? Cela reste à construire (mais je vous le dis, y'a du Kinto dedans !)</p> +<div class="section" id="la-suite"> +<h2>La suite ?</h2> +<p>Sans m'étaler, je veux prendre du temps pour quelques projets autour du +stockage de données (via Kinto), de l'auto défense numérique (via des +formations) et de la fabrication de bière artisanale (parce que bon, on se +refait pas !)</p> +<p>Évidemment, plein d'envies diverses et variées, envie de me balader un peu et +d'expérimenter des choses collectivement...</p> +<p>On se recroisera surement :)</p> +</div> +Let's Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début …</p><blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début Décembre, la nouvelle <em>autorité de certification</em> Let's Encrypt +est passée en version <em>Beta</em>. Les certificats SSL sont un moyen de 1. chiffrer la +communication entre votre navigateur et le serveur et 2. un moyen d'être sur +que le site Web auquel vous accédez est celui auquel vous pensez vous connecter +(pour éviter des <a class="reference external" href="https://fr.wikipedia.org/wiki/Attaque_de_l'homme_du_milieu">attaques de l'homme du milieu</a>).</p> +<p>Jusqu'à maintenant, il était nécessaire de payer une entreprise pour faire en +sorte d'avoir des certificats qui évitent d'avoir ce genre d'erreurs dans vos +navigateurs:</p> +<img alt="Message de firefox lorsque une connexion n'est pas sécurisée." src="{filename}/static/unsecure-connection.png" /> +<p>Maintenant, grâce à Let's Encrypt il est possible d'avoir des certificats SSL +<strong>gratuits</strong>, ce qui représente un grand pas en avant pour la sécurité de nos +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 SSL valides avec Let's Encrypt et +le répartiteur de charge <a class="reference external" href="http://www.haproxy.org/">HAProxy</a>.</p> +<p>Je me suis basé pour cet article sur d'<a class="reference external" href="https://blog.infomee.fr/p/letsencrypt-haproxy">autres</a> <a class="reference external" 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 d'information.</p> +<div class="section" id="validation-des-domaines-par-let-s-encrypt"> +<h2>Validation des domaines par Let's Encrypt</h2> +<p>Je vous passe les détails d'installation du client de Let's Encrypt, qui sont +<a class="reference external" 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 à:</p> +<pre class="literal-block"> +letsencrypt-auto certonly --renew-by-default +--webroot -w /home/www/letsencrypt-requests/ \ +-d hurl.kinto-storage.org \ +-d forums.kinto-storage.org +</pre> +<p>Le <em>webroot</em> est l'endroit ou les preuves de détention du domaine vont être +déposées.</p> +<p>Lorsque les serveurs de Let's Encrypt vont vouloir vérifier que vous êtes bien +à l'origine des demandes de certificats, ils vont envoyer une requête HTTP sur +<tt class="docutils literal"><span class="pre">http://domaine.org/.well-known/acme-challenge</span></tt>, ou il voudra trouver des +informations qu'il aura généré via la commande <tt class="docutils literal"><span class="pre">letsencrypt-auto</span></tt>.</p> +<p>J'ai choisi de faire une règle dans haproxy pour diriger toutes les requêtes +avec le chemin <tt class="docutils literal"><span class="pre">.well-known/acme-challenge</span></tt> vers un <em>backend</em> nginx qui sert +des fichiers statiques (ceux contenus dans +<tt class="docutils literal"><span class="pre">/home/www/letsencrypt-requests/</span></tt>).</p> +<p>Voici la section de la configuration de HAProxy (et <a class="reference external" href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L63-L72">la configuration +complete</a> +si ça peut être utile):</p> +<pre class="literal-block"> +frontend http + bind 0.0.0.0:80 + mode http + default_backend nginx_server + + acl letsencrypt_check path_beg /.well-known/acme-challenge + use_backend letsencrypt_backend if letsencrypt_check + + redirect scheme https code 301 if !{ ssl_fc } !letsencrypt_check + +backend letsencrypt_backend + http-request set-header Host letsencrypt.requests + dispatch 127.0.0.1:8000 +</pre> +<p>Et celle de NGINX:</p> +<pre class="literal-block"> +server { + listen 8000; + server_name letsencrypt.requests; + root /home/www/letsencrypt-requests; +} +</pre> +</div> +<div class="section" id="installation-des-certificats-dans-haproxy"> +<h2>Installation des certificats dans HAProxy</h2> +<p>Vos certificats SSL devraient être générés dans <tt class="docutils literal">/etc/letsencrypt/live</tt>, mais +ils ne sont pas au format attendu par haproxy. Rien de grave, la commande +suivant convertit l'ensemble des certificats en une version compatible avec +HAProxy:</p> +<pre class="literal-block"> +cat /etc/letsencrypt/live/domaine.org/privkey.pem /etc/letsencrypt/live/domaine.org/fullchain.pem &gt; /etc/ssl/letsencrypt/domaine.org.pem +</pre> +<p>Et ensuite dans la configuration de haproxy, pour le (nouveau) <em>frontend</em> https:</p> +<pre class="literal-block"> +bind 0.0.0.0:443 ssl no-sslv3 crt /etc/ssl/letsencrypt +</pre> +<p>Faites bien attention à avoir un <em>frontend</em> <cite>https</cite> pour tous vos sites en HTTPS. +<a class="reference external" 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 !</p> +</div> +<div class="section" id="automatisation"> +<h2>Automatisation</h2> +<p>Pour automatiser un peu tout ça, j'ai choisi de faire ça comme suit:</p> +<ul class="simple"> +<li>Un fichier domaine dans <tt class="docutils literal">letsencrypt/domains/domain.org</tt> qui contient le script <tt class="docutils literal">letsencrypt</tt>.</li> +<li>Un fichier d'installation de certificats dans +<tt class="docutils literal"><span class="pre">letsencrypt/install-certs.sh</span></tt> qui s'occupe d'installer les certificats +déjà générés.</li> +</ul> +<p>Et voila ! <a class="reference external" href="https://github.com/almet/infra/">Le tout est dans un dépot github</a>, si jamais ça peut vous servir, tant mieux !</p> +</div> +Ateliers d'autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de …</li></ul></blockquote><p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, +envers mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins +pour rendre le déchiffrement des messages plus longue, &quot;noyer le +poisson&quot;.</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="http://blog.notmyidea.org/chiffrement.html">Chiffrement</a></p> +</blockquote> +<p>J'ai mis un peu de temps à mettre le pied à l'étrier, mais je ressors +finalement du premier atelier que j'ai co-animé avec geb, auprès d'un public de +journalistes.</p> +<p>Pour cette première édition l'idée était à la fois d'aller à la rencontre d'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'autodéfense numérique.</p> +<p>L'objectif pour ce premier atelier était de:</p> +<ol class="arabic simple"> +<li>Échanger autour des besoins et <strong>faire ressortir des histoires</strong> ou le manque +d'outillage / connaissances à posé problème, dans des situations concrètes;</li> +<li>Se rendre compte des &quot;conduites à risque&quot;, <strong>faire peur</strong> aux personnes formées +pour qu'elles se rendent compte de l'état actuel des 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 appréhender.</li> +</ol> +<div class="section" id="faire-ressortir-les-problemes"> +<h2>1. Faire ressortir les 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 &quot;Groupes d'Interview Mutuels&quot;, +ou &quot;GIM&quot;:</p> +<blockquote class="epigraph"> +<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é vécu.</p> +<p class="attribution">&mdash;«<a class="reference external" href="http://www.scoplepave.org/pour-s-ecouter">Pour s'écouter</a>», SCOP Le Pavé.</p> +</blockquote> +<p>De ces <em>GIMs</em> nous avons pu ressortir quelques histoires, gravitant autour de:</p> +<ul class="simple"> +<li><strong>La protection des sources (d'information)</strong>: Comment faire pour aider +quelqu'un à faire &quot;fuiter&quot; des données depuis l'intérieur d'une entreprise ?</li> +<li><strong>Le chiffrement de ses données</strong>: Comment éviter de faire &quot;fuiter&quot; des données +importantes lors d'une perquisition de matériel ?</li> +</ul> +</div> +<div class="section" id="faire-peur"> +<h2>2. Faire 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'accéder à certaines données. <a class="reference external" href="http://blog.barbayellow.com/">Grégoire</a> m'avait conseillé quelques petites accroches +qui ont ma foi bien marché:</p> +<p>J'ai demandé aux présent.e.s de:</p> +<ul class="simple"> +<li>donner leur mot de passe à voix haute devant les autres: a priori personne ne +le fera;</li> +<li>venir se connecter à leur compte email depuis mon ordinateur. J'ai piégé une +personne, qui est venu pour taper son mot de passe.</li> +</ul> +<p>Cela à été un bon moyen de parler de l'importance des traces que l'on peut +laisser sur un ordinateur, et de la confiance qu'il faut avoir dans le matériel +que l'on utilise, à fortiori si ce ne sont pas les vôtres.</p> +<p>Pour continuer à leur faire peur, après une brève explication de ce qu'est SSL +nous avons montré comment il était facile de scruter le réseau à la recherche +de mots de passe en clair.</p> +</div> +<div class="section" id="proposer-des-solutions-concretes"> +<h2>3. Proposer des solutions concrêtes</h2> +<p>Une fois que tout le monde avait pleinement pris sonscience des problématiques +et n'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 attentes:</p> +<ul class="simple"> +<li>On a expliqué ce qu'était <a class="reference external" href="https://tails.boum.org">Tails</a>, et comment +l'utiliser et le dupliquer.</li> +<li>On a pu faire un tour des outils existants sur Tails, notamment autour de +l'<em>anonymisation</em> de fichiers et la suppression effective de contenus.</li> +<li>Certaines personnes ont pu créer une clé tails avec la persistance de +configurée.</li> +<li>Nous nous sommes connectés au réseau <a class="reference external" href="https://www.torproject.org">Tor</a> et testé +que nos adresses IP changeaient bien à la demande.</li> +<li>Nous avons utilisé <a class="reference external" href="https://crypto.cat">CryptoCat</a> par dessus Tor, afin de +voir comment avoir une conversation confidentielle dans laquelle il est +possible d'échanger des fichiers.</li> +</ul> +</div> +<div class="section" id="retours"> +<h2>Retours</h2> +<p>D'une manière générale, pour une formation de trois heures et demi, je suis +assez content de l'exercice, et de l'ensemble des sujets que nous avons pu +couvrir. Il y a beaucoup de place pour l'amélioration, notamment en amont (j'avais +par exemple oublié d'amener avec moi suffisamment de clés USB pour utiliser +Tails).</p> +<p>La plupart des retours qu'on a pu avoir jusqu'à maintenant sont positifs, et il +y a l'envie d'aller plus loin sur l'ensemble de ces sujets.</p> +</div> +<div class="section" id="la-suite"> +<h2>La suite</h2> +<p>Il y a beaucoup de sujets que nous n'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'après-midi par +exemple).</p> +<p>J'ai choisi volontairement de ne pas aborder le chiffrement des messages via +PGP parce que <a class="reference external" href="https://blog.notmyidea.org/les-problemes-de-pgp.html">je pense que la protection que ce média propose n'est pas +suffisante</a>, mais je suis en train de +revenir sur ma décision: il pourrait être utile de présenter l'outil, à minima, +en insistant sur certaines de ses faiblesses.</p> +<p>Un compte twitter à été créé recemment autour des crypto-party à Rennes, si +vous êtes interessés, <a class="reference external" href="https://twitter.com/CryptoPartyRNS">allez jeter un coup d'œil</a>!</p> +<p>Je n'ai pas trouvé de ressources disponibles par rapport à des plans de +formation sur le sujet, j'ai donc décidé de publier les nôtres, afin de +co-construire avec d'autres des plans de formation.</p> +<p>Ils sont pour l'instant disponibles <a class="reference external" href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The Docs</a>. Tous les retours +sont évidemment les bienvenus !</p> +</div> +Rencontres python francophones, 20152015-11-02T00:00:00+01:002015-11-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2015-11-02:/rencontres-python-francophones-2015.html<p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation …</p><p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation était vraiment impressionnante (merci +, si vous me lisez !). Et puis comme toujours l'occasion de recroiser quelques +copains, et d'en découvrir quelques autres... J'en ai profité pour parler de +Kinto (voici d'ailleurs <a class="reference external" href="http://alexis.notmyidea.org/kinto-pycon/">les slides de la présentation que j'ai faite</a>).</p> +<p>Parmis les conférences qui m'ont marquées, je vous conseille <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-hospital-des-tests-en-prod.html">celle de Benoit +Bryon, sur Hospital</a>, qui parle de +heartbeat, ou de comment tester vos projets en prod, et celle <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-geoalchemy.html">sur Geo Alchemy, +par Éric Lemoine</a>. Et bien sur, <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-cliquet.html">celle +de Mathieu Leplatre sur Cliquet</a>, le +toolkit qui rassemble les bonnes pratiques que nous souhaitons mettre en avant +chez Mozilla services, mais là, je suis tout sauf impartial !</p> +<p>Sinon, il peut être interessant de jeter un coup d'oeil au <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-table-ronde-diversite.html">compte rendu de la +table ronde sur la diversité</a>, si c'est un sujet qui vous +touche. Encore beaucoup de choses à faire sur le sujet, bien sur, mais cette table ronde +était un pas nécessaire dans la bonne direction. Un groupe de travail sur le +sujet est en train de se constituer au sein de l'association.</p> +<p>L'ensemble des notes que j'ai pu prendre sont disponibles dans la section <a class="reference external" href="http://blog.notmyidea.org/category/pyconfr2015.html">PyconFR 2015</a>.</p> +PyconFR 2015 — Assemblée générale2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-assemblee-generale.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes + Marseille +Support pour 2 Django Carrots. +Par rapport au mentoring, très peu de retours, peut etre de nouvelles choses +à faire.</p> +<p>FOSDEM 2015 était complet. Il y avait une salle python tojours pleine. +Dsicussions sur la diversité.</p> +</div> +<div class="section" id="futur"> +<h2>Futur</h2> +<p>Amandine propose d'organiser des soirées à NUMA l'an prochain. +Global code retreat: participation +Migrer le serveur de l'AFPY +Reboot des status: nos pratiques ne sont pas en ligne avec nos status. +Mise en place de mentoring pour python.</p> +<div class="section" id="status"> +<h3>Status</h3> +<p>Comité directeur renouvelé par tiers. Il est composé de 18 personnes. Les +discussions qui sont dans le CD n'en sortent pas, et les discussions sont donc +effectuées en priuvées.</p> +<p>L'idée actuelle serait de réduire le CD de 18 à 9 personnes. Tout le travail +serait fait en dehors du CD. Il est possible de mettre en place un groupe de +travail pour travailler sur l'évolution de la charte.</p> +<p>Il faut faire évoluer les status: ils ne sont pas actuellement bien faits par +rapport à notre utilisation.</p> +</div> +</div> +PyconFR 2015 — Hospital - des tests en prod2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-hospital-des-tests-en-prod.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et +envoi de fichiers).</p> +<p>Pour des applications plus complexes, il y a beaucoup de choses à tester (base +de données, cache, email, etc). Beaucoup de parties sont utiles: reverse +proxy, django, base de données etc.</p> +<p>Lors d'un déploiement, comment faire pour vérifier que tout tourne lorsque tout +est déployé ?</p> +<div class="section" id="comment-faire"> +<h2>Comment faire ?</h2> +<ul class="simple"> +<li>Les tests permettent de tester hors sol.</li> +<li>Le provisionning permet de valider que tout tourne correctement, mais</li> +<li>simplement au démarrage. Les pannes ne sont pas détectées.</li> +<li>Le logging va permettre de detecter les erreurs, mais trop tard.</li> +<li>Le monitoring permet d'avoir une vue de l'exterieur.</li> +</ul> +<p>Hostpital propose de faire des assertions sur la configuration, +l'environnement, <em>en cours de fonctionnement</em>. Ce sont les developeurs qui +ajoutent ces assertions.</p> +<p>Cela peut servir à valider un déploiement, pour etre rassuré une fois que le +déploiement effectué. Cela peut aussi service à surveiller un service et +diagnostiquer les problèmes.</p> +</div> +<div class="section" id="hospital"> +<h2>Hospital</h2> +<dl class="docutils"> +<dt>::</dt> +<dd>pip install hospital</dd> +</dl> +<p>Hospital est un outil en python. On définit des tests, de la même manière que +l'on définit des tests unitaires. On fait des assertions, comme pour les tests +unitaires. Hospital propose des helpers pour les cas courants: +<cite>assert_http_response</cite> ou <cite>assert_ping</cite>.</p> +<p>La vue est une vue de l'intérieur. La différence avec le monitoring est que +l'on teste la connectivité entre les services (exemple d'une requete +elasticsearch qui échoue depuis un service django).</p> +<p>Pour la supervision, les healthchecks sont lancés avec une ligne de commande +<cite>hospital-cli</cite>. Il est possible de lancer également ces tests avec nose ou +py.test.</p> +<p>Il est aussi possible de faire le monitoring avec une API HTTP <cite>hospital +serve</cite>.</p> +<div class="section" id="les-lacunes-de-hospital"> +<h3>Les lacunes de hospital</h3> +<p>Les healthchecks sont fait actuellement en synchrone. Cela peut prendre du +temps. Il pourrait etre interessant de lancer des taches de manière distribuée +/ en paralelle.</p> +<p>Il pourrait etre utile de faire la distinction entre les smoketests et les +diagnostiques: les premiers sont des petits checks qui permettent de dire si ça +marche, de manière très simple. De l'autre coté, les diagnostiques seraient eux +plus fins.</p> +</div> +</div> +<div class="section" id="wrap-up"> +<h2>Wrap up</h2> +<p>Validez votre configuration, la connectivité avec les services externes. Faites +des tests souvent !</p> +</div> +PyconFR 2015 — We don't need your loop2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-we-dont-need-your-loop.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer comment atteindre le resultat.</p> +<p>En python, par exemple, il vaut mieux utiliser <cite>sum</cite> plutôt que de faire +l'addition nous même (pour faire une addition des elements d'une liste).</p> +<p>Actuellement, le compilateur python est lent si on utilise numpy.sum sur des +matrices complexes.</p> +<div class="section" id="comment-aller-plus-vite"> +<h2>Comment aller plus vite?</h2> +<p>Cython est assez compliqué, il faut savoir ce que l'on fait pour optimiser et +écrire du bon code Cython.</p> +<p>Avec pythran, l'intelligence est dans le compilateur, qui permet d'écrire +notemment des boucles correctement.</p> +<p>En donnant plus d'informaitons au compilateur, plutôt que de faire des boucles, +cela lui permet d'avoir un contexte qui lui permet d'optimiser le code.</p> +<p>Par contre, cela veut dire que plus de connaissances sont necessaire pour lire +le code python.</p> +<p>pythran permet de compiler directement vers du C++ sans avoir à changer son +code de base (python). C'est utile pour du code numpy notemment.</p> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<p>Possible de paralelliser de manière explicite <strong>ou</strong> implicite.</p> +<p><strong>C'est très utile pour les gens qui font du &quot;number crunching&quot;. Est-ce que +c'est utile pour d'autres domaines d'application (Web)?</strong></p> +<p>Pas vraiment. CPython est déjà bien fait pour ces cas d'utilisation.</p> +<p><strong>Est-il possible de lancer pythran sans faire de commentaires ?</strong></p> +<p>C'est possible mais cela ne servira pas à grand chose. Il est necessaire de +connaitre le type des objets qui sont utilisés lors des boucles.</p> +<p><strong>Est-ce que vous songez à un compilateur à la volée ?</strong></p> +<p>De gros efforts ont été faits dernièrement pour diminuer le temps de +compilation. Mais pour une fonction qui renvoie None prends de l'ordre d'une +seconde ou une demi seconde. Ce n'est pas très utile pour un compilateur à la +volée puisqu'il faudrait des gains de perfs supérieurs à cela.</p> +</div> +PyconFR 2015 — Cliquet2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-cliquet.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous demande de faire des APIs, tout +le temps.</p> +<p>Souvent, les mêmes questions sont à l'ordre du jour. Heartbeat, codes +d'erreurs, etc. L'inventaire de tout ce qui est attendu d'une API, au dela de +ce qui est la valeur ajoutée du service.</p> +<p>Définition d'un protocole. Définir une API REST n'est pas aussi évident qu'il +y parait. Il faut définir les formats de JSON, les status, etc.</p> +<p>La réutilisation de certaines protocoles existants était possible (Sync, en +production depuis quelques années).</p> +<p>Réutiliser du code nous permettait et faire un template pour démarrer plus +facilement, pour se concentrer sur le métier de l'API. Puisque les besoins ne +sont pas toujours les mêmes, avoir une boite à outil permet de choisir ce que +l'on souhaite.</p> +</div> +<div class="section" id="protocole"> +<h2>Protocole</h2> +<ul class="simple"> +<li>Création d'un protocole qui respecte les bonnes pratiques. CORS, avoir les +bons codes de status, arrêter de se poser toujours les mêmes questions. +Contrairement à ce qu'on imagine, la spécification HTTP n'est pas si facile +à suivre. Plutôt que d'écrire un document, un toolkit à été créé.</li> +<li>Les ops ont besoin de quelques endpoints: un heartbeat (monitoring) des +endpoints de batch, un endpoint &quot;hello&quot;, pour connaitre le type de service, +ses URLs etc.</li> +<li>La service renvoie toujours un JSON avec la description de l'erreur. Cela +permet d'avoir tout le temps la même gestion des erreurs. Utilisation du +header &quot;backoff&quot; qui permet de demander aux clients d'arreter de faire des +requetes durant une durée spécifée par le serveur.</li> +<li>Pour les resources &quot;REST&quot;, quelques règles sont définies: quel est le format +du JSON, quel est la syntaxe du querystring pour filtrer, ordonner, gérer les +opérations concurentes, etc.</li> +<li>Comment la validation fonctionne ? La pagination ? La définition des +permissions ? Les erreurs.</li> +</ul> +<p>Définir le protocole une seule fois permet de se mettre d'accord avec les Ops. +On ne créé pas une RFC pour l'instant, il faut qu'on valide ce qu'on a fait, +il est necessaire de valider notre approche.</p> +</div> +<div class="section" id="toolkit"> +<h2>Toolkit</h2> +<p>La stack en place est basée sur Pyramid et Cornice. Autre chose aurait pu petre +utilisé. Mais pyramid à été choisi pour son approche simpliste et qui permet de +rajouter de la complexité au fur et à mesure.</p> +<p>Cliquet propose de faire l'ensemble du boilerplate, la lecture du protocole, et +vous permet de créer les backends souhaités.</p> +<p>Il est possible de choisir les methodes HTTP acceptables, les URLs à utiliser +etc. Tweaker l'API est possible, la chose qui reste toujouts stable est le +protocole.</p> +<p>le toolkit vise à faire quelque chose de pluggable. Tout est controllable +depuis la configuration.</p> +<p>Pour le deploiement, cela veut dire que le monitoring est déjà connecté, et il +est possible de changer la configuration depuis un fichier <cite>.ini</cite>.</p> +<p>Il est aussi possible de faire du profiling en ajoutant deux lignes de code, +qui permet de générer des graphs qui permettent d'identifier les goulots +d'étranglement.</p> +</div> +<div class="section" id="microservices"> +<h2>Microservices ?</h2> +<ul class="simple"> +<li>Cliquet apporte une manière standard de surveiller, deployer, configurer des +services.</li> +<li>Il est possible de se focaliser sur la logique de l'application, en faisait +une abstraction des backends, etc.</li> +<li>Le fait de figer l'API permet d'avoir des clients génériques que l'on peu +réutiliser d'une application à l'autre.</li> +</ul> +</div> +<div class="section" id="cliquet-est-utilise-pour"> +<h2>Cliquet est utilisé pour</h2> +<ul class="simple"> +<li>Kinto, un service générique de stpclage de données.</li> +<li>Syncto, un proxy pour Sync en utilisant le protocole.</li> +<li>La liste de lecture, service qui à été shutdown.</li> +</ul> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<ul class="simple"> +<li><strong>Qu'est-ce qui est pluggable ?</strong> Les choix qui sont fait dans cliquet +concernent le protocole. Le toolkit est lui fait de manière &quot;pluggable&quot;. Il +est par exemple possible de changer le backend, l'authentification, le cache +ou les permissions.</li> +<li><strong>Quelles sont les parties non standard? Est-il prévu de representer ça via +une RFC ?</strong> Le seul sujet qui pourrait etre utile dans une RFC serait de +définir les headers attendus pour la validation et l'écriture +concurrentielle. L'ensemble de ce qui est proposé est standard.</li> +<li><strong>Existe-il un client JavaScript, comme pour Kinto ?</strong> Actuellement, non. Par +contre, Kinto.js est prévu pour que la partie commune entre les APIs (le +protocole) peut etre extrait.</li> +</ul> +</div> +PyconFR 2015 — Geoalchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-geoalchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des données qui +representent des objets dans un espace géométrique.</p> +<ul class="simple"> +<li>Il est possible d estocker des ligne,s de polygones, des points. Il y a une +colonne géometrie pour stocker ces données.</li> +<li>Il y a aussi des fonctions qui permettent de travailler sur ces données +(transfomrations, projections, etc).</li> +<li>Indexs géographiques qui permettent de faire des recherches de manière +performante.</li> +</ul> +<div class="section" id="postgis"> +<h2>POSTGIS</h2> +<p>POSTGIS s'appuie sur postres pour offrir des types géographiques, des fonctions +et des indexes (R-Tree), qui permettent de ranger les géométries dans des +&quot;boites englobantes&quot;.</p> +<p>Pour créer une base de données postgis, il faut faire un &quot;create extension +postgis&quot;, ce qui installe tout ce dont on a besoin.</p> +<p>il est possible d'apeller <cite>GEOMETRY(POINT)</cite> par exemple.</p> +<p><cite>ST_GeomFromText('POINT(lat long)')</cite> permet de convertir un point dans un objet +geometrie interne à postgres.</p> +<p><cite>ST_DWithin</cite> permet de trouver les personnes qui sont autour d'un rayon donné.</p> +<p>L'ensemble des fonctions proposées par postgres commencent par <cite>ST_*</cite></p> +</div> +<div class="section" id="sqlalchemy"> +<h2>SQLAlchemy</h2> +<p>Il s'agit d'une bote à outil qui permet de faire des requetes de manière +simple. Il y a une philosophie forte.</p> +<ul class="simple"> +<li>Il ne sohaite pas cacher la base de données</li> +<li>C'est un language pour faire du SQL en python</li> +<li>Rien n'est caché.</li> +<li>Fourni un vocabulaire riche pour générer le SQL</li> +<li>L'objectif est de changer la manière dont on pense à SQL, redonner le gout du +SQL aux developeurs.</li> +</ul> +<p>Deux parties: +- ORM +- CORE</p> +<p>Il est possible d'utiliser simplement le core si l'on sohaite (sans utiliser +l'ORM)</p> +<div class="section" id="core"> +<h3>Core</h3> +<p>Il est possible d'utiliser SQL Alchemy pour générer les tables à l'origine. +Core permet d'utiliser des tables, et d'executer une insertion, depuis python. +Il est possible de representer les requetes avec des methodes chainées +<cite>select().where()</cite> etc.</p> +<p>Le &quot;core&quot; ne fait pas de mapping du tout, il manipule des Tables SQLA +directement.</p> +</div> +<div class="section" id="orm"> +<h3>ORM</h3> +<p>L'ORM fait, lui, du mapping. C'est cette couche que l'on va utiliser dans une +application Web complexe par exemple.</p> +<ul class="simple"> +<li>il est possible de travailler avec une session <cite>Session()</cite> puis on effectue +des opérations et on <cite>commit()</cite>.</li> +</ul> +<div class="section" id="geoalchemy"> +<h4>GeoAlchemy</h4> +<ul class="simple"> +<li>Créé en 2009, pour supporter uniquement postgis.</li> +<li>Depuis, d'autres bases de données (MySQL, Spatialite, MySQL server) etc.</li> +<li>Réécriture depuis grace à la nouvelle API de SQLAlechemy, mais perte du +support d'autres backends.</li> +<li>Finalement, retour sur POSTGIS uniquement, pour évite d'avoir à supporter les +différences de tous les backends.</li> +</ul> +</div> +</div> +</div> +<div class="section" id="features"> +<h2>Features</h2> +<p>Très simple de s'intégrer avec les features de POSTGIS, par exemple en +déclarant une colonne en tant que &quot;Géometrie&quot;.</p> +<p>Exemple: session.query(Lake).filter(Lake.geom.ST_Buffer(2).ST_Area) permet de +lister l'ensemble des lacs avec une aire de 2 au moins.</p> +<p>S'intègre bien avec des services existants (shapely, pyramid, etc).</p> +<p>Utilisation de geojsondumps pour representer des features en geojson.</p> +</div> +<div class="section" id="status"> +<h2>Status</h2> +<p>Le projet est completement documenté sur read the docs. La documentation est +assez complete et solide. Il est intégralement testé, sur differentes versions +de python, sqlalchemy et postgres.</p> +<dl class="docutils"> +<dt>3 ou 4 developeurs actifs sur le projet, ça fonctionne plutôt bien. Pour</dt> +<dd><p class="first">contribuer, il est possible de faire cela sur github.</p> +<p class="last">Slides de la presentation sur <a class="reference external" href="http://erliem.net/talks/pyconfr2015">http://erliem.net/talks/pyconfr2015</a></p> +</dd> +</dl> +<p>Resources:</p> +<ul class="simple"> +<li><a class="reference external" href="https://pypi.python.org/pypi/Shapely">https://pypi.python.org/pypi/Shapely</a> - Manipulation and analysis of geometric +objects in the Cartesian plane.</li> +</ul> +<p>Question:</p> +<ul class="simple"> +<li>Dans les exemples geoalchemy, les données geométriques sont passées sous +forme de chaine. Est-ce normal ? Oui.</li> +<li>Les rasters sont également supportés.</li> +</ul> +</div> +PyconFR 2015 — SQL Alchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-sql-alchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent …</li></ul><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent nos tables, et les liaisons entre les +tables, en utilisant <cite>relationship</cite> (qui à énormement d'attributs).</li> +<li>On définit quelles osnt les clés étrangères entre les tables.</li> +<li>Puis on va définir les attributs qui sont liés entre les tables +(relationship).</li> +<li>Pour définir des relations entre les Tables, il est possible d'utiliser des +chaines de caractère <cite>relationship('OtherTable')</cite>.</li> +<li>La session es tun concept important.</li> +<li>Lire efficacement. Attention à ne pas faire énormement de requetes avec +L'ORM.</li> +</ul> +<p><strong>Performance SQL</strong></p> +<ul class="simple"> +<li>Générer le SQL (python)</li> +<li>Ne pas faire énormement de petites requetes.</li> +</ul> +<p>Il est possible de demander à la session de charger les données qui sont +associées. (avec un joinedload). Par defaut, cela risque de charger +l'ensemble des colonnes.</p> +<p>Pour la générer avec SQLAlchemy, il est possible de faire un +<cite>.query(Table).join(Table).join(Table2).filter_by(field=value)</cite></p> +<p>En pratique, le mieux est de lister clairemnet le nom des tables</p> +<p>2ème partie:</p> +<p>Pour de l'import de données,</p> +<ul class="simple"> +<li>first() fait une requete SQL. A éviter dans les boucles</li> +<li>session.flush() c'est quand la session écrit en base tout ce qui est en cours +dans la transaction. Par default, la session fait un flush avant chaque +requete.</li> +<li>une option backçpopulates mets à jour la liste des documents associés à une +table qui à une foreign key. +backref modifie implicitement la classe associée. Il est recommandé +d'utiliser <cite>back_populates</cite> et non pas <cite>backref</cite>.</li> +<li><cite>subqueryload</cite> permet de générer une requete séparée plutôt qu'une jointure.</li> +</ul> +PyconFR 2015 — Table ronde diversité2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-table-ronde-diversite.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et …</strong></p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et Alexia).</strong></p> +<p><strong>JP — Pourquoi</strong>:On a eu une discussion sur la ML de l'AFPy suite à une décision +de l'afpy de ne pas financer un évènement qui n'était pas ouvert à tous-tes +(restreint aux femmes et personnes trans). Cette décision à été prise +conformément a la charte de l'AFPY qui dit que les evènements promus sont +ouverts à tous. Ce qui veut dire que cela n'inclue pas les évènement exclusifs. +(Je n'ai jamais demandé de financement à l'AFPY. J'ai juste demandé la +diffusion sur la mailing interne de la création de Pyladies Paris. Je ne sais +pas d'où vient cette histoire de financement! Pyladies Paris)</p> +<p>Suite à ça, une modification de la charte à été proposée. Demain matin, la +modification de la charte sera proposée lors de l'AG. Suite à la proposition de +modification, les discussions se sont enchainées, avec des points de vue +divergents. Cette table ronde vient donc dans ce contexte. +I +BD d'introduction: +<a class="reference external" href="http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/">http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/</a></p> +<div class="section" id="tour-de-presentation"> +<h2>Tour de présentation:</h2> +<ul class="simple"> +<li>Laurence directrice de l'école qui accueille d'évènement, docteure en Maths. +Contente de voir que la tendance s'inverse un peu (de plus en plus de filles).</li> +<li>Vivianne, maitre de conférence en informatique à paris sud. Études dans un +milieu assez masculin. Dans le domaine du developpement pour la recherche, ou +des environnements techniques, c'est très masculin. Essaye de voir comment +faire pour que les filles s'intéressent plus a l'informatique.</li> +<li>Amandine Neyrolle, diplomée d'école de commerce (plutot 50% fille/garcon dans +ces fillières). Intégrée le monde de l'informatique par la suite en autodidacte +et formations. Rencontré la créatrice de pyladies et discuté de ces questions.</li> +<li>Laurenne Chelan, organistrice des django girls bdx. Nouvelle dans cet +univers. Travaille dans des musées de science depuis quelques années. L'idée de +dj girs bdx part de l'idée de découvrir le code. Les djangogirls viennent de +berlin, créé par ???.</li> +<li>Alexia Sumois. organisatrice de django girls bdx. Nouvelle dans le milieu du +code. Les conférences d'aujourd'hui on donné envie d'apprendre.</li> +<li>Anna, créatrice de 4ideas. Essaye de faire en sorte que plus de femmes +viennent dans l'IT. En reconversion pro. Choisi ce domaine il ya un an. Trouve +que ce sujet est vraiment extremement important, et sur lequel il est possible +de faire quelque chose, et d'influencer positivement. L'idée étant de +démystifier l'IT, et laisser le choix aux femmes de choisir cette profession.</li> +<li>Jean Phillipe Campguillhem, secrétaire de l'AFPY</li> +</ul> +</div> +<div class="section" id="pourquoi-django-girls"> +<h2>Pourquoi Django Girls ?</h2> +<p><strong>Alexia</strong> — Le déclencheur de cette aventure vient des goodies (!). La décoration +de l'évènement a attiré l'attention et donné envie de creuser.</p> +<p><strong>Laurenne</strong> — C’est pour ça qu’on se pose la question « comment attirer ces +publics, ces personnes-là ? », importance de l’image qu’on renvoie. Ce n’est +pas tant une question de genre, mais d’initié·e·s : on a souvent peur d’entrer +dans ce milieu. Django-girls vise une plus grande bienveillancet Carte de la +convivialité, chaleureux, et facile d'accès pour les débutants. Tout est livré +clé en main, et l'évènement est facile à prendre en main. Le 28 oct à bordeau, +recherche de coachs / sponsors pour l'évènement. +<a class="reference external" href="http://djangogirls.com/bordeaux">http://djangogirls.com/bordeaux</a></p> +<p><strong>Laurence</strong> — Aspect macho présent dans la communication de l’école (pas +forcément explicite). « On a toujours dessiné des symboles de métiers +identifiés par des garçons »</p> +<p><strong>Laurenceu</strong> — Il y a une partie d'inconscient dans l'ensemble de +l'enseignement qui est donné. Il y a peu de candidates qui essayent. Pas +question de discrimination positive puisque cela a des effets indésirables +(communautarisme). La question est tout de meme posée, mais il est impensable +d'accepter des gens grace / a cause de leur genre. L'ambiance change lorsqu'il +y a de la mixité. À la recherche d’idées pour faire venir plus de candidates.</p> +<p><strong>Viviane</strong> — En tant que femme, on reçoit en permanence le message que ce +métier n’est pas fait pour nous. Ces messages ont un impact, le résultat est +que les filles ne vont pas dans les écoles d’informatiques. Il faut aller +convaincre les jeunes filles que c’est aussi fait pour elles. Ça passe par +changer les plaquettes. Il faut réussir à changer l'image existante des confs / +communautés. Un développeur peut aussi etre une développeuse. Dans l'assemblée, +on se rend compte que certaines femmes sont en dehors du parcours. Il faut +qu'en tant que communauté on soit capables d'accueillir les nouvelles / +nouveaux. C’est en ayant une diversité qu’on parviendra à changer l’image du +métier. Les rencontres pyladies permettent aussi de rencontrer d'autres femmes +qui ont les mêmes problématiques. Accompagner les nouvelles entrantes pour +trouver du boulot, découvrir l'AFPY et les initatives existantes. Les +initiatives existantes django girls / pyladies est très important.</p> +<p><strong>Amandine</strong> — C’est pourquoi ce genre d’évènements non-mixtes permet de faire +des séances de rattrapage pour permettre d’intégrer la communauté dans son +ensemble. C’est le point clé pour faire accepter ce genre d’initiatives.</p> +<p><strong>Laurenne</strong> — DjangoGirls et Django Carrots ne sont pas des évènements +excluants. Ils sont simplement orientés en priorité aux femmes. Sur la question +de « comment amener des jeunes filles vers ces études-là », ça se joue bien +avant, dans l’enfance, bien avant l’école. cf les jeux genrés. Il faut +travailler à ce niveau-là.</p> +<p><strong>Anna</strong> — Pour illustrer ce que dit Laurenne, l'importance des clichés +existants. Avant le mi-80s, il y avait autant de femmes que dans d'autres +domaines. Si on regarde les stats, dans tousles autres domaines, le pourcentage +de femmes augmente. Et en IT, en 84 il y a un pic qui inverse la tendance. Ce +sont des stats américaines. A priori cela s'applique aussi en Europe. En IT, la +culture qui à été créé autour des hackers qui ont des super pouvoirs, mangent +des pizzas, etc. Ces clichés ont influencé le monde. Nous ne sommes pas +complètement autonomes, et nous sommes influencés par la culture autour de +nous. Les dommages qui ont été fait dans le domaine de l'IT sont graves, et il +est important de renverser la tendance. La question de l'image est centrale. +Les personnes ont besoin de place pour faire leurs évènements. Il est important +de comprendre et respecter que les autres veuillent faire de la discrimination +positive. Ce sont des actions qui sont supportées par la France. Ce sont des +valeurs qui sont beaucoup lus fortes en France qu'ailleurs (Anna souligne +qu'elle est Polonaise). On devrait respecter ce droit.</p> +<p><strong>Vivianne</strong> — Certaines evènements sont non-mixtes (pour les personnes qui +s'identifient comme des femmes). Ce ne doit pas etre les seules initiatives. +Elle est pour la mixté. PyLadies est assez spécifique : ce n’est pas de la +formation, mais principalement des évènements tournés autour du réseau. Il est +important d'avoir un endroit ou les jeunes femmes seront moins imprésionnées. +Les situations exposées dans la BD sont réelles. De se retrouver dans un +environnement où elles sont sûres qu’elles ne subiront pas de micro-agressions.</p> +<p><strong>Laurence</strong> — Témoignage d'une mère qui dit à sa fille, en passant devant un +panneau de l'école, mentionnant maths et informatique, et qui dit à sa fille « +oh non, c'est pas pour toi ça » . On dit « attention les garçons, vous devez +être sympas avec les filles ». Les garçons ont envie que ça se passe bien avec +les filles.</p> +<p><strong>JP</strong> — Sans revenir sur les décisions qui ont été prises, nous n'avons pas +dit que nous étions contre ces évènements (à l'AFPY). A plusieurs reprises, +j'ai du faire des blagues sexistes. Évidemment qu'on est mieux ensemble. Pour +revenir sur la discussion de la mailing-list, je me suis rendu compte que +j'avais un regard biaisé. Si on en est la, c'est quil y a énormement de +travail. Que faire, du coup ? En tant qu'hommes ? Qu'association ? Si il est +necessaire de créer une zone de confort / sécurité, c'est qu'il y a une zone +d'inconfort / insécurité qui est forte. Les couleurs, les jolis goodies, sont +le sommet de l’iceberg. Rappel de l'éxistence du Code of Conduct : il y a déjà +eu des incidents par le passé. On passe la parole à Florent, qui est à +l’origine du CoC. Remerciement envers les intervenantes.</p> +<p><strong>Florent (vice secrétaire de l'AFPY)</strong> — Comme le dit JP, un code of conduct +est affiché devant toutes les portes et à l'entrée. Tout le monde n’aimait pas +forcément l’idée d’en avoir, on a fini par trancher. Le but est d’avoir des +endroits safes. Avant d’avoir un CoC, on ne peut pas dire qu’on soit safes, +envers l'ensemble des minorités. On a écrit le CoC en conséquence des +agressions. Aujourd’hui, pas de tolérance pour des comportements qui n’ont pas +lieu d’être (qu’on a définis comme tels). Ça fonctionne sur la dénonciation +lorsque l’on est témoin de ça. On n’a pas vraiment de mal à rencontrer des +femmes, mais plus de mal à faire comprendre qu’elles sont bienvenues. Impact +important de blagues sexistes, qu’on défend comme « c’est pour rire ». Merci de +lire le Code of Conduct. Les blagues sexistes etc. ne sont pas les bienvenues. +Merci de réagir lors de ces cas.</p> +</div> +<div class="section" id="questions"> +<h2>Questions.</h2> +<p><strong>Questiond de Gawel</strong>: Question pour Amandine. Est-ce que tu te sens bien à l'AFPY ? Si non, que faire pour que tu te sente mieux ?</p> +<p>Amandine — Oui je me sens bien, est-ce qu’il y a eu des évènements ? oui, sans +doute mais j’y suis aguerrie, donc je me rends peu compte. Qu’est-ce qu’on peut +faire ? L’idée du CoC est d’aller à l’encontre des comportements négatifs, mais +l’idée derrière est une ouverture à la différence dans son ensemble, promouvoir +l’ouverture à l’autre et à la différence. L’enjeu culturel est d’arriver à +changer d’état d’esprit et d’identifier ces biais cognitifs. Il faudrait pas +qu’on se dise « ho là là, il y a une fille, faut rien dire sinon je vais me +faire taper » Il faut cultiver la différence. et être curieux/se.</p> +<p><strong>Question</strong> : « c’est pas fait pour moi », mais plutôt « je suis mauvais, donc +je dois travailler », on en revient à l’importance de l’éducation. Il faut +continuer de pointer du doigt les problèmes. Je suis aussi membre d’un LUG, +nous sommes entre hommes diplomés blancs de 30 à 40 ans. La réflexion sur les +plaquettes pas accueillantes est pertinente : le site de l’asso est très +masculin.</p> +<p><strong>Question de Bruno</strong>. Pour l’école: quand j’étais étudiant, 20% de filles. +(Aujourd’hui on est partis de 7/8% pour arriver à 15%). Est-ce que les filles +réussissent plus ?</p> +<p>Laurence — on n’a pas de stats, mais elles posent moins de problèmes. Les +filles sont favorisées par les employeurs.</p> +<p>Vivianne — la motivation des filles à la sortie est identique aux garçons, mais +tout n’est pas rose. En entretien par exemple, ils sont faits par des hommes, +mais au niveau des stats, le nombre de femmes qui quittent le milieu est +important. Effort à faire au niveau de la communauté, des entreprises. Schémas +masculins, mais sur le long terme, on subit des agressions. Difficile de rester +dans le métier et faire une carrière intéressante, à compétences/motivation +identiques aux hommes. Il faut en avoir conscience</p> +<p><strong>Question de Benoit</strong>: il y a peut-être une façon de créer des +lieux/évènements protégés, en utilisant ceux qui existent déjà. Est-ce qu’on +peut aller organiser des évènements dans des écoles/lycées, des endroits où les +gens se sentent déjà à l’aise, où les populations sont plus représentées ?</p> +<p>Vivianne — ça se fait. En tant qu’enseignante, dès que j’ai une occasion, que +ce soit pour aller chercher des JF ou des étudiants maths/infos, même si c’est +ouvert à tous, je le fais. Si c’est que des hommes, les femmes n’ont pas envie +d’y aller.</p> +<p>Laurenne — c’est quelque chose qui se fait beaucoup. On met en avant des femmes +chercheuses dès qu’on le peut.</p> +<p><strong>Question d'Alexis</strong> : je suis très content qu’il y ait cette discussion qui +se fasse. Question par rapport aux discriminations positives, qu’on a pu voir +par le passé (notamment lors de conférences). Difficile de dire « on va +préférer des femmes ». Question irrésolue, parce que pour faire évoluer, on a +besoin d'initier quelque chose, d’essayer. Mais ça a un côté dérangeant.</p> +<p>Vivianne — à la PyCon (US), j’ai été impressionnée du nombre de femmes qui +parlaient. On va pas mettre un quota, ça serait stupide, on va forcer personne. +Mais il faut en avoir conscience. Cette année, on est 4 oratrices, y’a du +travail à faire. En tant qu’hommes, il faut aussi se mettre en retrait et +inviter des femmes à en parler à notre place. Faire le pas d'aller faire un +exposé dans une communauté où on ne se sent pas à sa place (même si on lutte +contre) est difficile. Inviter des gens, sans forcément passer par un énorme +processus. Ça passe par des events comme PyLadies.</p> +<p>Anna — pour les personnes par encore convaincues, juste apres le droit de vote +des femmes en 46, à l'assemblée nationale il y avait très peu de femmes. Puis +en 93, 6.1% apres que des mesures aient été prises. Ensuite de femmes puis vers +20% Les choses ne vont pas se changer toutes seules. Il est necessaire d'avoir +du temps pour faire évoluer les choses. Il est important de noter que PyconFR +fait déjà des choses. Et lors de django carrots, je me suis sentie très +accueillie. J'ai eu beaucoup de très bonnes expériences avec des personnes qui +étaient prêtes à aider.</p> +<p>JP — Remerciement pour Rémy qui abat un travail de ouf. C'est grace à Rémy si +il y a django carrots demain. Il faut faire des choses. :-) Merci !</p> +</div> +Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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't actually +trust the software authors but are rather trusting the software distributors +and certificate authorities (CAs).</p> +<p>I'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 come!</p> +<div class="section" id="the-problem-attack-vectors"> +<h2>The problem (Attack vectors)</h2> +<p>Let's try to describe a few potential 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 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 CDN +which delivers the files,</p> +<p>Trusted <em>Certificate Authorities</em> (&quot;governments&quot; or &quot;hacking team&quot;) can also +trick the User Agents (i.e. Firefox) into thinking they're talking to <em>Indie +Hoster</em> even though they're actually talking to a different 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 users.</p> +</div> +<div class="section" id="problem-mitigation"> +<h2>Problem Mitigation</h2> +<p>Part of the problem is solved by the recently introduced <a class="reference external" href="https://w3c.github.io/webappsec/specs/subresourceintegrity/">Sub Resource +Integrity</a> +(SRI). To quote them: &quot;[it] defines a mechanism by which user agents may verify +that a fetched resource has been delivered without unexpected manipulation.&quot;.</p> +<p>SRI is a good start, but isn't enough: it ensures the assets (JavaScript files, +mainly) loaded from a specific HTML page are the ones the author of the HTML +page intends. However, SRI doesn't allow the User Agent to ensure the HTML page +is the one he 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's not automated, but at least it's possible.</p> +<p>For web applications, we don't have such a mechanism, but it should be +possible. Consider the following:</p> +<ul class="simple"> +<li><em>App Authors</em> publish a new version of their software; They provide a hash of +each of their distributed files (including the HTML files);</li> +<li><em>Crypto Experts</em> audit these files and sign the hashes 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're signed by a trusted +party.</li> +</ul> +</div> +<div class="section" id="chosing-who-you-trust"> +<h2>Chosing who you trust</h2> +<p>In terms of user experience, handling certificates is hard, and that's where +the community matters. Distributions such as <a class="reference external" 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't verified.</p> +<p>But, as highligted earlier, CAs are hard to trust. A new instance of the same +CA system wouldn'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 of).</p> +<blockquote class="epigraph"> +<p>[...] 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 CA scandals. Both schemes can also be attacked if the +authority does not verify keys before vouching for them.</p> +<p class="attribution">&mdash;<a class="reference external" 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 reliable:</p> +<blockquote class="epigraph"> +<p>Melara et al proposed CONIKS, using a series of chained commitments to Merkle +prefix trees to build a key directory [...] for which individual users can +efficiently verify the consistency of their own entry in the directory +without relying on a third 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 self-auditing.</p> +<p class="attribution">&mdash;<a class="reference external" 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'm pretty sure +this design has many security problems attached to it.</p> +<p>However, that's a problem I would really like to see solved one day, so here +the start of the discussion, don't hesitate to <a class="reference external" href="/pages/about.html">get in touch</a>!</p> +</div> +<div class="section" id="addendum"> +<h2>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'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 this.</p> +<p>A bit like User-Agents do for SSL, but for the actual signature of the files +being viewed.</p> +</div> +Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-06-29:/roles.html<blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de …</p></blockquote><blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de +positions qu’adoptent ses protagonistes et les affects qui y sont liés, +imaginer ensuite des questions à résoudre ou des propositions à travailler +qui soient susceptibles d’enrichir la palette, les couleurs de la fonction +de chacun dans le groupe et les manières qui sont les siennes d’intervenir +et de faire évoluer l’histoire.</p> +<p class="attribution">&mdash;David Vercauteren, <a class="reference external" href="http://micropolitiques.collectifs.net/Role">Micropolitiques des groupes</a></p> +</blockquote> +<p>Réussir la transformation d'un espace compétitif vers un groupe soudé demande +de réaliser quels sont les points forts de chacun au sein d'un groupe.</p> +<p>Une solution évoquée par <a class="reference external" href="http://www.starhawk.org/about/">StarHawk</a>, reprise +par <em>David Vercauteren</em> repose sur l'existence de rôles informels au sein des +groupes et la nécessité de les faire tourner (ainsi que les responsabilités +attachées).</p> +<p>Parmi les rôles principaux, quelques autres citations:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">l'emphase est de mon fait, et je retravaillé très legèrement certains +passages afin d'avoir une lecture plus fluide. Je vous invite à suivre +les liens pour voir les &quot;questions que chaque rôle fait exister&quot;, et +poursuivre la lecture du livre, qui est entièrement disponible en +ligne.</p> +</div> +<div class="section" id="id1"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_0">Les corbeaux</a></h2> +<blockquote class="epigraph"> +<p>Les Corbeaux sont visionnaires […] Ils voient à long terme, et gardent en +ligne de mire les objectifs du groupe. Ils suggèrent de nouvelles directions, +dressent des plans, développent des stratégies et anticipent les problèmes et +les besoins.</p> +<p>Les Corbeaux ont souvent beaucoup d’influence sur le groupe. Si une ou deux +personnes pensent à des plans au long-terme, les autres acquiesceront, +simplement parce qu’ils n’ont pas amené d’autres propositions. <strong>Le groupe +aurait intérêt à considérer ensemble les questions du Corbeau</strong></p> +</blockquote> +</div> +<div class="section" id="id2"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_1">Les graces</a></h2> +<blockquote class="epigraph"> +<p>Les Grâces sont toujours attentives à l’énergie du groupe, prêtes à la +renforcer au moment où elle faiblit, à la diriger et à la canaliser quand +elle est forte.</p> +<p>Elles apportent au groupe […] enthousiasme, énergie, capacité +à s’agrandir. <strong>Elles font en sorte que les gens se sentent bien</strong>, génèrent de +l’enthousiasme pour le groupe, accueillent les nouveaux venus, amènent de +nouvelles personnes. Elles offrent au groupe l’inspiration et génèrent de +nouvelles idées.</p> +</blockquote> +</div> +<div class="section" id="id3"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_2">Les dragons</a></h2> +<blockquote class="epigraph"> +<p>Le dragon permet au groupe de rester connecté à […] l’aspect pratique et +réaliste des choses. […] Le dragon veille aux ressources du groupe, à ses +frontières et donne voix à ses limites.</p> +<p>Questions que fait exister le dragon:</p> +<ul class="simple"> +<li>Notre manière de travailler est-elle viable ?</li> +<li>Nos ressources sont-elles renouvelées ?</li> +<li>Les gens s’épuisent-ils ? Pourquoi ?</li> +<li>Pouvons-nous vraiment nous lancer dans ce projet et le mener à bien +convenablement ?</li> +<li>De quelles frontières avec l’extérieur avons-nous besoin et voulons-nous +?</li> +<li>Comment établissons-nous ces frontières ? Comment nous protégeons-nous +des intrusions ? Invasions ? Distractions ? De ce qui épuise nos énergies +?</li> +</ul> +<p><strong>Les Dragons établissent des frontières qui donnent au groupe un sentiment +de sécurité et des limites qui le rendent viable dans le temps</strong>. Ils peuvent +être perçus comme des rabat-joie, mais ils peuvent gagner l’estime de ceux +qui, dans le groupe, se sentent dépassés et ne peuvent partager l’énergie +des Corbeaux et des Grâces.</p> +<p>Nourrir les Dragons peut permettre au groupe de se maintenir dans le temps. +Mais une fois encore, si ce rôle ne tourne pas, même les Dragons risquent +de s’épuiser.</p> +</blockquote> +</div> +<div class="section" id="id4"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_3">Les araignées</a></h2> +<blockquote class="epigraph"> +<p>Le centre d’un groupe peut consister en un « cœur spirituel », <strong>un but ou une +vision commune</strong>, ou peut se manifester à travers une personne. Dans les modes +de pensée hiérarchique, le professeur ou le gourou occupe le centre du +réseau. […]</p> +<p>Dans les groupes non-hiérarchiques, certaines personnes peuvent être perçues +comme centrales : en disposant des informations dont les autres ont besoin, +en étant le point de contact pour les autres.</p> +<p>Une Araignée est toutefois plus efficace en ne monopolisant pas la +communication et les informations mais en posant les questions susceptibles +de créer et de renforcer un véritable réseau d’interactions complexes.</p> +</blockquote> +</div> +<div class="section" id="id5"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_4">Les serpents</a></h2> +<blockquote class="epigraph"> +<p>Les serpents cultivent une attention particulière à la manière dont les gens +se sentent. […]</p> +<p>Les serpents sont au courant de ce qui se murmure dans les couloirs, des +conflits naissants, et les mettent sur la place publique, là où ils +pourraient aider à une médiation, à une résolution du problème. […]</p> +<p>Les serpents transgressent les lois du Censeur, <strong>parlent des non-dits, mettent +en évidence ce que d’autres ne voient pas ou préfèrent garder caché</strong>. […]</p> +<p>Les serpents peuvent diminuer l’antipathie dont ils font l’objet s’ils +prennent la peine de poser des questions au groupe et non d’apporter des +analyses.</p> +</blockquote> +<p>Ainsi, il est possible de se rendre compte de la complexité et de l'importance +d'une position ou d'une autre, et de les faire évoluer ensemble, en prenant en +compte leur impact positif sur le groupe.</p> +<p>Il est par exemple possible, après avoir expérimenté des rôles, de questionner +leur pertinence et d'établir des pistes d'amélioration en enlevant une part +importante d'affect personnel qui parfois empêche des discussions +constructives.</p> +<p>Je n'ai pour l'instant pas pu expérimenter l'évolution des rôles au sein d'un +groupe donné, mais je peux d'ores et déjà me rendre compte que selon les +groupes et selon les moments je n'ai pas le même rôle (tour à tour dragon, +araignée et grace, parfois corbeau, rarement serpent)</p> +<p>Aussi, il semble que le groupe doive souhaiter l'établissement d'un +environnement <em>horizontal</em>, avec une considération partagée de la direction que +le groupe souhaite prendre pour qu'un tel dispositif ait du sens.</p> +</div> +Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois …</p><blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois passé l'euphorie du &quot;il faut utiliser PGP pour l'ensemble de nos +communications&quot;, j'ai réalisé lors de discussions que PGP avait plusieurs +problèmes, parmi ceux-ci:</p> +<ul class="simple"> +<li>Les <em>meta données</em> (y compris le champ &quot;sujet&quot; de la conversation) sont quand +même échangées en clair (il est possible de savoir qu'un message à été échangé +entre telle et telle personne, a telle date);</li> +<li>PGP 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 chiffrée;</li> +<li>Il est facile de connaître votre réseau social avec PGP, puisque tout le +principe est de signer les clés des personnes dont vous validez l'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 PGP 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 &quot;sécurisée&quot; (HTTPS). Tout le monde peut donc voir ces échanges et +savoir de qui vous cherchez la 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 clés).</li> +</ul> +<p>Je suis en train de creuser à propos les alternatives à PGP, par exemple <a class="reference external" href="https://pond.imperialviolet.org/">Pond</a>, qui lui ne construit pas par dessus un +standard déjà établi, et donc n'hérite pas de ses défauts (mais pas non plus de +son réseau déjà établi).</p> +<p>En attendant, quelques bonnes pratiques sur PGP ;)</p> +<div class="section" id="bonnes-pratiques"> +<h2>Bonnes pratiques</h2> +<p>Il est en fait assez facile d'utiliser PGP de travers. Riseup à fait <a class="reference external" href="https://help.riseup.net/en/security/message-security/openpgp/best-practices">un +excellent guide</a> +qui explique comment configurer son installation correctement.</p> +<ul class="simple"> +<li>J'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 oubliez.</li> +<li>Générez des clés RSA de 4096 bits, en utilisant sha512;</li> +<li>Il faut utiliser une date d'expiration de nos clés suffisamment proche (2 +ans). Il est possible de repousser cette date si nécessaire, par la suite.</li> +</ul> +<p>Parmi les choses les plus frappantes que j'ai rencontrées:</p> +<ul class="simple"> +<li>Utiliser le <em>flag</em> <cite>–hidden-recipient</cite> avec PGP pour ne pas dévoiler qui est +le destinataire du message;</li> +<li>Ne pas envoyer les messages de brouillons sur votre serveur, ils le seraient +en clair !;</li> +<li>Utilisez HPKS pour communiquer avec les serveurs de clés, sinon tout le +trafic est en clair.</li> +</ul> +<p>Le <a class="reference external" href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils de +chiffrement d'échanges de messages et de VPN simples à utiliser, encore quelque +chose à regarder.</p> +<p>Enfin bref, y'a du taf.</p> +</div> +Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui …</p><blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui n'étaient bien souvent que des +envies passagères.</p> +<p>Il est arrivé que quelqu'un m'ait demandé de le faire, et que j'y prenne du +plaisir, ou que je le fasse simplement pour moi et que d'autres y trouvent leur +compte, mais il s'agit nécessairement de projets non <em>commandités</em> par l'extérieur.</p> +<p>Encore un signal dans la direction du travailler moins, cette fois ci pour +être plus créatif.</p> +<img alt="Soupa'Soups." src="https://blog.notmyidea.org/images/soupasoups.jpg" /> +Simplifier les preuves d'identités2015-05-11T00:00:00+02:002015-05-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.html<p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la …</p><p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la clé publique que +j'utilise est réellement la mienne.</p> +<p>Traditionnellement, il est nécessaire de faire signer ma clé publique par +d'autres personnes, via une rencontre en personne ou des échanges hors du +réseau. C'est par exemple ce qui est réalisé lors des <a class="reference external" href="https://fr.wikipedia.org/wiki/Key_signing_party">Key Signing parties</a>.</p> +<p>Une manière simple d'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 personne.</p> +<p>PGP propose un mécanisme de signature des clés d'autrui, une fois celles ci +validées, ce qui permet de placer sa confiance dans les signataires de la clé.</p> +<p><a class="reference external" 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'il est possible +d'utiliser différents moyens afin de prouver l'identité des personnes. Par +exemple, leurs comptes Twitter, GitHub ou leurs noms de domaines. De la même +manière qu'il est possible de signer (valider) les clés de nos amis, il est +possible de les &quot;tracker&quot; selon le jargon de keybase.</p> +<p>Donc, en somme, <em>Keybase.io</em> est un annuaire, qui tente de rendre plus facile la +création de preuves. Bien.</p> +<div class="section" id="quelques-points-d-ombre"> +<h2>Quelques points d'ombre</h2> +<p>Il s'agit d'une <em>startup</em> américaine, domiciliée dans le Delaware, qui se trouve être +un des paradis fiscaux qui <a class="reference external" 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 class="reference external" href="https://github.com/keybase/keybase-issues/issues/1569">j'ai ouvert un ticket +sur GitHub pour en savoir plus</a> (après tout, le fait +d'être un paradis fiscal permet peut-être d'échapper à certaines lois sur la +requêtes de données). D'autant plus étonnant, la startup n'a pour l'instant <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/788">pas +de *business model*</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 là).</p> +<p>Le service (bien qu'en Alpha), n'est pas mis à disposition sous licence libre, +ce qui pour l'instant empêche quiconque de créer son propre serveur Keybase. +<a class="reference external" href="https://github.com/keybase/">Une partie des composants, cependant, le sont (open source)</a>.</p> +<p>J'ai du mal à croire en des initiatives qui veulent sauver le monde, mais dans +leur coin, je ne comprends pas pourquoi il n'y à pas de documentation sur +comment monter son propre serveur, ou comment les aider à travailler sur la +fédération. Mais bon, c'est pour l'instant une initiative encore fraîche, et je +lui laisse le bénéfice du doute.</p> +<p>Sur le long terme, une infrastructure comme <em>Keybase.io</em>, devra évidemment être +<a class="reference external" href="https://github.com/keybase/keybase-issues/issues/162">distribuée</a>.</p> +<blockquote class="epigraph"> +<p>We'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'd be so happy to get this +right.</p> +<p class="attribution">&mdash;<a class="reference external" href="http://chris.beams.io/posts/keybase/">Chris Coyne, co-founder of Keybase</a></p> +</blockquote> +<p>Afin de se &quot;passer&quot; de leur service centralisé, les preuves générées (qui sont +la force du système qu'ils mettent en place) pourraient être exportées sur des +serveurs de clés existants. C'est quelque chose <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/890">qu'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'on s'y attarde un brin.</p> +<p>Par ailleurs, <a class="reference external" href="https://leap.se/nicknym">d'autres projets qui visent des objectifs similaires</a> existent, via le projet LEAP, mais je n'ai pas +encore creusé.</p> +</div> +Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html<blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi …</p></blockquote><blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi est trop faible ou construit d'une +manière trop prédictible, cette attaque par la force pourrait se revéler +fructueuse en essayant toutes les possibilités.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://www.eff.org/wp/defending-privacy-us-border-guide-travelers-carrying-digital-devices">The Electronic Frontier Foundation</a> (traduction de mon fait)</p> +</blockquote> +<p>Comprendre les concepts et l'écosystème qui permettent d'avoir une vie +numérique chiffrée n'est pas quelque chose d'aisé. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Plusieurs</a> <a class="reference external" 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 existants.</p> +<blockquote class="epigraph"> +<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 système.</p> +<p class="attribution">&mdash;La page de manuel de GPG.</p> +</blockquote> +<p>Une phrase de passe devrait:</p> +<ul class="simple"> +<li>Être suffisamment longue pour être difficile à deviner;</li> +<li>Ne pas être une citation connue (littérature, livres sacrés etc);</li> +<li>Difficile à deviner même pour vos proches;</li> +<li>Facile à se souvenir et à taper;</li> +<li>être unique et non partagée entre différents sites / applications etc.</li> +</ul> +<p>Une des techniques consiste à utiliser des mots du dictionnaire, sélectionnés de +manière aléatoire, puis modifiés.</p> +<div class="figure"> +<img alt="XKCD sur la force des mots de passe." src="https://imgs.xkcd.com/comics/password_strength.png" /> +</div> +<p>Micah Lee <a class="reference external" 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 longues.</p> +<div class="figure"> +<img alt="Capture d'écran du logiciel de génération et de mémorisation des phrases de passe." src="{filename}/static/passphrases.png" /> +</div> +<p>Oui, ce n'est pas aussi simple que ce qu'il y parait. Pour ma part, j'ai une +copie en local de mes clés, dans un fichier chiffré avec une autre clé que j'ai +généré pour l'occasion et que je ne partagerait pas. J'ai par ailleurs +<a class="reference external" href="https://github.com/jamessan/vim-gnupg">configuré</a> mon éditeur de texte pour +pouvoir chiffrer les documents textes par défaut.</p> +<p>J'ai donc regénéré une nouvelle fois mes clés de travail et personnelles, en +utilisant des phrases de passe plus complexes.</p> +<p>Reste encore la question de la sauvegarde de ces clés privées de manière +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.</p> +Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-08:/chiffrement.html<blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise …</strong></li></ul></blockquote><blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise sous surveillance de pans entiers de la vie politique, syndicale, +militante</strong>, mais aussi économique, scientifique, etc. ;</li> +<li>Légalisation massive de pratiques illégales des services de +renseignement et <strong>introduction de techniques de surveillance de masse +des communications électroniques</strong> ;</li> +<li><strong>Absence de contrôle réel et indépendant</strong> a priori par la future +CNCTR, et recours des citoyens illusoires ;</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="https://www.laquadrature.net/fr/lassemblee-nationale-vote-la-surveillance-de-masse-des-citoyens-francais">La Quadrature du Net - L'Assemblée nationale vote la surveillance de +masse des citoyens français !</a></p> +</blockquote> +<p>Je m'étonne que <a class="reference external" href="https://fr.wikipedia.org/wiki/R%C3%A9v%C3%A9lations_d%27Edward_Snowden">les révélations d'Edward Snowden</a> — qui +ont démontré que la plupart des communications électroniques et téléphoniques +pouvaient être scrutés par la NSA, l'agence de sécurité Américaine) — ne +fassent pas plus de remous que ça.</p> +<p>À peine deux années après ces révélations, la France fait passer une loi qui +légitime cette surveillance de masse, à plus de 77% des voies. Pour moi c'est +un signal fort de la perte de valeurs de notre démocratie, et à fortiori de ma +perte de foi en notre forme de démocratie.</p> +<p>Notre liberté d'expression se voit bien évidemment amputée de par la +surveillance généralisée. Sans avoir nécessairement à cacher mes échanges, ce +qui est de la sphère privée devrait pouvoir le rester.</p> +<p>De toute manière, l'email comme on l'utilise traditionnellement est une +hérésie: toutes les parties qui traitent le message peuvent le lire, +(destinataire, auteur et corps du message entre autres). Il est grand temps de +rendre les outils de chiffrement plus simples et ergonomiques.</p> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, envers +mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins pour +rendre le déchiffrement des messages plus longue, &quot;noyer le poisson&quot;.</li> +</ul> +<p>Si vous êtes intéressé(e)s, faites moi signe, je me ferais un plaisir de vous +expliquer ce qui n'est pas si complexe et vise à laisser dans la sphère privée +ce qui devrait l'être à priori.</p> +<p>Une manière simple de se protéger est d'installer Thunderbird avec Enigmail et +de le configurer correctement. Ce n'est pas très compliqué et permet d'avoir +des échanges chiffrés. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à pas.</p> +<p>La clé publique pour me contacter est <a class="reference external" href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et +vous ?</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 autour (<a class="reference external" href="https://supporters.eff.org/donate">Electronic +Fronteer Fondation</a>, <a class="reference external" href="https://tails.boum.org/contribute/how/donate/index.fr.html">Tails</a>, <a class="reference external" href="https://support.laquadrature.net/">La quadrature +du net</a> en france ou d'autres…)</p> +<link href="http://vjs.zencdn.net/4.12/video-js.css" rel="stylesheet"> +<script src="http://vjs.zencdn.net/4.12/video.js"></script> +<video id="MY_VIDEO_1" class="video-js vjs-default-skin" controls + preload="auto" width="640" height="264" poster="MY_VIDEO_POSTER.jpg" + data-setup="{}"> + <source src="https://citizenfour.thecthulhu.com/citizenfour.mp4" type='video/mp4'> + <p class="vjs-no-js">To view this video please enable JavaScript, and + consider upgrading to a web browser that <a + href="http://videojs.com/html5-video-support/" target="_blank">supports + HTML5 video</a></p> +</video>Language2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-01:/language.html<blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux …</p></blockquote><blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux dont c'est la langue maternelle.</p> +<p>Aussi nous savons tous que les concepts qui paraissent similaires sont +souvent différents d'une civilisation à l'autre. Les mots expriment une +culture, une façon de penser et une vision du monde.</p> +<p class="attribution">&mdash;M. Boutros Boutros-Ghali, ancien secrétaire général des Nations Unies</p> +</blockquote> +<p>Je me surprends à préférer le français pour m'exprimer au lieu de l'anglais, +notamment au niveau des articles non techniques.</p> +<p>Il y a quelques années, alors que je terminais mes études en Angleterre et que +je commençais à travailler pour Mozilla, on me proposait de venir aux +États-Unis, ce que j'ai refusé parce qu'exprimer mes points de vue de manière +fine m'était trop difficile dans une langue qui n'était pas la mienne.</p> +<ul class="simple"> +<li>Cela me permet de pouvoir tenir des discours avec des positions et un +argumentaire &quot;fin&quot;, ce qui me serait beaucoup plus difficile dans une langue +que je maitrise moins;</li> +<li>Sans même parler d'argumentaire, les mots utilisés dans ma langue maternelle +me permettent de manœuvrer plus finement et de faire passer des idées de +manière plus efficace;</li> +<li>J'ai l'impression de pouvoir engager plus facilement avec les gens qui +m'entourent géographiquement, par exemple par rapport à la communauté +technophile / pythoniste francophone.</li> +<li>Même si mon niveau d'anglais à progressé, ce n'est pas nécessairement le cas +de mes interlocuteurs.</li> +</ul> +<p>Par contre, cela nuit clairement à engager avec d'autres personnes dont la +langue n'est pas la mienne, dans tels cas, traduire les contenus intéressants +vers l'anglais semble une solution (chronophage).</p> +Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html<p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village …</p><p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village de dire :</p> +<blockquote> +Mais quel mauvais père qui oblige ainsi son fils d'aller à pied !</blockquote> +<p>Le lendemain ils sortent de nouveau.</p> +<p>Le père ayant installé son fils sur l'âne et lui marchant à côté.</p> +<p>Les gens du village dirent alors :</p> +<blockquote> +Quel fils indigne, qui ne respecte pas son vieux père et le laisse aller à pied !</blockquote> +<p>Le jour suivant, ils s'installent tous les deux sur l'âne avant de quitter la maison. +Les villageois commentèrent en disant :</p> +<blockquote> +Ils ne respectent pas leur bête à la surcharger ainsi !</blockquote> +<p>Le jour suivant, ils partirent en portant eux-mêmes leurs affaires, l'âne trottinant derrière eux. +Cette fois les gens du village y trouvèrent encore à redire :</p> +<blockquote> +Voilà qu'ils portent eux-mêmes leurs bagages maintenant ! C'est le monde à l'envers !</blockquote> +<p>De retour à la maison, le père dit à son fils :</p> +<blockquote> +Tu me demandais l'autre jour le secret du bonheur. +Peu importe ce que tu fais, il y aura toujours quelqu'un pour y trouver à redire. +Fais ce qui te plaît et là tu seras vraiment heureux.</blockquote> +What's Hawk and how to use it?2014-07-31T00:00:00+02:002014-07-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.html<p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original …</p><p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original <a class="reference external" href="https://en.wikipedia.org/wiki/OAuth">OAuth</a> specification authors, that intends to +replace the 2-legged OAuth authentication scheme using a simpler approach.</p> +<p>It is an authentication scheme for HTTP, built around <a class="reference external" href="https://en.wikipedia.org/wiki/Hmac">HMAC digests</a> of requests and responses.</p> +<p>Every authenticated client request has an Authorization header containing a MAC +(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 +server.</p> +<div class="section" id="exchange-of-the-hawk-id-and-hawk-key"> +<h2>Exchange of the hawk id and hawk key</h2> +<p>To sign the requests, a client needs to retrieve a token id and a token key +from the 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 class="reference external" href="http://accounts.firefox.com">Firefox Accounts</a> put together a scheme to do that, which acts +like the following:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p>All this derivation crazyness might seem a bit complicated, but don't worry, +we put together some libraries that takes care of that for you automatically.</p> +<p class="last">If you are not interested into these details, you can directly jump to the +next section to see how to use the libraries.</p> +</div> +<p>When your server application needs to send you the credentials, it will return +it inside a specific <cite>Hawk-Session-Token</cite> 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 requests.</p> +<p>In order to get the hawk credentials, you'll need to:</p> +<p>First, do an <a class="reference external" href="http://en.wikipedia.org/wiki/HKDF">HKDF derivation</a> on the +given session token. You'll need to use the following parameters:</p> +<pre class="literal-block"> +key_material = HKDF(hawk_session, &quot;&quot;, 'identity.mozilla.com/picl/v1/sessionToken', 32*2) +</pre> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">The <tt class="docutils literal">identity.mozilla.com/picl/v1/sessionToken</tt> is a reference to this way of +deriving the credentials, not an actual URL.</p> +</div> +<p>Then, the key material you'll get out of the HKDF need to be separated into two +parts, the first 32 hex caracters are the hawk id, and the next 32 ones are the +hawk key.</p> +<p>Credentials:</p> +<div class="highlight"><pre><span></span><span class="nx">credentials</span> <span class="o">=</span> <span class="p">{</span> + <span class="s1">&#39;id&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">0</span><span class="o">:</span><span class="mi">32</span><span class="p">],</span> + <span class="s1">&#39;key&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">32</span><span class="o">:</span><span class="mi">64</span><span class="p">],</span> + <span class="s1">&#39;algorithm&#39;</span><span class="o">:</span> <span class="s1">&#39;sha256&#39;</span> +<span class="p">}</span> +</pre></div> +</div> +<div class="section" id="httpie"> +<h2>Httpie</h2> +<p>To showcase APIs in the documentation, I like to use <a class="reference external" href="https://github.com/jakubroztocil/httpie">httpie</a>, a curl-replacement with a nicer +API, built around <a class="reference external" 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 class="reference external" href="https://github.com/mozilla-services/requests-hawk">I wrote +a wrapper</a> around <a class="reference external" href="https://github.com/kumar303/mohawk">mohawk</a> to add hawk support to the requests lib.</p> +<p>Doing hawk requests in your terminal is now as simple as:</p> +<pre class="literal-block"> +$ pip install requests-hawk httpie +$ http GET localhost:5000/registration --auth-type=hawk --auth='id:key' +</pre> +<p>In addition, it will help you to craft requests using the requests library:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Alternatively, if you don'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 you:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +</div> +<div class="section" id="integrate-with-python-pyramid-apps"> +<h2>Integrate with python pyramid apps</h2> +<p>If you're writing pyramid applications, you'll be happy to learn that <a class="reference external" 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'm chocked how simple it +is to use it.</p> +<p>Here is a demo of how we implemented it for Daybed:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>The <cite>get_hawk_id</cite> function is a function that takes a request and +a tokenid and returns a tuple of <cite>(token_id, token_key)</cite>.</p> +<p>How you want to store the tokens and retrieve them is up to you. The default +implementation (e.g. if you don't pass a <cite>decode_hawk_id</cite> function) decodes the +key from the token itself, using a master secret on the server (so you don't +need to store anything).</p> +</div> +<div class="section" id="integrate-with-node-js-express-apps"> +<h2>Integrate with node.js Express 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 class="reference external" href="https://github.com/mozilla-services/express-hawkauth">express-hawkauth</a>.</p> +<p>In order to plug it in your application, you'll need to use it as +a middleware:</p> +<div class="highlight"><pre><span></span><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express&quot;</span><span class="p">);</span> +<span class="kd">var</span> <span class="nx">hawk</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express-hawkauth&quot;</span><span class="p">);</span> +<span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span> + +<span class="kd">var</span> <span class="nx">hawkMiddleware</span> <span class="o">=</span> <span class="nx">hawk</span><span class="p">.</span><span class="nx">getMiddleware</span><span class="p">({</span> + <span class="nx">hawkOptions</span><span class="o">:</span> <span class="p">{},</span> + <span class="nx">getSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which pass to the cb the key and algorithm for the</span> + <span class="c1">// given token id. First argument of the callback is a potential</span> + <span class="c1">// error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span><span class="nx">key</span><span class="o">:</span> <span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="nx">algorithm</span><span class="o">:</span> <span class="s2">&quot;sha256&quot;</span><span class="p">});</span> + <span class="p">},</span> + <span class="nx">createSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which stores a session for the given id and key.</span> + <span class="c1">// Argument returned is a potential error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span> + <span class="p">},</span> + <span class="nx">setUser</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function that uses req and res, the hawkId when they&#39;re known so</span> + <span class="c1">// that it can tweak it. For instance, you can store the tokenId as the</span> + <span class="c1">// user.</span> + <span class="nx">req</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="nx">tokenId</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">});</span> + +<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;/hawk-enabled-endpoint&quot;</span><span class="p">,</span> <span class="nx">hawkMiddleware</span><span class="p">);</span> +</pre></div> +<p>If you pass the <cite>createSession</cite> parameter, all non-authenticated requests will +create a new hawk session and return it with the response, in the +<cite>Hawk-Session-Token</cite> 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't have any <cite>createSession</cite> parameter +defined.</p> +</div> +<div class="section" id="some-reference-implementations"> +<h2>Some reference implementations</h2> +<p>As a reference, here is how we're using the libraries I'm talking about, in +case that helps you to integrate with your projects.</p> +<ul class="simple"> +<li>The Mozilla Loop server <a class="reference external" href="https://github.com/mozilla-services/loop-server/blob/master/loop/index.js#L70-L133">uses hawk as authentication once you're logged in with +a valid BrowserID assertion</a>; +request, to keep a session between client and server;</li> +<li><a class="reference external" href="https://github.com/spiral-project/daybed/commit/f178b4e43015fa077430798dcd3d0886c7611caf">I recently added hawk support on the Daybed project</a> +(that's a pyramid / cornice) app.</li> +<li>It's also interesting to note that Kumar put together <a class="reference external" href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for the +django rest framework</a></li> +</ul> +</div> +Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html<p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est …</p><p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est +écrivain il est important de se poser des questions sur les textes que l'on +produit, pour qui et dans quel but; il est important de se questionner sur +l'utilité du métier de développeur, et sur l'utilisation des contenus produits.</p> +<p>Je suis un développeur parce que je défends certaines valeurs. Les valeurs du +partage de connaissances, de la collaboration, et de l'émancipation.</p> +<p>Je suis aussi développeur parce qu'il me plait de créer des contenus à partir +de &quot;pas grand chose&quot;. La <em>magie</em> de la création logicielle m'anime, parce que j'ai +l'impression qu'il est possible de faire des choses géniales à partir de ce &quot;pas +grand chose&quot;. Donnez moi un ordinateur et je vous crée une application de +partage de semences paysannes. Un peu comme il est possible de donner une +feuille de papier à un dessinateur pour se retrouver avec un univers magnifique +couché sur papier.</p> +<p>Je me rends compte qu'au fur et à mesure des années, je me laisse ramollir, +absorber par le quotidien et me retrouve à ne plus me poser de questions +quant à l'utilité de mon métier. Pourquoi est-ce que je code ? À qui cela sert +il ? Quelle est ma motivation réelle ?</p> +<p>En travaillant pour Mozilla, on pourrait croire que ce problème est résolu de fait, +puisque après tout, Mozilla, c'est les &quot;protecteurs du web&quot;, des +gentils, et qu'on essaye nécessairement de faire les choses bien…</p> +<div class="section" id="l-omnipresence-technologique"> +<h2>L'omniprésence technologique</h2> +<p>Je ne suis pas convaincu qu'utiliser la technologie de la manière dont on le +fait actuellement est systématiquement une bonne chose:</p> +<p>Depuis 2 ans quasiment maintenant, Mozilla travaille sur un système +d'exploitation mobile, un remplaçant pour les iphones et androides, qui utilise +cette fois ci les technologies du web. Les avantages sont multiples, et le +principal intérêt est de faire un téléphone qui ne soit pas au service +des &quot;gros&quot; du Web mondial (Google et Apple).</p> +<p>Ces &quot;ordiphones&quot; à destination des pays dits &quot;émergents&quot; sont d'ailleurs +construits à faible coût — toujours de manière honteuse, pour la plupart en +chine, dans les mêmes chaines de production que les autres téléphones, mais +c'est un autre débat.</p> +<p>L'idée, assez intéressante d'un point de vue marché (les pays en question +n'ayant que peu de périphériques actuellement semblent un terrain propice à la +diffusion des &quot;ordiphones&quot;), est de donner accès à la technologie, au Web à ces +pays émergents.</p> +<p>L'accès à la technologie pour tous me semble relever de la chimère +productiviste: je conçois que la technologie puisse être un pas en avant assez +fou, notamment lorsque l'on connaît la richesse des contenus qu'on peut trouver +sur le web, mais cette richesse vient aussi avec un certain coût, que nous +avons actuellement du mal, en tant qu'utilisateurs, à contrôler et à mesurer. +Les gens sont beaucoup beaucoup trop connectés.</p> +<p>Je le suis par exemple bien plus souvent que ce que je voudrais l'admettre, que +ce soit pour regarder un film, lire mes emails, communiquer avec des amis, +faire de l'associatif, écrire du code, des billets sur ces carnets…</p> +<p>Cette technologie, omniprésente dans nos vies, je ne sais pas si c'est un +futur que je souhaite partager.</p> +<p>Pour prendre un autre exemple, les bienfaits de la technologie ne viennent pas +seuls. Les réseaux sociaux, qui constituent une bonne part de l'utilisation du +Web, relèvent du culte de la personnalité, de l'individualisme, et ce n'est pas +ce développement que je souhaite pour notre société.</p> +<p>L'idée de base du Web, le fait de faire une toile de connaissances ouverte et +partagée entre tous est en train, petit à petit, de glisser vers l'idée d'un +outil de relai de l'information, où tout va vite, où l'on ne prends guère +plus le temps de lire autre chose que les titres des quotidiens, ou des +&quot;tweets&quot; de cent vingt caractères…</p> +</div> +<div class="section" id="des-outils-utiles"> +<h2>Des outils utiles</h2> +<p>Bon an, mal an, je pense quand même que la technologie puisse être un vecteur +d'émancipation. Plus spécifiquement, je crois qu'il ne faut pas laisser +l'utilisation de la technologie aux &quot;gros&quot;, aux entreprises, aux états ou +&quot;spécialistes&quot;.</p> +<p>Il est important de ne pas laisser ceux que l'on combat s'emparer des &quot;outils +du pouvoir&quot;. La science, la technologie ou les médias sont autant de champs +qu'il est important de défendre, de conserver, de s'approprier.</p> +<p>Un des objectifs que je me fixe, pour les années à venir, ce que j'ai envie de +créer, c'est à la fois des outils utiles pour les organisations, mais aussi +éduquer à ces outils.</p> +<p>Parce que l'éducation populaire ne s'arrête pas aux frontières du numérique, +parce qu'il est important de se battre avec les mêmes outils que ce monde que +l'on cherche parfois à combattre.</p> +<p>Les outils sur lesquels j'ai envie d'être amené à travailler sont des outils +qui favorisent et questionnent la collaboration.</p> +<p>Des outils comme etherpad par exemple, révolutionnent la manière de prendre des +notes en commun, et il reste énormément à faire sur le web à ce propos.</p> +<p>Nombre d'associations me demandent de plus en plus souvent ce qu'il en est de +Daybed, et de quand est-ce qu'on va pouvoir utiliser un système de génération +de formulaires en ligne, qui ne soit pas centré sur les services de google…</p> +<p>Allez, au boulot !</p> +<p>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, <a class="reference external" href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler-fr.html">sur le sens du travail et +de l'informatique</a>, ça fait du bien :)</p> +</div> +Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud Services&quot;.</p> +<p>Depuis, énormément de choses ont évoluées, tant en ce qui concerne les +objectifs de Mozilla (avec l'arrivée de FirefoxOS) que le travail que +j'effectue au jour le jour. Pour autant, mes objectifs personnels restent +intacts.</p> +<p>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 <a class="reference external" href="ziade.org">Tarek</a> par exemple.</p> +<p>Ç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 !</p> +<div class="section" id="services"> +<h2>Services</h2> +<p>Le principal de mon travail a été de construire des outils. Je suis le +mainteneur de <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>, un +utilitaire qui vient se greffer par dessus <a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">le framework python pyramid</a> pour +vous simplifier la vie et créer des services web; J'ai travaillé un peu +sur un outil de gestion des processus nommé <a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a>, et également sur un outil de +montée en charge dénommé <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a></p> +<p>Au tout début, j'ai travaillé sur un concept de <a class="reference external" href="https://github.com/mozilla-services/tokenserver">serveur de +tokens</a>. L'idée était de +désolidariser l'authentification des services web des services eux mêmes.</p> +<p>L'idée est (je pense) bonne mais le service n'a pas été utilisé durant plus de +deux ans. La raison étant principalement que Sync, pour lequel le serveur de +tokens a été écrit, a subi des changements majeurs (qui sont rentrés en +production il y a quelques semaines)</p> +<p>Circus est né de besoins découverts via le token server, et il m'a +personnellement beaucoup appris. Le token server est finalement utilisé dans la +nouvelle version de Sync qui est rentrée en production il y a peu.</p> +</div> +<div class="section" id="marketplace-chouette-on-va-casser-du-serveur"> +<h2>Marketplace (&quot;chouette, on va casser du serveur&quot;)</h2> +<p>Après 6 mois à travailler à Services, Tarek et moi avons commencé à rejoindre +l'équipe du Marketplace pour faire un travail d'&quot;audit de performance&quot;.</p> +<p>L'idée était de prêter main forte à l'équipe du marketplace, mais les détails +étaient alors assez flous. Le code est assez indigeste au premier abord, ce qui +m'avait alors pas mal refroidi. La raison principale étant que le code est +utilisé à la fois par <cite>addons.mozilla.org</cite> et par <cite>marketplace.firefox.com</cite>, +rendant les choses souvent un peu plus compliquées qu'il ne faudrait.</p> +<p>Cet &quot;audit&quot; a été l'occasion de travailler sur des outils de montée en charge +assez sympa, qui ont donné naissance à un projet qu'on utilise assez souvent +maintenant, <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a>.</p> +<p>Énormément d'efforts sont fait pour aller dans la bonne direction et faire en +sorte que le code soit plus facile à maintenir et que le projet soit plus +facile à aborder. D'ailleurs, pas mal de copains djangonautes français +travaillent dessus (salut <a class="reference external" href="http://virgule.net">Mathieu</a>, Yohan, <a class="reference external" href="http://larlet.fr">David</a> et <a class="reference external" href="http://mathieu.agopian.info">Mathieu Agopian</a>!)</p> +<p>Une partie de notre plan a été de sortir certaines fonctionnalités du code +actuel, pour en faire quelque chose de plus facile à maintenir et de moins +imbriqué.</p> +</div> +<div class="section" id="la-communaute"> +<h2>La Communauté</h2> +<p><a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a> et <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a> sont +deux outils qui semblent utiles à la communauté. J'ai eu des retours très +positifs sur Cornice, et j'essaye de le faire évoluer dans la direction qui me +semble propice.</p> +<p>D'ailleurs, Cornice est utilisé (par <a class="reference external" href="http://blog.mathieu-leplatre.info/pages/about.html">Mathieu L.</a> +— encore un —, <a class="reference external" href="http://twitter.com/natim">Rémy</a> et moi) actuellement pour coder +<a class="reference external" href="https://github.com/spiral-project/daybed">Daybed</a> un service de validation +de formulaires, mais ça sera l'objet d'un futur billet.</p> +<p>Circus commence à recevoir des contributions de plus en plus intéressantes, et +à être utilisé en interne chez nous et chez d'autres, donc c'est une +extrêmement bonne nouvelle.</p> +</div> +<div class="section" id="talkilla-loop"> +<h2>Talkilla / Loop</h2> +<p>Après quelques temps, j'avais envie d'apprendre de nouveau. Python c'est génial +mais c'était devenu ma &quot;zone de confort&quot;. J'adore découvrir des choses, donc +c'était le moment de faire en sorte que ça continue!</p> +<p>C'était aussi l'occasion de travailler avec <a class="reference external" href="https://nicolas.perriault.net/">Nicolas</a> et <a class="reference external" href="http://monkeypatch.me/blog/">Romain</a>. +Je suivais le projet Talkilla de plus ou moins loin depuis quelques mois, +c'était donc l'occasion à ne pas manquer.</p> +<p>En rentrant dans cette équipe, je cherchais principalement à avoir un projet +visible pour les utilisateurs finaux. Refaire un peu de frontend, apprendre +à faire du JavaScript propre et découvrir de nouvelles personnes.</p> +<p>J'y ai aussi récupéré une équipe qui essaye de suivre les principes de +l'agilité et qui est sur mon fuseau horaire (pour la plupart). Le rêve.</p> +<p>L'idée derrière Talkilla est d'utiliser la technologie de communication pair +à pair dans les navigateurs (WebRTC) pour faire des appels audio / vidéo. En +d'autres termes, c'est un peu transformer votre firefox en téléphone, sauf que +personne ne peut espionner ce qui se passe entre vous et l'autre bout du fil.</p> +<p>A peine arrivé dans le projet (peut-être un mois et quelques après mon +débarquement) le choix a été fait de tout réécrire depuis zéro, dans un projet +qui se nomme actuellement &quot;Loop&quot;, qui veut proposer la même chose, mais inclus +directement dans Firefox.</p> +<p>C'est en bonne voie, on a quelque chose qui fonctionne dans nightly, et le code +du serveur fonctionne pas mal. Le code du serveur est ici: +<a class="reference external" href="https://github.com/mozilla-services/loop-server">https://github.com/mozilla-services/loop-server</a>.</p> +<p>Un client est en train d'être implémenté dans Firefox et un autre en tant +qu'application pour FirefoxOS. Le boulot ne s'arrête pas de pleuvoir, mais je +pense qu'on va dans une direction intéressante.</p> +<p>Pour être complètement terminé, il faudrait qu'on soit capable de se passer +complètement de notre provider, TokBox (que l'on utilise en tant que relai +média), pour que n'importe qui puisse choisir d'utiliser son propre serveur +STUN / TURN et installe son serveur loop chez lui.</p> +<div class="section" id="le-travail-a-distance"> +<h3>Le travail à distance</h3> +<p>Quand j'ai commencé à travailler à Mozilla, j'ai décidé de venir m'installer +à Paris. La plupart des personnes de mon entourage ont d'ailleurs fait des gros +yeux, parce qu'ils connaissaient mon avis sur la ville en question, mais casser +des préjugés n'est jamais une mauvaise chose.</p> +<p>Après deux ans passés à Paris, j'ai décidé de partir m'installer à Rennes, +puisque de toute manière, la plupart de mon travail s'effectue au jour le jour +à distance. En d'autres termes, la plupart de mon équipe n'est pas à coté de +moi quand je travaille, ce qui veut dire que je peux travailler depuis +n'importe où.</p> +<p>Ce qui fonctionne pour moi, c'est de ne quasiment jamais travailler depuis la +maison. J'utilise <a class="reference external" href="http://www.lacantine-rennes.net/">un espace de coworking</a> +qui est un moyen de garder ma vie perso séparée de ma vie privée et de +rencontrer des gens passionnés par ce qu'ils font.</p> +<p>Depuis que je suis arrivé à Rennes, Rémy a commencé à travailler avec moi, et +c'est un réel bonheur que de pouvoir partager des journées de travail. On +&quot;pair-prog&quot; énormément et j'ai l'impression d'avoir un boost dans ma +productivité quotidienne.</p> +</div> +<div class="section" id="enseignements"> +<h3>Enseignements</h3> +<p>Mozilla est ma première expérience professionnelle, et par conséquent, je +manque nécessairement de recul sur ce qui est acceptable et ce qui ne l'est +pas. D'une manière générale, avoir un environnement de travail basé sur la +confiance est réellement appréciable (La première réaction des gens quand je +dis que je peux travailler à distance, c'est de me demander comment ils font +pour être sur que je travaille. Et la réponse est… il n'y en a pas).</p> +<p>J'ai encore un peu de mal à savoir quels indicateurs utiliser pour savoir si je +suis &quot;productif&quot; ou non, mais j'ai globalement l'impression que je manque de +concentration et de discipline: beaucoup d'interruptions n'aident pas à se +concentrer.</p> +<p>La motivation fluctue aussi énormément: un jour on est super motivé, un autre +c'est juste impossible de la trouver. Après quelques expérimentations, le mieux +(pour moi) est d'avoir des horaires fixes, pour pouvoir séparer le travail du +reste, de ne pas hésiter à faire des pauses et d'écouter un peu ses envies et +son corps (si je suis crevé, ça ne sert à rien de se lever pour aller +travailler, il vaut mieux se reposer un peu pour être plus efficace ensuite, +par exemple).</p> +<p>J'ai essayé de tirer quelques enseignements de ces deux années:</p> +</div> +</div> +<div class="section" id="malheureusement-le-code-n-est-pas-propre"> +<h2>Malheureusement, le code n'est pas propre</h2> +<p>Je me rends compte que bien souvent je suis assez déçu de la qualité du code +que je regarde. Principalement parce que je ne suis pas capable de le +comprendre rapidement. Spécifiquement, ça m'est arrivé avec certaines parties +de <a class="reference external" href="https://github.com/mozilla/zamboni">Zamboni</a>, le code du <a class="reference external" href="http://marketplace.firefox.com">Marketplace</a> dont je parlais plus haut, avec certaines +parties de Talkilla ou alors le code de Firefox lui même.</p> +<p>C'était extrêmement frustrant pour moi de découvrir que le code écrit à Mozilla +n'était pas exemplaire. Tout le code qui est ajouté à l'heure actuelle est +revu, corrigé et validé par des pairs, mais un certain nombre de projets ont un +historique assez lourd qui rends leur structure complexe.</p> +<p>Je réalise donc que mon travail n'est pas uniquement de savoir écrire du code +propre, mais également de réussir à comprendre du code que je considère comme +&quot;sale&quot; (quitte à l'améliorer au passage !).</p> +<p>Et c'est pas du gâteau; je m'attendais à réussir à comprendre des projets +complexes facilement, mais aucun miracle de ce coté là. Il faut réussir +à rester concentré pendant suffisamment longtemps pour pouvoir tirer tous les +fils et commencer à démêler… Pas facile !</p> +</div> +<div class="section" id="apprendre-est-un-processus-actif"> +<h2>Apprendre est un processus actif</h2> +<p>Il est facile de passer à coté de l'apprentissage. Être entouré de gens +talentueux ne suffit pas pour continuer à apprendre.</p> +<p>Savoir reconnaitre un échec est nécessaire. Dire que l'on comprends pour éviter +de passer pour un idiot est un biais qui se prends assez rapidement, et qu'il +faut éviter à tout prix.</p> +<p>Surtout au début, c'était une erreur que je faisais énormément, une question +d'égo probablement.</p> +<p>Il y a une espèce de honte de ne pas savoir, alors que tout le monde autour +sait ou en tout cas semble savoir. Bien souvent, les gens autour ne savent pas +non plus, ce qui mène à des discussions de comptoir, sans trop savoir pourquoi.</p> +<p>Connaître ses limites techniques est un bon début pour pouvoir les surpasser. +Chercher à les rencontrer est un processus actif.</p> +<p>Le manque de temps m'empêche bien souvent de pouvoir prendre un livre technique +et de pouvoir l'apprécier. Je ne sais pas exactement pourquoi, peut être par +sur-dose, mais je n'ai ouvert que quelques rares livres techniques durant ces +deux années. Et j'aimerais bien que ça change !</p> +</div> +<div class="section" id="assez-bien-est-suffisant"> +<h2>&quot;Assez bien&quot; est suffisant</h2> +<p>La culture de l'excellence se mets parfois au milieu du chemin. On oublie +souvent que &quot;le mieux est l'ennemi du bien&quot;.</p> +<p>Rien ne sert de faire des commits parfaits tout le temps. Quand j'ai besoin de +&quot;hacker&quot; sur un projet, je ne voulais d'abord pas tout péter, par peur de ne +plus m'y retrouver.</p> +<p>Mon approche actuelle est bien différente: on mets les mains dans le cambouis +jusqu'à ce que ça marche, et ensuite on répare les dégâts. Enfin… dans une +certaine mesure hein !</p> +</div> +<div class="section" id="ecrire-des-boites-a-outils-et-non-pas-des-frameworks"> +<h2>Écrire des boites à outils et non pas des frameworks</h2> +<p>Écrire des frameworks force les utilisateurs à les utiliser, et à les connaitre +dans les moindres recoins. Heureusement, il existe déjà énormément de +frameworks qui pour la plupart font très bien leur travail. Ce qui nous manque +ce n'est pas plus de frameworks, mais bel et bien plus de boites à outils.</p> +<p>Une boite à outil prends un problème bien défini et propose une solution pour +ce problème. Une boite à outils est, en mon sens, ce qu'on appelle une +bibliothèque. Pas besoin de réécrire tout votre projet pour utiliser ma +nouvelle bibliothèque afin de profiter des fonctionnalités qu'elle apporte +(alors que c'est le cas avec un framework, justement).</p> +</div> +<div class="section" id="etre-le-moteur-de-son-propre-changement"> +<h2>Être le moteur de son propre changement</h2> +<p>Facile à dire, héhé ! D'une manière générale, je me rends compte qu'il est +facile de se plaindre sans pour autant être moteur du changement que l'on +souhaite voir arriver.</p> +<p>Ça vaut le coup de se donner la peine de faire changer les choses, surtout +à Mozilla, parce que le changement n'est pas seulement vu d'un mauvais œil.</p> +<p>Pour que les choses évoluent, il faut être force de proposition. Se plaindre +n'a jamais servi à rien si ce n'est pas suivi d'actes ;)</p> +<p>Je dis de temps en temps que Mozilla est une &quot;do-o-cratie&quot; (celui qui fait +à raison), et je le pense de plus en plus. Quand j'ai envie que quelque chose +soit fait, et bah… il faut le faire !</p> +</div> +<div class="section" id="ne-pas-chercher-a-avoir-raison"> +<h2>Ne pas chercher à avoir raison</h2> +<p>Peu importe qui a raison, l'important n'est pas de chercher à montrer que tu +sais, mais de trouver ce qui est juste. Ça parait peut être évident, mais bien +souvent on cherche à se mettre en avant, au détriment du projet… Allez, gardons +nos égos de coté ;)</p> +</div> +<div class="section" id="arreter-le-negativisme"> +<h2>Arrêter le négativisme</h2> +<p>Il est très facile de se laisser embarquer dans le négativisme. Il y a toujours +des choses qui ne vont pas, et probablement il y en aura toujours. Ce ne sont +pas des raisons suffisantes pour perdre le moral. Identifier les points faibles +est important est permet de savoir ce qu'il est nécessaire d'améliorer, mais +regarder les choses du coté positif (et il y en a nécessairement un !) est +indispensable !</p> +<p>À plusieurs reprises je me suis retrouvé dans des crises de négativisme, pour +un tas de raisons différentes. La meilleure manière de s'en sortir: en causer +et trouver des solutions, prendre le problème à bras le corps, et ne pas +considérer que c'est un problème sur lequel on a aucune prise possible.</p> +<div class="section" id="la-suite"> +<h3>La suite ?</h3> +<p>Je n'ai aucune idée d'à quoi va ressembler la suite, et c'est justement ce que +j'apprécie et qui m'effraie en même temps…</p> +<p>Je fais actuellement énormément de Javascript et je travaille sur des +projets qui semblent avoir plus de sens qu'avant (même si je vois déjà des +choses que je souhaiterais améliorer, mais chaque chose en son temps). Donc +techniquement j'apprends et dans ma quête de faire des produits qui touchent un +utilisateur.</p> +<p>Depuis quelques semaines, je peux travailler une journée par semaine sur un +projet qui me tiens vraiment à cœur: daybed (<a class="reference external" href="http://daybed.rtfd.org">http://daybed.rtfd.org</a>). +L'objectif est de faire en sorte que le projet avance et soit utilisé au sein +de mozilla.</p> +<p>Avant toute autre chose, il faudra faire des changements de &quot;pitch&quot; pour qu'il +soit plus simple d'expliquer ce que Daybed souhaite faire, mais… c'est une autre +histoire.</p> +</div> +</div> +Le revenu de base2013-10-03T00:00:00+02:002013-10-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-10-03:/le-revenu-de-base.html<iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra …</p><iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra pas suffire à toute la population. En refusant +l'idée du RDB, on est obligé de croire en la croissance économique.</p> +<p>Différence entre une approche qantitative du travail VS une approche sociale.</p> +<p>La croissance éco ≠ croissance de l'emploi.</p> +<p>Parallelle entre le RDB et la déclaration des droits de l'homme. &quot;Et qui voudra +faire le sale boulot ?&quot;</p> +<p>Utopie veut dire le &quot;non lieu&quot;, le lieu qu'on à pas encore trouvé ici sur +terre, à part dans notre imaginaire.</p> +<p>Agriculture: Il y à 100 ans, qqn qui travaillait dans l'agriculture produisait assez pour +3 autres personnes. ajd un agriculteur produit assez pour 120 personnes, via +des machines énormes et à la rationalisation.</p> +<p>Rationalisation: moins d'emploi.</p> +<p>La condition de pouvoir refuser un travail est très importante.</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Le financmenet est acquis, la dificulté c'est la liberté</p> +<p class="attribution">&mdash;NA</p> +</blockquote> +<blockquote> +<p>Il faut en finir avec cette idée fausse, selon laquelle seul le travail +rémunéré constitue une contribution méritoire à la société, en réalité, c'est +souvent exactement l'inverse.</p> +<p class="attribution">&mdash;Katja Kipping, membre du parlement allemand.</p> +</blockquote> +<blockquote> +<p>Si les gens on déjà une sécurité matérielle, ils sont plus difficiles +à corrompre.</p> +<p class="attribution">&mdash;Katja Kipping</p> +</blockquote> +<blockquote> +<p>Soutenir les populations sans poser de condition. c'est un principe qui à la +longe, devra s'imposer. Mais il lui faudra d'abord affronter les droits et +privilèges dont on bénéficie aujourd'hui.</p> +<p class="attribution">&mdash;Anonyme.</p> +</blockquote> +<blockquote> +Si les revenus étaient uniquement lié au travail, il faudrait donner les plus +hauts revenus aux machines.</blockquote> +<p>Le sens de l'économie, c'est de libérer l'homme du travail Beaucoup de gens qui +ont une &quot;place de travail&quot;, n'ont en réalité qu'une &quot;place de revenu&quot;.</p> +</div> +<div class="section" id="chiffres"> +<h2>Chiffres</h2> +<p>Un sondage à été effectué. La question est: &quot;Si vous aviez un revenu de base, +est-ce que vous iriez encore travailler ?&quot;</p> +<ul class="simple"> +<li>~60% disent oui</li> +<li>30% répondent oui, mais plus à plein temps.</li> +<li>10% pour faire autre chose.</li> +</ul> +<p>Avec une question différente:</p> +<p>&quot;Si on instaurait un revenu de base, est-ce que vous pensez que les autres +iraient travailler ?&quot;</p> +<ul class="simple"> +<li>~80% répondent non.</li> +</ul> +<p>C'est un changement aussi dans les modes d'éducation, on nous enseigne à être +&quot;employable&quot;, et non pas à apprendre quelque chose qui nous interesse. Les gens +ont peur de ne pas trouver du travail.</p> +</div> +<div class="section" id="ressources"> +<h2>Ressources</h2> +<ul class="simple"> +<li>Le sens commun, Thomas Payne.</li> +<li>Peter Ulrich</li> +</ul> +</div> +<div class="section" id="comment-financer-le-rdb"> +<h2>Comment financer le RDB</h2> +<p>Si l’on se fie à son produit intérieur brut (PIB), la France est aujourd’hui le +cinquième pays le plus riche du monde. En 2010, le revenu disponible (après +versement des pres- tations sociales et prélèvement des impôts directs) s’y +élevait à 1 276 euros par mois et par personne, adultes et enfants confondus. +Nous disposons donc de ressources suffisantes pour garantir à chaque individu 1 +276 euros si l’on décidait d’opérer un partage strictement égalitaire. C’est +nettement plus que le seuil de pauvreté actuel, fixé en France à 60 % du revenu +médian (1), soit 960 euros par adulte. Qui peut le plus pouvant le moins, la +France a donc sans nul doute les moyens d’assurer à tous ses résidents un +revenu au moins égal au seuil de pauvreté.</p> +</div> +<div class="section" id="a-reculons-par-andre-gorz"> +<h2>À Reculons, par André Gorz.</h2> +<p>(Paru dans le monde diplomatique de Juin 1990)</p> +<p><em>Proche de Jean-Paul Sartre, cofondateur, en 1964, du Nouvel Observateur, le +philosophe André Gorz (1923-2007) s’est converti progressivement à un +écosocialisme dont il est devenu l’un des principaux théoriciens. En 1990, dans +nos colonnes, sous le titre « Pourquoi la société salariale a besoin de +nouveaux valets », il formulait une critique de l’idéologie du travail qui +devait l’amener quelques années plus tard à se prononcer en faveur d’un revenu +d’existence.</em></p> +<p>Dans l’ensemble des pays capitalistes d’Europe, on produit trois à quatre fois +plus de richesses qu’il y a trente-cinq ans ; cette production n’exige pas +trois fois plus d’heures de travail, mais une quantité de travail beaucoup plus +faible. (...)</p> +<p>Nous sortons de la civilisation du travail, mais nous en sortons à reculons, et +nous entrons à reculons dans une civilisation du temps libéré, incapables de la +voir et de la vouloir, incapables donc de civiliser le temps libéré qui nous +échoit, et de fonder une culture du temps disponible et une culture des +activités choisies pour relayer et compléter les cultures techniciennes et +profes- sionnelles qui dominent la scène. (...)</p> +<p>Pour près de la moitié de la population active, l’idéologie du travail est +devenue une mauvaise farce ; l’identification au travail est désormais +impossible, car le système économique n’a pas besoin ou n’a pas un besoin +régulier de leur capacité de travail. La réalité que nous masque l’exaltation +de la « ressource humaine », c’est que l’emploi stable, à plein temps, durant +toute l’année et toute la vie active, devient le privilège d’une minorité. +Pour [les autres], le travail cesse d’être un métier qui intègre dans une +communauté productive et définit une place dans la société. Ce que le patronat +appelle « flexibilité » se traduit pour les salariés par la précarité. (...)</p> +<p>Que doit être une société dans laquelle le travail à plein temps de tous les +citoyens n’est plus nécessaire, ni économiquement utile ? Quelles priorités +autres qu’économiques doit-elle se donner ? Comment doit-elle s’y prendre pour +que les gains de productivité, les économies de temps de travail profitent à +tout le monde ? Comment peut-elle redistribuer au mieux tout le travail +socialement utile de manière à ce que tout le monde puisse travailler, mais +travailler moins et mieux, tout en recevant sa part des richesses socialement +produites ?</p> +<p>La tendance dominante est d’écarter ce genre de questions et de poser le +problème à l’envers : comment faire pour que, malgré les gains de productivité, +l’économie consomme autant de travail que par le passé ? Comment faire pour que +de nouvelles activités rémunérées viennent occuper ce temps que, à l’échelle de +la société, les gains de productivité libèrent ? A quels nouveaux domaines +d’activité peut-on étendre les échanges marchands pour remplacer tant bien que +mal les emplois supprimés par ailleurs dans l’industrie et les services +industrialisés ?</p> +<p>On connaît la réponse, pour laquelle les Etats-Unis et le Japon ont montré la +voie : le seul domaine dans lequel il est possible, en économie libérale, de +créer à l’avenir un grand nombre d’emplois, c’est celui des services aux +personnes. Le développement de l’emploi pourrait être illimité si l’on +parvenait à transformer en prestations de services rétribuées les activités que +les gens ont, jusqu’à présent, assumées chacun pour soi. Les économistes +parlent à ce sujet de « nouvelle croissance plus riche en emplois », de « +tertiarisation » de l’économie, de « société de services » prenant le relais de +la « société industrielle » (1). (...)</p> +<p>Le problème de fond auquel nous sommes confrontés est celui d’un au-delà de +l’économie et, ce qui revient au même, d’un au- delà du travail rémunéré. La +rationalisation économique libère du temps, elle continuera d’en libérer, et il +n’est plus possible, par conséquent, de faire dépendre le revenu des citoyens +de la quantité de travail dont l’économie a besoin. Il n’est plus possible, non +plus, de continuer à faire du travail rémunéré la source principale de +l’identité et du sens de la vie pour chacun.</p> +<p>La tâche d’une gauche, si gauche il doit y avoir, consiste à transformer cette +libération du temps en une liberté nouvelle et en des droits nouveaux : le +droit de chacun et de chacune de gagner sa vie en travaillant, mais en +travaillant de moins en moins, de mieux en mieux, tout en recevant sa pleine +part de la richesse socialement produite. Le droit, d’autre part, de travailler +de façon discontinue, intermittente, sans perdre durant les intermittences de +l’emploi le plein revenu – de manière à ouvrir de nouveaux espaces aux +activités sans but économique 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.</p> +</div> +Notes: Économie libidinale et économie politique2013-07-06T00:00:00+02:002013-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-06:/notes-economie-libidinale-et-economie-politique.html<p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un …</p><p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un autre comportement s'est développé: le modèle &quot;collaboratif et contributif&quot;. +Ce modèle ne se repose pas sur la consommation mais sur l'implication et la +collaboration. Ce modèle est induit par internet, qui ne repose plus sur +l'opposition production / consommation.</p> +<p>Sur internet nous ne sommes pas des simples consommateurs, puisque vous êtes un +expéditeur / distributeur.</p> +<p>Le changement prduit par internet est le fait que les gens ne sont plus +simplement des consommateurs,mais sont également producteurs de contenus +/ viennent améliorer les contenus existants.</p> +<p>Note perso: quid du culte de la personalité qui en ressort ? Ce qu'il apelle +l'écologie relationelle ?</p> +<p>Quel est le manque que vient combler facebook par exemple ? Et quel est +l'impact que ces nouveaux réseaux ont sur les modèles relationels que l'ont +connait (famille, école, droit, etc.).</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Une révolution c'est le fait de faire une boucle est d'arriver au terme de +quelque chose. D'avoir clôt un cycle. La lune fait des révolutions aussi.</p> +<p>81% des Américains déclarent que le consumerisme est une plaie pour l'amérique +(d'après Juliet Score)</p> +</blockquote> +</div> +New year python meme, 20122013-07-01T00:00:00+02:002013-07-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-01:/new-year-python-meme-2012.html<p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this …</p><p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this year and +quite enjoyed it. I like the way they bring back some nice concepts on the +table, and how they compete with other frameworks. That's nicely decomposed and +everything fits together really well. I learned a bit about its internal +routing mechanism when working on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, and +it's really well done.</p> +<p><strong>2. What new programming technique did you learn in 2012 ?</strong></p> +<p>I learned about asynchronous programming, something I wasn't really aware of. +(Yes, that's a shame). This was really helpful to understand some bits of +<a class="reference external" href="http://circus.io">Circus</a>. I also started to learn about some related +concepts present in <a class="reference external" href="http://golang.org">go</a> or in <a class="reference external" href="http://erlang.org">erlang</a> with <a class="reference external" href="http://en.wikipedia.org/wiki/Actor_model">the actor model</a></p> +<p><strong>3. Which open source project did you contribute to the most in 2012 ? What did +you do ?</strong></p> +<p>I worked a bunch on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a> and <a class="reference external" href="http://circus.io">Circus</a>, not as much as I would like, but that was two really +interesting projects. For Cornice, I completely <a class="reference external" href="http://blog.notmyidea.org/refactoring-cornice.html">refactored the internals</a> back in May, and since +that, I added support for <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a> +and am currently working on porting it to Python 3 and adding support for <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>. For Circus, I worked on the web interface and +on other bits of the projects related to stats.</p> +<p>I didn't contributed that much to <a class="reference external" href="http://getpelican.com">Pelican</a>, mainly +because I'm less excited about it than I was previously: the project is +working and needs to focus more on code quality than features. We started in +this direction, hopefully it will pay-off; but I committed a lot less code than +previously.</p> +<p><strong>4. Which Python blog or website did you read the most in 2012 ?</strong></p> +<p>I really don't know. I found some interesting python-related news on <a class="reference external" href="http://news.ycombinator.com/">hacker +news</a> and on the printed version as well, +<a class="reference external" href="http://hackermonthly.com/">hacker monthly</a>. Twitter and IRC got me some +interesting articles as well.</p> +<p><strong>5. What are the three top things you want to learn in 2013 ?</strong></p> +<p>On the computer science side, I want to learn more about other paradigms, maybe +in other languages. I like python, but I want to learn about other concepts, +maybe some of them don't really fit with python.</p> +<p>For instance, I don't know that much about pattern matching or about the actor +model. Well I know what it is, but I would like to make good use of them in +order to have something nice and useful.</p> +<p>Also, I want to learn how to make a product. From scratch. Which means +designing, implementing and maintaining something. Maybe this will be the case +with <a class="reference external" href="https://github.com/spiral-project/daybed">daybed</a> ? Who knows.</p> +<p>I want to get better at building communities. Working with others is something +that can be complex and quite hard sometimes. I want to learn how to handle +this better.</p> +<p>On the other side, I want to learn about tons of other non-tech things: taking +pictures, finding a good balance between life and work, working with children, +teaching and animating workshops, writing articles, be better at reading (being +critic when I'm thinking!).</p> +<p><strong>6. What is the top software, application or library you wish someone would +write in 2013 ?</strong></p> +<p>The one missing thing, IMO, is a <strong>good</strong> webmail reader, in python. One we +could contribute to, one we could write features for, and one that could come +and compete with gmail, in term of features of UI.</p> +<p>However, most of the time, I'm just impressed by the new ideas that come from +others. I would like to have a library to handle the actor model in a nice way +in Python, I would like to see packaging fixed in python :-)</p> +<p>Want to do your own list? Here's how:</p> +<ul class="simple"> +<li>copy-paste the questions and answer to them in your blog</li> +<li>tweet it with the #2012pythonmeme hashtag</li> +</ul> +François Elie : Quelle école pour la société de l’information ?2013-06-14T00:00:00+02:002013-06-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-06-14:/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html<p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens …</p></blockquote><p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens font ça entre eux et on n’est pas non plus +dans une école de l’apprentissage où l’école a pour but de donner un métier, un +bagage utilisable. L’école ne sert évidemment pas à ça. D’ailleurs heureusement +parce que sinon on n’enseignerait pas la philosophie qui ne sert à rien à part +fabriquer des profs de philosophie !</p> +<p>On n’a pas besoin de tableau numérique pour enseigner l’informatique elle-même +pour enseigner la science. De la même façon on n’a pas besoin de machine à +calculer pour enseigner les mathématiques. Évidemment ! On n’a pas besoin d’une +machine à calculer pour savoir faire une division. Au contraire, surtout pas !</p> +<p>Il faut cesser d’opposer l’enseignement de la programmation d’une part et +l’enseignement des usages, c’est important mais ça c’est l’école des maîtres et +des esclaves. Ce qu’il faut enseigner, vite et à tous, c’est la science, pas la +technologie ou l’usage. C’est en amont de la programmation, l’algorithmique. +C’est, en amont de telle instanciation, du codage, du chiffrement, la théorie, +quelque chose qui comme les maths n’ont besoin que d’une craie et d’un tableau +noir.</p> +<p>Ce n'est pas un hasard si le mot &quot;numérique&quot; à remplaçé le mot &quot;informatique&quot;, +c'est qu'on voudrait nous faire croire qu'il n'y a pas besoin de l'apprendre.</p> +</blockquote> +Implementing CORS in Cornice2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/cross-origin-in-cornice.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In other +words, if you have a page served from the domain <cite>lolnet.org</cite>, it will not be +possible for it to get data from <cite>notmyidea.org</cite>.</p> +<p>Well, it's possible, using tricks and techniques like <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a>, but that doesn't work all the time (see +<a class="reference external" 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's API.</p> +<p>Thankfully, there is a nicer way to do this, namely, &quot;Cross Origin +Resource-Sharing&quot;, or <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>.</p> +<div class="section" id="you-want-an-icecream-go-ask-your-dad-first"> +<h2>You want an icecream? Go ask your dad first.</h2> +<p>If you want to use CORS, you need the API you're querying to support it; on the +server side.</p> +<p>The HTTP server need to answer to the <cite>OPTIONS</cite> verb, and with the appropriate +response headers.</p> +<p><cite>OPTIONS</cite> is sent as what the authors of the spec call a &quot;preflight request&quot;; +just before doing a request to the API, the <em>User-Agent</em> (the browser most of +the time) asks the permission to the resource, with an <cite>OPTIONS</cite> call.</p> +<p>The server answers, and tell what is available and what isn't:</p> +<img alt="The CORS flow (from the HTML5 CORS tutorial)" src="images/cors_flow.png" /> +<ul class="simple"> +<li>1a. The User-Agent, rather than doing the call directly, asks the server, the +API, the permission to do the request. It does so with the following headers:<ul> +<li><strong>Access-Control-Request-Headers</strong>, contains the headers the User-Agent +want to access.</li> +<li><strong>Access-Control-Request-Method</strong> contains the method the User-Agent want +to access.</li> +</ul> +</li> +<li>1b. The API answers what is authorized:<ul> +<li><strong>Access-Control-Allow-Origin</strong> the origin that's accepted. Can be <cite>*</cite> or +the domain 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 methods.</li> +<li><strong>Access-Allow-Headers</strong> a list of allowed headers, for all of the +methods, since this can be cached as well.</li> +</ul> +</li> +<li><ol class="first arabic" start="2"> +<li>The User-Agent can do the &quot;normal&quot; request.</li> +</ol> +</li> +</ul> +<p>So, if you want to access the <cite>/icecream</cite> resource, and do a PUT there, you'll +have the following flow:</p> +<pre class="literal-block"> +&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 +</pre> +<p>You can see that we have an <cite>Origin</cite> Header in the request, as well as +a <cite>Access-Control-Request-Methods</cite>. We're here asking if we have the right, as +<cite>notmyidea.org</cite>, to do a <cite>PUT</cite> request on <cite>/icecream</cite>.</p> +<p>And the server tells us that we can do that, as well as <cite>GET</cite> and <cite>DELETE</cite>.</p> +<p>I'll not cover all the details of the CORS specification here, but bear in mind +than with CORS, you can control what are the authorized methods, headers, +origins, and if the client is allowed to send authentication information or +not.</p> +</div> +<div class="section" id="a-word-about-security"> +<h2>A word about security</h2> +<p>CORS 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 CORS, so you'll need to +write a proxy yourself, to provide this.</p> +<p>Secondly, if misunderstood, CORS 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're authorizing.</p> +<p>An incorrectly secured CORS 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 VPN 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 want.</p> +</div> +<div class="section" id="how-this-is-different-from-jsonp"> +<h2>How this is different from JSONP?</h2> +<p>You may know the <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> protocol. JSONP +allows cross origin, but for a particular use case, and does have some +drawbacks (for instance, it's not possible to do DELETEs or PUTs with JSONP).</p> +<p>JSONP exploits the fact that it is possible to get information from another domain +when you are asking for javascript code, using the <cite>&lt;script&gt;</cite> element.</p> +<blockquote> +Exploiting the open policy for &lt;script&gt; elements, some pages use them to +retrieve JavaScript code that operates on dynamically generated +JSON-formatted data from other origins. This usage pattern is known as +JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. +They are evaluated by the JavaScript interpreter, not parsed by a JSON +parser.</blockquote> +</div> +<div class="section" id="using-cors-in-cornice"> +<h2>Using CORS in Cornice</h2> +<p>Okay, things are hopefully clearer about CORS, let's see how we +implemented it on the 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 CORS support as +well.</p> +<p>In Cornice, you define a service like this:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>To add CORS support to this resource, you can go this way, with the +<cite>cors_origins</cite> parameter:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> +</pre></div> +<p>Ta-da! You have enabled CORS for your service. <strong>Be aware that you're +authorizing anyone to query your server, that may not be what you want.</strong></p> +<p>Of course, you can specify a list of origins you trust, and you don't need +to stick with <cite>*</cite>, which means &quot;authorize everyone&quot;.</p> +<div class="section" id="headers"> +<h3>Headers</h3> +<p>You can define the headers you want to expose for the service:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> + +<span class="nd">@foobar.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> +</pre></div> +<p>I've done some testing and it wasn't working on Chrome because I wasn't +handling the headers the right way (The missing one was <cite>Content-Type</cite>, 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 developing.</p> +<p>So I introduced an <cite>expose_all_headers</cite> flag, which is set to <cite>True</cite> by +default, if the service supports CORS.</p> +</div> +<div class="section" id="cookies-credentials"> +<h3>Cookies / Credentials</h3> +<p>By default, the requests you do to your API endpoint don't include the +credential information for security reasons. If you really want to do that, +you need to enable it using the <cite>cors_credentials</cite> parameter. You can activate +this one on a per-service basis or on a per-method basis.</p> +</div> +<div class="section" id="caching"> +<h3>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's not redone before each actual call.</p> +<p>The caching period is defined by the server, using the <cite>Access-Control-Max-Age</cite> +header. You can configure this timing using the <cite>cors_max_age</cite> parameter.</p> +</div> +<div class="section" id="simplifying-the-api"> +<h3>Simplifying the API</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 CORS-policy for your services, that +can be a bit tedious to pass these to your services all the time.</p> +<p>I introduced another way to pass the CORS policy, so you can do something like +that:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">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> +</pre></div> +</div> +</div> +<div class="section" id="comparison-with-other-implementations"> +<h2>Comparison with other implementations</h2> +<p>I was curious to have a look at other implementations of CORS, in +django for instance, and I found <a class="reference external" href="https://gist.github.com/426829.js">a gist about it</a>.</p> +<p>Basically, this adds a middleware that adds the &quot;rights&quot; headers to the answer, +depending on the request.</p> +<p>While this approach works, it's not implementing the specification completely. +You need to add support for all the resources at once.</p> +<p>We can think about a nice way to implement this specifying a definition of what's +supposed to be exposed via CORS and what shouldn't directly in your settings. +In my opinion, CORS support should be handled at the service definition level, +except for the list of authorized hosts. +Otherwise, you don't know exactly what's going on when you look at the definition of the service.</p> +</div> +<div class="section" id="resources"> +<h2>Resources</h2> +<p>There are a number of good resources that can be useful to you if you want to +either understand how CORS works, or if you want to implement it yourself.</p> +<ul class="simple"> +<li><a class="reference external" href="http://enable-cors.org/">http://enable-cors.org/</a> is useful to get started when you don't know anything +about CORS.</li> +<li>There is a W3C wiki page containing information that may be useful about +clients, common pitfalls etc: <a class="reference external" href="http://www.w3.org/wiki/CORS_Enabled">http://www.w3.org/wiki/CORS_Enabled</a></li> +<li><em>HTML5 rocks</em> has a tutorial explaining how to implement CORS, with <a class="reference external" 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 class="reference external" href="http://caniuse.com/#search=cors">clients support-matrix for this feature</a>.</li> +<li>About security, <a class="reference external" href="https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity">check out this page</a></li> +<li>If you want to have a look at the implementation code, check <a class="reference external" href="https://github.com/mozilla-services/cornice/pull/98/files">on github</a></li> +</ul> +<p>Of course, the W3C specification is the best resource to rely on. This +specification isn't hard to read, so you may want to go through it. Especially +the <a class="reference external" href="http://www.w3.org/TR/cors/#resource-processing-model">&quot;resource processing model&quot; section</a></p> +</div> +Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag: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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais …</p><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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais vous aussi ça vous +titille:</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.habicoop.fr/IMG/pdf/Memoire_hbtat_coop_Vaulx-2.pdf">L’Habitat Coopératif : Solution au problème de responsabilisation sociale des +copropriétaires sur la commune de Vaulx en Velin +?</a> - mémoire REPIQUET Anne +2005.</li> +<li>Un bouquin à lire avec plein d'infos: <a class="reference external" href="http://www.ecosociete.org/t101.php">Vivre autrement</a> de Diana Leafe Christian.</li> +<li>…</li> +</ul> +Languages2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/languages.html<p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe><p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe>Tricot2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/tricot.html<p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu …</p><p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu +près un rang d'endroit et j'arrive pas à enchainer sur l'envers pour réussir +à faire un point jersey (jersey c'est un rang endroit puis un rang envers).</p> +<p>Enfin bref, si jamais ça vous botte vous aussi, voila quelques ressources que +j'ai trouvé sur internet (en plus des conseils avisés de maman chérie™):</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.youtube.com/watch?v=VcGiBG2BNxo&amp;list=UUskaiVNnKf7amRb5OI5op_w">Montage des mailles &quot;normales&quot;</a></li> +<li><a class="reference external" href="http://www.youtube.com/watch?v=aIQtNN89pqA&amp;list=UUskaiVNnKf7amRb5OI5op_w">Le point jersey</a></li> +</ul> +<p>La nana explique plutôt bien et assez lentement. En espérant que ça prenne.</p> +Astuces SSH2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/astuces-ssh.html<div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s …</pre></div><div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') +PATH=.:\$PATH nc -w1 $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /') +</pre> +<p>On peut donc spécifier des &quot;sauts&quot; ssh du style:</p> +<pre class="literal-block"> +ssh root&#64;91.25.25.25+192.168.1.1 +</pre> +<p>Ensuite on peut essayer de rajouter:</p> +<pre class="literal-block"> +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é +</pre> +</div> +Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag: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'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial …</a></li></ul><p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de +ubuntu, j'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial Menu</a> vire les +boutons et textes en rapport avec le web social. J'en avais pas besoin +puisque je suis connecté à mon instant messenger dans un terminal, en +utilisant weechat.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/97/coverflow-alt-tab/">Coverflow Alt-Tab</a> change le +switcher d'applications par defaut. Je le trouve bien plus pratique que celui +par defaut puisqu'il me permet de voir &quot;en grand&quot; quelle est la fenêtre que +je vais afficher.</li> +<li><a class="reference external" 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'intègre niquel avec +Spotify, et ça c'est chouette.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/149/search-firefox-bookmarks-provider/">Rechercher dans les bookmarks firefox</a> +permet de… à votre avis ?</li> +</ul> +<p>Un peu moins utile mais sait on jamais:</p> +<ul class="simple"> +<li>“<a class="reference external" href="https://extensions.gnome.org/extension/130/advanced-settings-in-usermenu/">Advanced Settings in UserMenu</a>” +permet d'avoir un raccourci vers les paramètres avancés dans le menu +utilisateur (en haut à droite)</li> +<li>Une <a class="reference external" href="https://extensions.gnome.org/extension/409/gtg-integration/">intégration à Getting things Gnome</a> (un truc de +GTD). Je suis en train d'expérimenter avec cet outil, donc je ne sais pas +encore si ça va rester, mais pourquoi pas.</li> +</ul> +<p>Vous pouvez aller faire un tour sur <a class="reference external" href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> +pour en trouver d'autres à votre gout.</p> +"Groovy"2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/groovy.html<p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>C'est pour ça que j'ai du …</p><p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>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 ;)</p> +Notre dame des landes2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/notre-dame-des-landes.html<p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre …</p><p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre +2012:</p> +<ul class="simple"> +<li>Article dans le monde qui explique la complexité de la lutte sur place: <a class="reference external" href="http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html">http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html</a></li> +<li>autour de relations à la presse: +<a class="reference external" href="http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html">http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html</a></li> +<li>Notre-Dame-des-Landes : un pilote annonce un fiasco pour le futur aéroport <a class="reference external" href="http://www.bastamag.net/article2866.html">http://www.bastamag.net/article2866.html</a></li> +</ul> +Semences paysannes2012-12-20T00:00:00+01:002012-12-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-20:/semences-paysannes.html<p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité …</p><p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité en 1960 au sein de l'UPOV pour faire des textes pour s'approprié les selections qu'ils ont fait. Les textes ont été votés par les députés depuis: bien prové au lieu de bien collectif.</p> +<p>Les semenciers n'existent que depuis 150 ans. Ils revendiquent maintenant le monopole de selection.</p> +<p>Un catalogue est prévu pour les semences dites &quot;de conservation&quot; (alors qu'elles évoluent, conservation n'est pas un terme adapté). C'est la voie qui est possible pour pouvoir échanger des semences entre agriculteurs.</p> +<p>→ Quelles sont les semences de conservation depuis 2002 ? → Quid des semences paysannes, qui évoluent et que l'on garde d'année en année, en selectionnant les meilleures especes. → Existe-il un autre catalogue ? → Au niveau européen, quelles sontles contraintes d'inscription ? Gratuité demandée, qu'en est il ?</p> +<p>→ Relocalistion sur les terroirs des échanges.</p> +<p>→ Biodiversité serait tué par l'utilisation d'espèces inscrites.</p> +<p>Série de vidéos sur la paysannerie: <a class="reference external" href="http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86">http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86</a></p> +Cheese & code - Wrap-up2012-10-22T00:00:00+02:002012-10-22T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.html<p>This week-end I hosted a <em>cheese &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 well.</p> +<p>Here is a summary of what we worked on:</p> +<div class="section" id="daybed"> +<h2>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 REST web service, in python, and open +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're using <strong>CouchDB</strong> as a backend.</p> +<img alt="Daybed is a big couch!" src="images/daybed.jpg" style="width: 400px;" /> +<p>We mainly hacked on daybed and are pretty close to the release of the first +version, meaning that we have something working.</p> +<p><a class="reference external" href="http://github.com/spiral-project/daybed">The code</a> is available on github, +and we also wrote <a class="reference external" href="http://daybed.rtfd.org">a small documentation</a> for 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'm pretty confidend that we now have really good basis for this project.</p> +<p>Also, we will have a nice todolist application, with the backend <strong>and</strong> the +frontend, in javascript / html / css, you'll know more when it'll be ready :-)</p> +<p>Once we have something good enough, we'll release the first version and I'll +host it somewhere so that people can play with it.</p> +</div> +<div class="section" id="cornice"> +<h2>Cornice</h2> +<p>Daybed is built on top of <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, a framework to +ease the creation of web-services.</p> +<p>At Pycon France, we had the opportunity to attend a good presentation about <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a>. SPORE is a way to describe your +REST web services, as WSDL is for WS-* services. This allows to ease the +creation of generic SPORE clients, which are able to consume any REST API with +a SPORE endpoint.</p> +<p>Here is how you can let cornice describe your web service for you</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>And you'll get a definition of your service, in SPORE, available at <cite>/spore</cite>.</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, etc.</p> +<p>I released today <a class="reference external" href="http://crate.io/packages/cornice/">Cornice 0.11</a>, which adds +into other things the support for SPORE, plus some other fixes we found on our +way.</p> +</div> +<div class="section" id="respire"> +<h2>Respire</h2> +<p>Once you have the description of the service, you can do generic clients +consuming them!</p> +<p>We first wanted to contribute to <a class="reference external" href="https://github.com/bl0b/spyre">spyre</a> but +it was written in a way that wasn't supporting to <cite>POST</cite> data, and they +were using their own stack to handle HTTP. A lot of code that already exists in +other libraries.</p> +<p>While waiting the train with <a class="reference external" href="http://natim.ionyse.com/">Rémy</a>, we hacked +something together, named &quot;Respire&quot;, a thin layer on top of the awesome +<a class="reference external" href="http://python-requests.org">Requests</a> 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're still hacking on it so it may break +(for the better), but that had been working pretty well for us so far.</p> +<p>You can <a class="reference external" 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 daybed)</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Finally, we were out of cheese so everyone headed back to their respective +houses and cities.</p> +<p>Until next time?</p> +</div> +Cheese & Code party: October 20-212012-09-20T00:00:00+02:002012-09-20T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-20:/afpy-computer-camp-october-20-21.html<p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing …</p><p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing something related with the Afpy Computer +Camps at his house each year, I've been there twice and it really was a nice +experience.</p> +<p>At Djangocong 2012, in Montpellier (south of France), <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu Leplatre</a> and myself started to work on a model +validation and storage service, named <a class="reference external" href="https://github.com/spiral-project/daybed/">Daybed</a>.</p> +<p>I've talked about this project to some persons this week-end (I've even done <a class="reference external" href="http://alexis.notmyidea.org/lightning-daybed.html">a +lightning talk</a> about it) +and it gathered some interest from people in the python community, so we +thought about sprinting on this.</p> +<div class="section" id="and-21-october-a-computer-camp"> +<h2>20 and 21 October - A Computer Camp !</h2> +<p>Add to this a few beers, and the sprint turns magically into a camp. We'll be +sprinting at the end of October (the 20 and 21) near Angers, on daybed.</p> +<p>We plan to have great food and wine, so if you feel like it and if you want to +come and work on some python-related things, you're invited!</p> +<p>Although, I can host a limited number of persons, so you'll need to contact me +before :), that's <cite>alexis at notmyidea dot org</cite>.</p> +<p>I've setup a wiki page to organize a bit everything (knowing how many people will +come by will allow me to handle things better), please put information there:</p> +<p><a class="reference external" href="http://wiki.python.org/moin/ComputerCampAlexis">http://wiki.python.org/moin/ComputerCampAlexis</a></p> +</div> +Circus sprint at PyconFR2012-09-17T00:00:00+02:002012-09-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.html<p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're …</p><p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're using +at Mozilla for some of our 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 features.</p> +<p>Having people wanting to sprint on our projects is exciting because that's +when making things in the open unleashes its full potential. You can't imagine +how happy I was to have some friends come and work on this with us :)</p> +<p>Here is a wrap-up of the sprint:</p> +<div class="section" id="autocompletion-on-the-command-line"> +<h2>Autocompletion on the command-line</h2> +<p><a class="reference external" 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're using bash. It seems that not that much work is needed to +make it happen on zsh as well :)</p> +<p><a class="reference external" href="https://github.com/mozilla-services/circus/blob/master/extras/circusctl_bash_completion">Have a look at the feature</a></p> +<p>On the same topic, we now have a cool shell for Circus. If you start the +<cite>circusctl</cite> command without any option, you'll end-up with a cool shell. Thanks +<a class="reference external" href="https://github.com/jojax">Jonathan Dorival</a> for the work on this! You can +have a look at <a class="reference external" href="https://github.com/mozilla-services/circus/pull/268">the pull request</a>.</p> +</div> +<div class="section" id="future-changes-to-the-web-ui"> +<h2>Future changes to the web ui</h2> +<p><a class="reference external" 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'm glad of this. +Currently, it's done with bottle.py and we want to switch to 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 instance.</p> +</div> +<div class="section" id="bug-and-doc-fixing"> +<h2>Bug and doc fixing</h2> +<p>While reading the source code, we found some inconsistencies and fixed them, +with <a class="reference external" href="http://mathieu.agopian.info/">Mathieu Agopian</a>. We also tried to +improve the documentation at different levels.</p> +<p>Documentation still needs a lot of love, and I'm planning to spend some time on +this shortly. I've gathered a bunch of feedback on this</p> +</div> +<div class="section" id="circus-clustering-capabilities"> +<h2>Circus clustering 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 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 be.</p> +<p>Remy wrote <a class="reference external" href="http://tech.novapost.fr/circus-clustering-management-en.html">a good summary about our brainstorming</a> so I'll not do +it again here, but feel free to contact us if you have ideas on this, they're +very welcome!</p> +</div> +<div class="section" id="project-management"> +<h2>Project management</h2> +<p>We've had some inquiries telling us that's not as easy as it should to get +started with the Circus project. Some of the reasons are that we don't +have any release schedule, and that the documentation is hairy enough to lost +people, at some point :)</p> +<p>That's something we'll try to fix soon :)</p> +<p>PyconFR was a very enjoyable event. I'm looking forward to meet the community +again and discuss how Circus can evolve in ways that are interesting to +everyone.</p> +<p>Tarek and me are going to <a class="reference external" href="http://python.ie/pycon/2012/">Pycon ireland</a>, feel +free to reach us if you're going there, we'll be happy to meet and enjoy beers!</p> +</div> +Refactoring Cornice2012-05-14T00:00:00+02:002012-05-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-05-14:/refactoring-cornice.html<p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> routing system, +allowing to register services in …</p><p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" 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 HTTP headers <a class="reference external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">as defined by the HTTP specification</a> without the need +from the developer to deal with them nor to know them.</p> +<p>If you're not familiar with Cornice, here is how you define a simple service +with it:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>This external API is quite cool, as it allows to do a bunch of things quite +easily. For instance, we've written our <a class="reference external" href="https://github.com/mozilla-services/tokenserver">token-server</a> code on top of this in a +blast.</p> +<div class="section" id="the-burden"> +<h2>The 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 internally.</p> +<p>The API of the <cite>cornice.service.Service</cite> class was as following (simplified so +you can get the gist of it).</p> +<div class="highlight"><pre><span></span><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="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="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> +</pre></div> +<p>I encourage you to go read <a class="reference external" 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 done.</p> +<p>A bunch of things are wrong:</p> +<ul class="simple"> +<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 <cite>get_drink</cite>, you will instead get a decorator which +contains this view.</li> +<li>second, we are using decorators as APIs we expose. Even if decorators are +good as shortcuts, they shouldn't be the default way to deal with an API. A +good example of this is <a class="reference external" href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/resource.py#L56">how the resource module consumes this API</a>. +This is quite hard to follow.</li> +<li>Third, in the <cite>api</cite> 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 API.</li> +</ul> +</div> +<div class="section" id="how-do-we-improve-this"> +<h2>How do we improve this?</h2> +<p>Python is great because it allows you to refactor things in an easy way. What I +did isn'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 API that much.</p> +<p>Here is the gist of the new architecture:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">None</span><span class="p">):</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="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="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> +</pre></div> +<p>So, the service is now only storing the information that'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 +<cite>register_service_views</cite> and has the following signature:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>To sum up, here are the changes I made:</p> +<ol class="arabic simple"> +<li>Service description is now separated from the route registration.</li> +<li><cite>cornice.service.Service</cite> now provides a <cite>hook_view</cite> method, which is not a +decorator. decorators are still present but they are optional (you don't +need to use them if you don't want to).</li> +<li>Everything has been decoupled as much as possible, meaning that you really +can use the <cite>Service</cite> class as a container of information about the services +you are describing. This is especially useful when generating 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. <cite>cornice.services.Service</cite> 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 system.</p> +<p>However, no integration with other frameworks is done at the moment even if the +design allows it.</p> +<p>The same way, the sphinx description layer is now only a consumer of this +service description tool: it looks at what's described and build-up the +documentation from it.</p> +<p>The resulting branch is not merged yet. Still, you can <a class="reference external" 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 :-)</p> +</div> +Thoughts about a form generation service, GIS enabled2012-02-04T00:00:00+01:002012-02-04T00:00:00+01:00Alexis Métaireau, Mathieu Leplatretag:blog.notmyidea.org,2012-02-04:/carto-forms.html<p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of it.</p> +<p>This idea has been stuck …</p><p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of 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've named it +<em>carto-forms</em> for now, but that's only the &quot;codename&quot;.</p> +<p>To put it shortly: what if we had a way to build forms, ala Google forms, but +with geographic information in them?</p> +<p>If you don't know Google forms, it means having an user-friendly way to build +forms and to use them to gather information from different users.</p> +<p>In my opinion, Google forms is missing two important things: first, it's not +open-source, so it's not possible to hack it or even to run it on your own +server. Second, it doesn't really know how to deal with geographic data, and +there is no way to filter the information more than in a spreadsheet.</p> +<p>I knew that <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu</a> and some folks at <a class="reference external" href="http://makina-corpus.com">Makina Corpus</a> would be interested +in this, so I started a discussion with him on IRC and we refined the details +of the project and its objectives.</p> +<p>Imagine the following:</p> +<ol class="arabic simple"> +<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) ;</li> +<li>In situ, users fill the form fields with what they see. Geo fields can be +pre-populated using device geolocation ;</li> +<li>At the end of the day, we can see a map with all user contributions seized +through this particular form ;</li> +<li>If relevant, a script could eventually import the resulting dataset and +publish/merge with OpenStreetMap.</li> +</ol> +<div class="section" id="some-use-cases"> +<h2>Some use cases</h2> +<p>I can see some use cases for this. The first one is a collaborative map, with +facet filtering. Let's draw a potential user flow:</p> +<ul> +<li><p class="first">An &quot;administrator&quot; goes to the website and creates a form to list all the +alternative-related events. He creates the following fields:</p> +<ul class="simple"> +<li>Name: a plain text field containing the name of the event.</li> +<li>Category: the category of the event. Can be a finite list.</li> +<li>Location: The location of the event. It could be provided by selecting a +point on a map or by typing an address.</li> +<li>Date: the date of the event (a datepicker could do the 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 etc)</p> +</li> +<li><p class="first">Once finished, the form is generated and the user gets an url (say +<a class="reference external" href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>) for it.</p> +</li> +<li><p class="first">REST APIs allow third parties to get the form description and to +push/edit/get information from there.</p> +</li> +<li><p class="first">He can communicate the address in any way he wants to his community so they +can go to the page and add information to it.</p> +</li> +<li><p class="first">Then, it is possible to filter the results per location / date or category. +This can be done via API calls (useful for third parties) or via a nice +interface in the browser.</p> +</li> +</ul> +<p>So, as you may have noticed, this would allow us to create interactive maps really +easily. It's almost just a matter of some clicks to the users. If we also come +up with a nice Web API for this, we could do server-side validation and build +even phone applications 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 clients.</p> +<p>As mentioned before, the idea of a simple tool to support collaborative mapping +fullfils a recurring necessity !</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'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 class="reference external" href="http://fixmystreet.ca">http://fixmystreet.ca</a>), +geocaching, trajectories (e.g hiking, runners, cyclists)...</p> +<p>Here are some other examples of where <em>carto-forms</em> could be useful:</p> +<div class="section" id="simple-gis-storage-backend"> +<h3>Simple GIS storage backend</h3> +<p>Let's say you are a mobile developer, you don't want to bother with PostGIS +nor write a custom and insecure code to insert and retrieve your GIS data! You +need carto-forms! A simple API helps you design your models/forms and the +same API allows you to CRUD and query your data. Thus, you only need to focus +on your application, not on how GIS data will be handled.</p> +<p>We make a distinction between storage and widgets.</p> +<p>Besides, if you are a django / drupal / plomino... maintainer : you +can develop a module to &quot;plug&quot; your models (content types) and UI to carto-forms! +Carto forms are then exposed to your backoffice users (ex: drupal admin UI, django +adminsite), and likewise you can write your own HTML widgets that consume datasets +in frontend views (facets in JSON/XML, and map data in GeoJSON).</p> +</div> +<div class="section" id="visualization-tool"> +<h3>Visualization tool</h3> +<p>Since data submission can be done programmatically using the API, you could use Carto-forms +results page as a visualization 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're in +front of a decision support system!</p> +<p>Of course, filtered raw data can be downloaded (GeoJSON, XML) and a permalink allows to +share the page with the state of the filters and the zoom/location of the map.</p> +</div> +<div class="section" id="generic-forms-service"> +<h3>Generic forms service</h3> +<p>If you want to generate a configuration file (or whatever, email messages, ...), +you will need a form and a template to inlay user submitted values and get the result.</p> +<p>A form service would be really useful to create forms programmatically and retrieve +cleaned and validated input 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 result).</p> +<p>Note that for this use-case, there is no specific need of GIS data nor storage of records +for further retrieval.</p> +</div> +</div> +<div class="section" id="what-s-out-in-the-wild-already"> +<h2>What's out in the wild already?</h2> +<p>Of course, there is Google forms, which allows you to do these kind of things, +but it's closed and not exactly what we are describing here.</p> +<p>We've discovered the interesting <a class="reference external" 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't handle APIs and +geolocation information.</p> +<p>The idea of <a class="reference external" href="http://thoth.io">http://thoth.io</a> is very attractive : an extremely simple web API to store +and retrieve data. In addition, <em>carto-forms</em> would do datatype validation and have +basic GIS fields (point, line, polygon).</p> +<p><a class="reference external" href="http://mapbox.com">http://mapbox.com</a> also did an awesome work on cartography, but didn't take into +account the form aspect we're leveraging here.</p> +</div> +<div class="section" id="so-let-s-get-it-real"> +<h2>So… Let's get it real!</h2> +<p>As you may have understood, this isn't a really complicated problem. We have +been sometimes chatting about that with Mathieu about what we would need and +how we could achieve this.</p> +<p>We can probably come with an elegant solution without too much pain. Mathieu is +used to work with GIS systems (which is really cool because I'm not at all) and +knows his subject, so that's an opportunity to learn ;-)</p> +<p>We will be at <a class="reference external" 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 join!</p> +<p>We don'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 welcome!</p> +<p>Here is the etherpad document we worked on so far: +<a class="reference external" href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don't hesitate to add your thoughts and edit +it, that's what it's made for!</p> +<p>Thanks to <a class="reference external" href="http://sneakernet.fr/">Arnaud</a> and <a class="reference external" href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo fixing.</p> +</div> +2012, first months2012-01-21T00:00:00+01:002012-01-21T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-21:/2012-first-months.html<p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services …</p><p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services able to scale out of +the box.</p> +<p>Our most visible and known project, so far, is Firefox Sync, which allows to synchronize +browsing data (tabs, passwords, history, etc.) among different instances of +Firefox. We are also building other things, such as a way to get metrics +easily, a web service based queue, etc. Our primary consumers are +people inside Mozilla, and we want to help them having a simple way to create, +deploy and scale their apps. The project is named &quot;sagrada&quot;, and you +can find some more information about it on <a class="reference external" href="https://wiki.mozilla.org/Services/Sagrada">our public wiki</a></p> +<p>All of what we do, we do it in the open. So you can have a look at <a class="reference external" href="http://github.com/mozilla-services">the +different pieces of code we wrote</a> +and use them / contribute if you want to.</p> +<p>I will not dig in to all the details of what I have been doing, but so far, this have been +a pretty amazing experience. Part of this is explainable by the fact that the +team is made of amazing folks, all with a strong experience in different +topics, so I'm learning things™.</p> +<p>I am currently practicing a bit my C++ to do crypto related things (I may or +may not talk about this later on this web-logs) and it's great (well, it +remembers me why I love python for so many things, but it makes me think closer +to the metal ;)). I love this job.</p> +<p>Second, I moved to Paris. Yes, Paris. Some of you who know me a bit may find +it unexpected, and that's the case. I'm usually not a big fan of big cities and +am a fairly strong defender of having and creating activities in the country side, +to face the rural exodus problem, into other thingS.</p> +<p>I didn't changed my opinion about that. However, I don't want to <em>start</em> by +working remote, especially when working with a remote team. Having offices kind +of help me to have a differentiation between my working place and home, which I +find to be important.</p> +<p>And, to be honest, I don't like Paris for unknown reasons: I +haven't been there, so it's a big over-generalisation to say that it's not +good for me. The reality is that I have no idea of what Paris is, and if I'll +like it or not.</p> +<p>I found a really nice house (yeah, a house!) in Paris and am sharing it with 3 +other persons. We have room, all like good food and… +they are not geeks, which is a big win for me: work is work and home is home.</p> +<p>So far, Paris had been really nice. A lot of things are going on in here, and I +kind of like the way it is possible to find alternative related things in here. +I found a <a class="reference external" href="http://en.wikipedia.org/wiki/Community-supported_agriculture">CSA</a>, +some people interested by agriculture related problems and I like where things +seems to be going.</p> +<p>So, new job, new house, new city, things are going forward and that's great.</p> +<p>Oh, and I will try to post some more technical articles soon, +I'm missing them :)</p> +Using JPype to bridge python and Java2011-11-06T00:00:00+01:002011-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-11-06:/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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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, 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 VM level. This means you need to start a VM +from your python script, but it does the job and stay fully compatible with +Cpython and its C extensions.</p> +<div class="section" id="first-steps-with-jpype"> +<h2>First steps with JPype</h2> +<p>Once JPype installed (you'll have to hack a bit some files to integrate +seamlessly with your system) you can access java classes by doing something +like that:</p> +<div class="highlight"><pre><span></span><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> +</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 them.</p> +</div> +<div class="section" id="interfacing-with-boilerpipe"> +<h2>Interfacing with Boilerpipe</h2> +<p>To install boilerpipe, you just have to run an ant script:</p> +<pre class="literal-block"> +$ cd boilerpipe +$ ant +</pre> +<p>Here is a simple example of how to use boilerpipe in Java, from their sources</p> +<div class="highlight"><pre><span></span><span class="kn">package</span> <span class="nn">de.l3s.boilerpipe.demo</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">java.net.URL</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">de.l3s.boilerpipe.extractors.ArticleExtractor</span><span class="o">;</span> + +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Oneliner</span> <span class="o">{</span> + <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="kd">final</span> <span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="kd">final</span> <span class="n">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="n">URL</span><span class="o">(</span><span class="s">&quot;http://notmyidea.org&quot;</span><span class="o">);</span> + <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ArticleExtractor</span><span class="o">.</span><span class="na">INSTANCE</span><span class="o">.</span><span class="na">getText</span><span class="o">(</span><span class="n">url</span><span class="o">));</span> + <span class="o">}</span> +<span class="o">}</span> +</pre></div> +<p>To run it:</p> +<div class="highlight"><pre><span></span>$ javac -cp dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar src/demo/de/l3s/boilerpipe/demo/Oneliner.java +$ java -cp src/demo:dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar de.l3s.boilerpipe.demo.Oneliner +</pre></div> +<p>Yes, this is kind of ugly, sorry for your eyes. +Let's try something similar, but from python</p> +<div class="highlight"><pre><span></span><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="k">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> +</pre></div> +<p>And you get what you want.</p> +<p>I must say I didn'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, nice!</p> +</div> +How are you handling your shared expenses?2011-10-15T00:00:00+02:002011-10-15T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.html<p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 …</p><p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 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 come.</p> +<p>I said yes and gave it some more thoughts: We probably aren'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, boooh!).</p> +<p>I then discussed with a friend of mine, who was excited about it and wanted to learn +python. Great! That'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 class="reference external" href="http://www.sneakernet.fr/">Arnaud</a> and Quentin!)</p> +<p>Since that, the project now support multiple languages and provides a REST API +(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's it (this was inspired by +doodle)!</p> +<img alt="Capture d'écran du site." src="images/ihatemoney.png" /> +<p>You can try the project at <a class="reference external" href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a> for now, and the +code lives at <a class="reference external" href="https://github.com/spiral-project/ihatemoney/">https://github.com/spiral-project/ihatemoney/</a>.</p> +<div class="section" id="features"> +<h2>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 once.</p> +<p>No, I don'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 way.</p> +<div class="section" id="no-user-registration"> +<h3>No user registration</h3> +<p>You don'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 you).</p> +</div> +<div class="section" id="keeping-things-simple"> +<h3>Keeping things simple</h3> +<p>&quot;Keep It Simple, Stupid&quot; 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're back from the +farmer's market on raw paper.</p> +</div> +<div class="section" id="no-categories"> +<h3>No categories</h3> +<p>Some people like to organise their stuff into different &quot;categories&quot;: +leisure, work, eating, etc. That's not something I want (at least to begin +with).</p> +<p>I want things to be simple. Got that? Great. Just add your bills!</p> +</div> +<div class="section" id="balance"> +<h3>Balance</h3> +<p>One of the most useful thing is to know what's your &quot;balance&quot; compared to +others. In other words, if you're negative, you owe money, if you'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 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 balance.</p> +</div> +<div class="section" id="api"> +<h3>API</h3> +<p>All of what's possible to do with the standard web interface is also available +through a REST API. I developed a simple REST toolkit for flask for this (and +I should release it!).</p> +</div> +</div> +<div class="section" id="interested"> +<h2>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't hesitate +a second! The project lives at <a class="reference external" href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p> +</div> +Using dbpedia to get languages influences2011-08-16T00:00:00+02:002011-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.html<p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 …</p><p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 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 technologies.</p> +<p>Well, you may have guessed it, the project in question in dbpedia, and exposes +information in the form of RDF triples, which are way more easy to work with +than simple HTML.</p> +<p>For instance, let's take the page about python: +<a class="reference external" 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 &quot;Influenced&quot; and &quot;InfluencedBy&quot;, 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 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 &quot;( +programming language)&quot;, which is the case for python.</p> +<p>So I've built <a class="reference external" 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 graphviz.</p> +<p>After a nice:</p> +<pre class="literal-block"> +$ python get_influences.py python dot | dot -Tpng &gt; influences.png +</pre> +<p>The result is the following graph (<a class="reference external" href="http://files.lolnet.org/alexis/influences.png">see it directly here</a>)</p> +<img alt="Graph des influances des langages les uns sur les autres." src="http://files.lolnet.org/alexis/influences.png" style="width: 800px;" /> +<p>While reading this diagram, keep in mind that it is a) not listing all the +languages and b) keeping a python 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 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 readable.</p> +<p>You can find the script <a class="reference external" href="https://github.com/ametaireau/experiments">on my github account</a>. Feel free to adapt it for +whatever you want if you feel hackish.</p> +Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html<p>Back in October, I released <a class="reference external" 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 class="reference external" 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 github.</p> +<p>And people started contributing. I wasn'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 requests.</p> +<p><strong>Which is clearly 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 fun.</p> +<p>Thank you, guys, you're why I like open source so much.</p> +Introducing Cornice2011-07-12T00:00:00+02:002011-07-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-12:/introducing-cornice.html<p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of …</p><p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of any kind.</p> +<p>The goal is to simplify your work, but we don't want to reinvent the wheel, so +it is easily pluggable with validations frameworks, such as <a class="reference external" href="http://docs.pylonsproject.org/projects/colander/en/latest/">Colander</a>.</p> +<div class="section" id="handling-errors-and-validation"> +<h2>Handling errors and validation</h2> +<p>Here is how it works:</p> +<div class="highlight"><pre><span></span><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.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> +</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 future)</p> +<p>As you might have seen, <cite>request.errors.add</cite> 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 &quot;body&quot;, +&quot;query&quot;, &quot;headers&quot; or &quot;path&quot;. <strong>name</strong> is the name of the variable causing +problem, if any, and <strong>description</strong> contains a more detailed message.</p> +<p>Let's run this simple service and send some queries to it:</p> +<pre class="literal-block"> +$ curl -v http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: */* +&gt; +* HTTP 1.0, assume close after body +&lt; HTTP/1.0 400 Bad Request +&lt; Content-Type: application/json; charset=UTF-8 +[{&quot;location&quot;: &quot;query&quot;, &quot;name&quot;: &quot;awesome&quot;, &quot;description&quot;: &quot;You lack awesomeness!&quot;} +</pre> +<p>I've removed the extra clutter from the curl's output, but you got the general idea.</p> +<p>The content returned is in JSON, and I know exactly what I have to do: add an +&quot;awesome&quot; parameter in my query. Let's do it again:</p> +<pre class="literal-block"> +$ curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;yay!&quot;} +</pre> +<p>Validators can also convert parts of the request and store the converted value +in <cite>request.validated</cite>. It is a standard dict automatically attached to the +requests.</p> +<p>For instance, in our validator, we can chose to validate the parameter passed +and use it in the body of the webservice:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>The output would look like this:</p> +<pre class="literal-block"> +curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;awesome yeah&quot;} +</pre> +</div> +<div class="section" id="dealing-with-accept-headers"> +<h2>Dealing with &quot;Accept&quot; headers</h2> +<p>The HTTP spec defines a <strong>Accept</strong> header the client can send so the response +is encoded the right way. A resource, available at an URL, can be available in +different formats. This is especially true for web services.</p> +<p>Cornice can help you dealing with this. The services you define can tell which +<cite>Content-Type</cite> values they can deal with and this will be checked against the +<strong>Accept</strong> headers sent by the client.</p> +<p>Let's refine a bit our previous example, by specifying which content-types are +supported, using the <cite>accept</cite> parameter:</p> +<div class="highlight"><pre><span></span><span class="nd">@service.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> +</pre></div> +<p>Now, if you specifically ask for XML, Cornice will throw a 406 with the list of +accepted <cite>Content-Type</cite> values:</p> +<pre class="literal-block"> +$ curl -vH &quot;Accept: application/xml&quot; http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: application/xml +&gt; +&lt; HTTP/1.0 406 Not Acceptable +&lt; Content-Type: application/json; charset=UTF-8 +&lt; Content-Length: 33 +&lt; +[&quot;application/json&quot;, &quot;text/json&quot;] +</pre> +</div> +<div class="section" id="building-your-documentation-automatically"> +<h2>Building your documentation 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 API in your docs.</p> +<div class="highlight"><pre><span></span><span class="p">..</span> <span class="ow">services</span><span class="p">::</span> + <span class="nc">:package:</span> <span class="nf">coolapp</span> + <span class="nc">:service:</span> <span class="nf">quote</span> +</pre></div> +<p>Here is an example of what a generated page looks like: <a class="reference external" href="http://packages.python.org/cornice/exampledoc.html">http://packages.python.org/cornice/exampledoc.html</a></p> +</div> +<div class="section" id="yay-how-can-i-get-it"> +<h2>Yay! How can I get it?</h2> +<p>We just cut a 0.4 release, so it's available at <a class="reference external" href="http://pypi.python.org/pypi/cornice">http://pypi.python.org/pypi/cornice</a> +You can install it easily using <cite>pip</cite>, for instance:</p> +<pre class="literal-block"> +$ pip install cornice +</pre> +<p>You can also have a look at the documentation at +<a class="reference external" href="http://packages.python.org/cornice/">http://packages.python.org/cornice/</a></p> +</div> +<div class="section" id="what-s-next"> +<h2>What's 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 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 class="reference external" href="https://github.com/mozilla-services/cornice">go grab them on github</a> +, commit and send us a pull request!</p> +</div> +Analyse users' browsing context to build up a web recommender2011-04-01T00:00:00+02:002011-04-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.html<p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full …</p><p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full time on my dissertation topic.</p> +<p>When I learned we'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's the good time to learn.</p> +<p>Since a long time, I'm being impressed by the <a class="reference external" href="http://last.fm">last.fm</a> +recommender system. They're <em>scrobbling</em> the music I listen to since something +like 5 years now and the recommendations they're doing are really nice and +accurate (I discovered <strong>a lot</strong> of great artists listening to the +&quot;neighbour radio&quot;.) (by the way, <a class="reference external" href="http://lastfm.com/user/akounet/">here is</a> +my lastfm account)</p> +<p>So I decided to work on recommender systems, to better understand what is it +about.</p> +<p>Recommender systems are usually used to increase the sales of products +(like Amazon.com does) which is not really what I'm looking for (The one who +know me a bit know I'm kind of sick about all this consumerism going on).</p> +<p>Actually, the most simple thing I thought of was the web: I'm browsing it quite +every day and each time new content appears. I've stopped to follow <a class="reference external" 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 class="reference external" href="http://twitter.com/ametaireau/">on +twitter</a>.</p> +<p>Too much information kills the 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're probably not interested by the same topics at different +times of the day, or depending on the computer you're using. We can also +probably make good use of the way you browse to create groups into the content +you're browsing (or even use the great firefox4 tab group feature).</p> +<p>There is a large part of concerns to have about user's privacy as well.</p> +<p>Here is my proposal (copy/pasted from the one I had to do for my master)</p> +<div class="section" id="introduction-and-rationale"> +<h2>Introduction and 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 articles.</p> +<p>A lot of people share the same interest to various topics, and the quantity of +information is such than it'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 perspective.</p> +<p>Machine learning is a branch of Artificial Intelligence (AI) 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 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'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 else.</p> +<p>Page contents are also interesting to analyse, because that'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 etc.)</p> +<p>The goal of this dissertation is to create a recommender system for web links, +including this context 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 system.</p> +</div> +<div class="section" id="background-review"> +<h2>Background 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 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's +browsers.</p> +<div class="section" id="data-preparation-and-extraction"> +<h3>Data preparation and 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 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, 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, 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 HTML pages so there is a need of tools to recognise 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 &quot;liked&quot; a resource, and +determine a mark for it, which can be used by information filtering a later +step (T. Segaran, 2007).</p> +<p>At this stage, structuring the data is required. Storing this kind of +information in RDBMS 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 querying.</p> +</div> +<div class="section" id="information-filtering"> +<h3>Information filtering</h3> +<p>To filter the information, three techniques can be used (Balabanovic et +Al, 1997):</p> +<ul class="simple"> +<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's about +establishing a profile for the user and compare new items against 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 to.</li> +<li>the hybrid approach, which appeared recently combine both of the previous +approaches, giving recommendations when items score high regarding user's +profile, or if a similar user already liked 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, 2007).</p> +<p>References:</p> +<ul class="simple"> +<li>Balabanović, M., &amp; Shoham, Y. (1997). Fab: content-based, collaborative +recommendation. Communications of the ACM, 40(3), 66–72. ACM. +Retrieved March 1, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp">http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp</a>;.</li> +<li>Berners-Lee, T., Hendler, J., &amp; Lassila, O. (2001). +The semantic web: Scientific american. Scientific American, 284(5), 34–43. +Retrieved November 21, 2010, from <a class="reference external" href="http://www.citeulike.org/group/222/article/1176986">http://www.citeulike.org/group/222/article/1176986</a>.</li> +<li>Castellano, G., Fanelli, A., &amp; Torsello, M. (2007). +LODAP: a LOg DAta Preprocessor for mining Web browsing patterns. Proceedings of the 6th Conference on 6th WSEAS Int. Conf. on Artificial Intelligence, Knowledge Engineering and Data Bases-Volume 6 (p. 12–17). World Scientific and Engineering Academy and Society (WSEAS). Retrieved March 8, 2011, from <a class="reference external" 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., &amp; Nejdl, W. (2010). Boilerplate detection using shallow text features. Proceedings of the third ACM international conference on Web search and data mining (p. 441–450). ACM. Retrieved March 8, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=1718542">http://portal.acm.org/citation.cfm?id=1718542</a>.</li> +<li>Myatt, G. J. (2007). Making Sense of Data: A Practical Guide to Exploratory +Data Analysis and Data Mining.</li> +<li>Segaran, T. (2007). Collective Intelligence.</li> +</ul> +</div> +</div> +<div class="section" id="privacy"> +<h2>Privacy</h2> +<p>The first thing that's come to people minds when it comes to process their +browsing data is privacy. People don't want to be stalked. That's perfectly +right, and I don't either.</p> +<p>But such a system don't have to deal with people identities. It's completely +possible to process completely anonymous data, and that's probably what I'm +gonna 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 !</p> +</div> +<div class="section" id="what-s-the-plan"> +<h2>What's the plan ?</h2> +<p>There is a lot of different things to explore, especially because I'm +a complete novice in that field.</p> +<ul class="simple"> +<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 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 db?</li> +<li>Process the data using well known recommendation algorithms. Compare the +results and criticize their value.</li> +</ul> +<p>There is plenty of stuff I want to try during this experimentation:</p> +<ul class="simple"> +<li>I want to try using Geshi to visualize the connexion between the links, +and the contexts</li> +<li>Try using graph databases such as Neo4j</li> +<li>Having a deeper look at tools such as scikit.learn (a machine learning +toolkit in python)</li> +<li>Analyse web pages in order to categorize them. Processing their +contents as well, to do some keyword based classification will be done.</li> +</ul> +<p>Lot of work on its way, yay !</p> +</div> +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:00Alexis Métaireautag: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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time …</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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time in a console while +developing, it's possible to work via ssh, from everywhere.</p> +<p>The only problem is the synchronisation of the source code, config files etc. +from my machine to the server.</p> +<p>Unison provides an interesting way to synchronise two folders, even over +a network. So let's do it !</p> +<div class="section" id="creating-the-jail"> +<h2>Creating the jail</h2> +<p>In case you don't use FreeBSD, you can skip this section.</p> +<div class="highlight"><pre><span></span><span class="c1"># I have a flavour jail named default</span> +$ ezjail-admin -f default workspace.notmyidea.org <span class="m">172</span>.19.1.6 +$ ezjail-admin start workspace.notmyidea.org +</pre></div> +<p>In my case, because the &quot;default&quot; flavour contains already a lot of interesting +things, my jail come already setup with ssh, bash and vim for instance, but +maybe you'll need it in your 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 <cite>/etc/pf.conf</cite>:</p> +<pre class="literal-block"> +workspace_jail=&quot;172.19.1.6&quot; +rdr on $ext_if proto tcp from any to $ext_ip port 20006 -&gt; $workspace_jail port 22 +</pre> +<p>Reload packet filter rules</p> +<div class="highlight"><pre><span></span>$ /etc/rc.d/pf reload +</pre></div> +</div> +<div class="section" id="working-with-unison"> +<h2>Working with unison</h2> +<p>Now that we'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 it</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> +$ make -C /usr/ports/net/unison-nox11 config-recursive +$ make -C /usr/ports/net/unison-nox11 package-recursive +</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 2.32.52.</p> +<p>Check that unison is installed and reachable via ssh from your machine</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> unison -version +unison version <span class="m">2</span>.27.157 +$ unison -version +unison version <span class="m">2</span>.27.57 +</pre></div> +</div> +<div class="section" id="let-sync-our-folders"> +<h2>Let sync our folders</h2> +<p>The first thing I want to sync is my vim configuration. Well, it's already <a class="reference external" href="http://github.com/ametaireau/dotfiles/">in +a git repository</a> but let's try to use +unison for it right now.</p> +<p>I have two machines then: <cite>workspace</cite>, the jail, and <cite>ecureuil</cite> my laptop.</p> +<div class="highlight"><pre><span></span>unison .vim ssh://notmyidea.org:20006/.vim +unison .vimrc ssh://notmyidea.org:20006/.vimrc +</pre></div> +<p>It is also possible to put all the informations in a config file, and then to +only run <cite>unison</cite>. (fire up <cite>vim ~/.unison/default.prf</cite>.</p> +<p>Here is my config:</p> +<pre class="literal-block"> +root = /home/alexis +root = ssh://notmyidea.org:20006 + +path = .vimrc +path = dotfiles +path = dev + +follow = Name * +</pre> +<p>My vimrc is in fact a symbolic link on my laptop, but I don't want to specify +each of the links to unison. That's why the <cite>follow = Name *</cite> is 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 2GB in 20mn ;)</p> +</div> +<div class="section" id="run-the-script-frequently"> +<h2>Run the script 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've wrote a tiny script to get some +feedback from the sync:</p> +<div class="highlight"><pre><span></span><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="bp">True</span> + <span class="n">error</span> <span class="o">=</span> <span class="bp">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; {0}&#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="bp">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 {0}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 {2} &quot;{0}&quot; &quot;{1}&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> +</pre></div> +<p>This is probably perfectible, but that does the job.</p> +<p>Last step is to tell you machine to run that frequently. That's what <cite>crontab</cite> +is made for, so let's <cite>crontab -e</cite>:</p> +<pre class="literal-block"> +$ * */3 * * * . ~/.Xdbus; /usr/bin/python /home/alexis/dev/python/unison-syncer/sync.py +</pre> +<p>The <cite>~/.Xdbus</cite> allows cron to communicate with your X11 session. Here is its +content.</p> +<div class="highlight"><pre><span></span><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 -u <span class="nv">$LOGNAME</span> -n 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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$nautilus_pid</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">exit</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="k">$(</span>tr <span class="s1">&#39;\0&#39;</span> <span class="s1">&#39;\n&#39;</span> &lt; /proc/<span class="nv">$nautilus_pid</span>/environ <span class="p">|</span> grep <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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$DBUS_SESSION_BUS_ADDRESS</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">echo</span> <span class="s2">&quot;Failed to find bus address&quot;</span> &gt;<span class="p">&amp;</span><span class="m">2</span> +<span class="nb">exit</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> DBUS_SESSION_BUS_ADDRESS +</pre></div> +<p>And it comes from <a class="reference external" 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 developments.</p> +</div> +Wrap up of the distutils2 paris' sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00Alexis Métaireautag: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've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what …</p><p>Finally, thanks to a bunch of people that helped me to pay my train and bus +tickets, I've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what we've been working on:</p> +<ul class="simple"> +<li>the <cite>datafiles</cite>, a way to specify and to handle the installation of files which +are not python-related (pictures, manpages and so on).</li> +<li><cite>mkgcfg</cite>, a tool to help you to create a setup.cfg in minutes (and with funny +examples)</li> +<li>converters from setup.py scripts. We do now have a piece of code which +reads your current <cite>setup.py</cite> file and fill in some fields in the <cite>setup.cfg</cite> +for you.</li> +<li>a compatibility layer for distutils1, so it can read the <cite>setup.cfg</cite> you will +wrote for distutils2 :-)</li> +<li>the uninstaller, so it's now possible to uninstall what have been installed +by distutils2 (see PEP 376)</li> +<li>the installer, and the setuptools compatibility layer, which will allow you +to rely on setuptools' based distributions (and there are plenty of them!)</li> +<li>The compilers, so they are more flexible than they were. Since that'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 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 use.</p> +<p>I'm really pleased to see how newcomers went trough the code, and started +hacking so fast. I must say it wasn't the case when we started to work on +distutils1 so that's a very good point: people now can hack the code quicker +than they could 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 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 +bears^Wbeers.</p> +<p>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 :-)</p> +PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00Alexis Métaireautag: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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +drawbacks.</p> +<p>Basically, if you want to use informations coming from the simple API, you will +have to parse web pages manually, to extract informations using some black +vodoo magic. Badly, magic have a price, and it's sometimes impossible to get +exactly the informations you want to get from this index. That's the technique +currently being used by distutils2, setuptools and pip.</p> +<p>On the other side, while XML/RPC is working fine, it'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's important to point out that, even if +PyPI have a mirroring infrastructure, it's only for the so-called <em>simple</em> API, +and not for the XML/RPC.</p> +<div class="section" id="couchdb"> +<h2>CouchDB</h2> +<p>Here comes CouchDB. CouchDB is a document oriented database, that +knows how to speak REST and JSON. It's easy to use, and provides out of the box +a replication mechanism.</p> +</div> +<div class="section" id="so-what"> +<h2>So, what ?</h2> +<p>Hmm, I'm sure you got it. I'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 HTTP request on the CouchDB server. You can also access the informations +from the index directly using a REST API, speaking json. Handy.</p> +<p>So PyPIonCouch is using the PyPI XML/RPC API to get data from PyPI, and +generate records in the CouchDB instance.</p> +<p>The final goal is to avoid to rely on this &quot;simple&quot; API, and rely on a REST +insterface instead. I have set up a couchdb server on my server, which is +available at <a class="reference external" 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've done the first import from PyPI yesterday and all +went fine: it's possible to access the metadata of all PyPI projects via a REST +interface. Next step is to write a client for this REST interface in +distutils2.</p> +</div> +<div class="section" id="example"> +<h2>Example</h2> +<p>For now, you can use pypioncouch via the command line, or via the python API.</p> +<div class="section" id="using-the-command-line"> +<h3>Using the command line</h3> +<p>You can do something like that for a full import. This <strong>will</strong> take long, +because it's fetching all the projects at pypi and importing their metadata:</p> +<pre class="literal-block"> +$ pypioncouch --fullimport http://your.couchdb.instance/ +</pre> +<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 http://couchdb.notmyidea.org/pypi/</strong>, to avoid +the duplication of nodes:</p> +<pre class="literal-block"> +$ pypioncouch --update http://your.couchdb.instance/ +</pre> +<p>The principal node is updated once a day by now, I'll try to see if it's +enough, and ajust with the time.</p> +</div> +<div class="section" id="using-the-python-api"> +<h3>Using the python API</h3> +<p>You can also use the python API to interact with pypioncouch:</p> +<pre class="literal-block"> +&gt;&gt;&gt; from pypioncouch import XmlRpcImporter, import_all, update +&gt;&gt;&gt; full_import() +&gt;&gt;&gt; update() +</pre> +</div> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I want to make a couchapp, in order to navigate PyPI easily. Here are some of +the features I want to propose:</p> +<ul class="simple"> +<li>List all the available projects</li> +<li>List all the projects, filtered by specifiers</li> +<li>List all the projects by author/maintainer</li> +<li>List all the projects by keywords</li> +<li>Page for each project.</li> +<li>Provide a PyPI &quot;Simple&quot; API 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 replication</li> +</ul> +<p>I also still need to polish the import mechanism, so I can directly store in +couchdb:</p> +<ul class="simple"> +<li>The OPML files for each project</li> +<li>The upload_time as couchdb friendly format (list of int)</li> +<li>The tags as lists (currently it's only a string separated by spaces</li> +</ul> +<p>The work I've done by now is available on +<a class="reference external" href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it's still +a work in progress, and everything can break at any time. However, any feedback +will be appreciated !</p> +</div> +Help me to go to the distutils2 paris' sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00Alexis Métaireautag: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 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 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 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 event.</p> +<p>You can find more informations about the sprint on the wiki page of the event +(<a class="reference external" 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'm unfortunately blocked in UK for money reasons. +The cheapest two ways I've found is about £80, which I can't afford. +Following some advices on #distutils, I'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 way.</p> +<p>I'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't make it to paris, I'll hang around on IRC to give some help +while needed.</p> +<p>If you want to contribute some money to help me go there, feel free to use this +chipin page: <a class="reference external" href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> +<p>Thanks for your support !</p> +Fork you ! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html<p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to …</p><p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to share +our knowledge.</p> +<p>I say github, because it seems to be the more mainstream, but I think it's +something strongly related to the <a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_revision_control">DVCS</a> principles: the &quot;only&quot; thing github have +made is to turn that into a social network, and to reveal the awesomeness of the +DVCSes to the masses.</p> +<p>What is really interesting is to see how this platform is addictive: it's +automatically updating a webpages with the more accurate informations about the +projects you're involved in, and add a bit of magic to that using webhooks, +allowing you to update your website each time you push to you repository, for +instance.</p> +<p>Quite nothing, indeed, but, I don't know why, I find this fascinating.</p> +<p>I haven't had the privilege to see my projects forked from github by strangers, +but I've forked others repository to give an hand some times, when I wanted to, +and the main reason is &quot;because it's <strong>fun</strong>&quot; to do so.</p> +<p>Yeah, you're probably right, you have to be a nerd to find fun to fork others. +The good point is that geeks are a kind of nerds, and some geeks are coders :)</p> +<div class="section" id="new-ways-to-contribute"> +<h2>New ways to contribute</h2> +<p>In addition, it seems that he community, or the communities, are there, on those +new social networks for coders. It's really handy to drop an eye on interesting +projects, to report bugs, propose new features, and check what new projects this +or this person have made.</p> +<p>Well, &quot;it's not new&quot;, you may think. That's true, because it's been a while that +SVN was there and even CVS before that. But, it was a bit messy to &quot;fork&quot; a +project, isn't it ? And I'm not talking about all the hell SVN involved with it +(who have not had issues with those messy .svn folders raises an hand !).</p> +<p>It have not been so easy to share code and thoughts about code, to propose +changes on existing code, than now. You think it's better to implement this or +that in a different way ? Clone it (fork it), make your changes and publish +them, and then ask projects owners about it. For sure you'll have answers.</p> +<p>Even if they don't want it, you can easily keep your changes, and keep getting +their updates!</p> +<p>Also, lot of <em>fashionables</em> projects tend to move on DVCS. +Personally, if I know I can fork on a DVCS instead of from a &quot;simple&quot; VCS, +I'll probably be quicker to fork/clone, and to publish changes on my own copy, +than if I had to do so on the upstream repository (and I'll likely dont have +the rights to push to it), because I will not be afraid to break things.</p> +<p>DVCSes makes the contribution easier.</p> +</div> +<div class="section" id="release-early-release-often"> +<h2>Release early, release often</h2> +<p>Maybe have you read <a class="reference external" href="http://www.catb.org/~esr/writings/cathedral-bazaar/">The cathedral and the bazaar</a>, by Eric Steven Raymond ? +(If not, consider doing so, it's a really interesting reading)</p> +<p>Among a lot of others interesting things, one hint he gives is <em>release early, +release often</em>.</p> +<p>I understand it as: if you want to get contributors, release your code early, +even if it's not perfect, and don't be afraid to publish your changes each +time it's needed.</p> +<p>Without notifying it, that's basically what I was doing for my own projects. +I guess that's because Social coding platforms encourages those practices, +partially cause of the possible impact publishing each of your changes can have +on your final solution.</p> +<p>If you have considered publishing your projects, code snippets, or whatever +(code related) but did not done it, considering them not yet ready, maybe +should you think about it twice: you can get feedback and probably start some +interesting discussions about it, if you write code that's readable, of course!</p> +</div> +<div class="section" id="a-step-further-for-open-source-softwares"> +<h2>A step further for open source softwares</h2> +<p>Well, DVCSes are a honking great idea, and they're starting to be really +powerful when applied to free softwares. I mean: if you can't see a project, +it will be hard to contribute to it. And, I don't think anyone wants to +contribute to something closed/proprietary, <em>just for fun</em>. Or maybe am I +missing something.</p> +<p>Maybe it's a kind of revolution, about free and open source softwares (<a class="reference external" href="http://en.wikipedia.org/wiki/Free_and_open_source_software">FOSS</a>), +that is going on. I really like to know I have my word to say about the changes +in the tools I use, and to know that I can make them evolve.</p> +<p>Let's take an example. Imagine I'm using a web framework on daily basis, as a +part of my job as a web developer. I do like using an open source software +because I know how it's working, and because I know that I can interact with the +authors of the framework while they're doing the changes on it.</p> +<p>That's communication, nothing more, and of course I can do that with an internal +proprietary solution, but it will cost me <strong>a lot</strong> more time, for a dead-simple +reason: a company is not as big and powerful as a community can be: it will cost +time to work on this framework, resources to maintain it, fix bugs etc.</p> +<p>Well, I'm starting advocating here about Free and Open Source Softwares use on +companies, what is a bit beyond the scope of this article, so let's back to +our DVCSes and new social related tools.</p> +<p>If I find a bug in this framework, while working, I have the possibility to +go and talk with the creators of the framework, to open a ticket, and even to +make a fix for it, because I've access to the source code. If I want to create a +new feature, I just have to fork it, hack it, and then publish my code to have +feedback of the community.</p> +<p>My fix/work will benefit to all the people (and maybe others companies) working +with this framework, and it's a way to prove the community that my company is +enough skilled to make code-fixes to the framework, so that's all good !</p> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I hope those social coding platforms are only the begining of a new area. I hope +they will make people realize what the power of the community is, and how easily +they can becomes part of it.</p> +<p>If you're not using them right now, maybe you should do so: have a +look 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 !</p> +</div> +How to reboot your bebox using the CLI2010-10-21T00:00:00+02:002010-10-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.html<p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using …</p></div><p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using directly the +command line tools curl, grep and tail (but really harder to read).</p> +<div class="highlight"><pre><span></span>curl -X POST -u joel:joel 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 -d <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="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> +</pre></div> +</div> +<div class="section" id="the-python-version"> +<h2>The Python version</h2> +<p>Well, that's not the optimal solution, that's a bit &quot;gruik&quot;, but it works.</p> +<div class="highlight"><pre><span></span><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="bp">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> +</pre></div> +</div> +Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html<p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some …</p><p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some time ago, I've made a little python script to ease that, and you can now +use it too. It's named &quot;gnome-background-generator&quot;, and you can install it via +pip for instance.</p> +<div class="highlight"><pre><span></span>$ pip install gnome-background-generator +</pre></div> +<p>Then, you have just to use it this way:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator -p ~/Images/walls -s +/home/alexis/Images/walls/dynamic-wallpaper.xml generated +</pre></div> +<p>Here is a extract of the <cite>--help</cite>:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator --help +usage: gnome-background-generator <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-p PATH<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> + <span class="o">[</span>-t TRANSITION_TIME<span class="o">]</span> <span class="o">[</span>-d DISPLAY_TIME<span class="o">]</span> <span class="o">[</span>-s<span class="o">]</span> + <span class="o">[</span>-b<span class="o">]</span> + +A simple <span class="nb">command</span> line tool to generate an XML file to use <span class="k">for</span> gnome +wallpapers, to have dynamic walls + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -p PATH, --path PATH Path to look <span class="k">for</span> the pictures. If no output is + specified, will be used too <span class="k">for</span> outputing the dynamic- + wallpaper.xml file. Default value is the current + directory <span class="o">(</span>.<span class="o">)</span> + -o OUTPUT, --output OUTPUT + Output filename. If no filename is specified, a + dynamic-wallpaper.xml file will be generated in the + path containing the pictures. You can also use <span class="s2">&quot;-&quot;</span> to + display the xml in the stdout. + -t TRANSITION_TIME, --transition-time TRANSITION_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> transitions must last <span class="o">(</span>default value + is <span class="m">2</span> seconds<span class="o">)</span> + -d DISPLAY_TIME, --display-time DISPLAY_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> a picture must be displayed. Default + value is <span class="m">900</span> <span class="o">(</span>15mn<span class="o">)</span> + -s, --set-background <span class="s1">&#39;&#39;</span><span class="err">&#39;</span>try to <span class="nb">set</span> the background using gnome-appearance- + properties + -b, --debug +</pre></div> +How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html<p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr …</pre><p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr/ports/lang/php5-extensions +$ make package-recursive -C /usr/ports/lang/php5-extensions + +# install nginx +$ make config-recursive -C /usr/ports/www/nginx-devel +$ make package-recursive -C /usr/ports/www/nginx-devel +</pre> +<p>Now we have all the dependencies installed, we need to configure a bit the +server.</p> +<p>That's a simple thing in fact, but it could be good to have something that will +work without effort over time.</p> +<p>Here's a sample of my configuration:</p> +<pre class="literal-block"> +server { + server_name ndd; + set $path /path/to/your/files; + root $path; + + location / { + index index.php; + } + + location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { + access_log off; + expires 30d; + } + + location ~ .php$ { + fastcgi_param SCRIPT_FILENAME $path$fastcgi_script_name; + fastcgi_pass backend; + include fastcgi_params; + } +} + +upstream backend { + server 127.0.0.1:9000; +} +</pre> +<p>And that's it !</p> +Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html<p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple tool to generate your …</p><p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" 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's easy to extend, +and has a template support (via jinja2).</p> +<p>I'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's needs.</p> +<p>Need an example ? You're looking at it ! This weblog is using pelican to be +generated, also for the atom feeds.</p> +<p>I've released it under AGPL, since I want all the modifications to be profitable +to all the users.</p> +<p>You can find a repository to fork at <a class="reference external" href="https://github.com/getpelican/pelican/">https://github.com/getpelican/pelican/</a>. +feel free to hack it !</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 (<cite>pelican --help</cite>)</p> +<div class="highlight"><pre><span></span>$ pip install pelican +</pre></div> +<div class="section" id="usage"> +<h2>Usage</h2> +<p>Here's a sample usage of pelican</p> +<div class="highlight"><pre><span></span>$ pelican . +writing /home/alexis/projets/notmyidea.org/output/index.html +writing /home/alexis/projets/notmyidea.org/output/tags.html +writing /home/alexis/projets/notmyidea.org/output/categories.html +writing /home/alexis/projets/notmyidea.org/output/archives.html +writing /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 ! +</pre></div> +<p>You also can use the <cite>--help</cite> option for the command line to get more +informations</p> +<div class="highlight"><pre><span></span><span class="nv">$pelican</span> --help +usage: pelican <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-t TEMPLATES<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> <span class="o">[</span>-m MARKUP<span class="o">]</span> <span class="o">[</span>-s SETTINGS<span class="o">]</span> <span class="o">[</span>-b<span class="o">]</span> + path + +A tool to generate a static blog, with restructured text input files. + +positional arguments: + path Path where to find the content files <span class="o">(</span>default is + <span class="s2">&quot;content&quot;</span><span class="o">)</span>. + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -t TEMPLATES, --templates-path TEMPLATES + Path where to find the templates. If not specified, + will uses the ones included with pelican. + -o OUTPUT, --output OUTPUT + Where to output the generated files. If not specified, + a directory will be created, named <span class="s2">&quot;output&quot;</span> in the + current path. + -m MARKUP, --markup MARKUP + the markup language to use. Currently only + ReSTreucturedtext is available. + -s SETTINGS, --settings SETTINGS + the settings of the application. Default to None. + -b, --debug +</pre></div> +<p>Enjoy :)</p> +</div> +An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html<p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the …</p><p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the PyPI +testing infrastructure. You could find what each person have done +on +<a class="reference external" 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 shape.</p> +<p>Then, I'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've been introducing myself to +python in the late 2009.</p> +<p>I'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've traveled +since I wrote it.</p> +<p>This summer was awesome because I've learned about python good +practices, now having some strong +<a class="reference external" href="http://mercurial.selenic.com/">mercurial</a> knowledge, and I've +seen a little how the python community works.</p> +<p>Then, I would like to say a big thanks to all the mentors that have +hanged around while needed, on IRC or via mail, and especially my +mentor for this summer, <a class="reference external" 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 work!</p> +<div class="section" id="why"> +<h2>Why ?</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 way.</p> +<p>Now, we have PEPs that describes some format we agreed on (see PEP +345), and we wanted to have a tool on which users can base their +code on, that's <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>.</p> +</div> +<div class="section" id="my-job"> +<h2>My job</h2> +<p>I had to provide a way to crawl the PyPI indexes in a simple way, +and do some installation / uninstallation scripts.</p> +<p>All the work done is available in +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket repository</a>.</p> +<div class="section" id="crawling-the-pypi-indexes"> +<h3>Crawling the PyPI indexes</h3> +<p>There are two ways of requesting informations from the indexes: +using the &quot;simple&quot; index, that is a kind of REST index, and using +XML-RPC.</p> +<p>I've done the two implementations, and a high level API to query +those twos. Basically, this supports the mirroring infrastructure +defined in PEP 381. So far, the work I've done is gonna be used in +pip (they've basically copy/paste the code, but this will change as +soon as we get something completely stable for distutils2), and +that's a good news, as it was the main reason for what I've done +that.</p> +<p>I've tried to have an unified API for the clients, to switch from +one to another implementation easily. I'm already thinking of +adding others crawlers to this stuff, and it was made to be +extensible.</p> +<p>If you want to get more informations about the crawlers/PyPI +clients, please refer to the distutils2 documentation, especially +<a class="reference external" 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 class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> source code .</p> +</div> +<div class="section" id="installation-uninstallation-scripts"> +<h3>Installation / Uninstallation scripts</h3> +<p>Next step was to think about an installation script, and an +uninstaller. I've not done the uninstaller part, and it's a smart +part, as it's basically removing some files from the system, so +I'll probably do it in a near future.</p> +<p><a class="reference external" 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 +METADATA (1.2) (See, the PEP 345), but I'm working on a +compatibility layer for the old metadata, and for the informations +provided via PIP requires.txt, for instance.</p> +</div> +<div class="section" id="extra-work"> +<h3>Extra work</h3> +<p>Also, I've done some extra work. this includes:</p> +<ul class="simple"> +<li>working on the PEP 345, and having some discussion about it +(about the names of some fields).</li> +<li>writing a PyPI server mock, useful for tests. you can find more +information about it on the +<a class="reference external" href="http://distutils.notmyidea.org">documentation</a>.</li> +</ul> +</div> +</div> +<div class="section" id="futures-plans"> +<h2>Futures plans</h2> +<p>As I said, I've enjoyed working on distutils2, and the people I'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 usable.</p> +<p>I'm not plainly satisfied by the work I've done, so I'll probably +tweak it a bit: the installer part is not yet completely finished, +and I want to add support for a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +index in the future.</p> +<p>We'll talk again of this in the next months, probably, but we +definitely need a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +API for <a class="reference external" href="http://pypi.python.org">PyPI</a>, as the &quot;simple&quot; index +<em>is</em> an ugly hack, in my opinion. I'll work on a serious +proposition about this, maybe involving +<a class="reference external" href="http://couchdb.org">CouchDB</a>, as it seems to be a good option +for what we want here.</p> +</div> +<div class="section" id="issues"> +<h2>Issues</h2> +<p>I've encountered some issues during this summer. The main one is +that'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 emails.</p> +<p>I've finally managed to work in an office, so good point for +home/office separation.</p> +<p>I'd not planned there will be so a high number of emails to read, +in order to follow what'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 !).</p> +</div> +<div class="section" id="thanks"> +<h2>Thanks !</h2> +<p>A big thanks to <a class="reference external" href="http://www.graine-libre.fr/">Graine Libre</a> and +<a class="reference external" 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're a student, if you're +interested about FOSS, dont hesitate any second, it's a really good +opportunity to work on interesting projects!</p> +</div> +Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html<p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my …</p><p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my weekly +summaries in +<a class="reference external" href="http://wiki.notmyidea.org/distutils2_schedule">a dedicated wiki page</a>.</p> +<div class="section" id="general-feelings"> +<h2>General feelings</h2> +<p>First, and it's a really important point, the GSoC is going very +well, for me as for other students, at least from my perspective. +It's a pleasure to work with such enthusiast people, as this make +the global atmosphere very pleasant to live.</p> +<p>First of all, I've spent time to read the existing codebase, and to +understand what we're going to do, and what's the rationale to do +so.</p> +<p>It's really clear for me now: what we'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 PEP about packaging.</p> +<p>With distutils2, it will be simpler to make &quot;things&quot; 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 so.</p> +</div> +<div class="section" id="tasks"> +<h2>Tasks</h2> +<p>My main task while working on distutils2 is to provide an +installation and an un-installation command, as described in PEP +376. For this, I first need to get informations about the existing +distributions (what's their version, name, metadata, dependencies, +etc.)</p> +<p>The main index, you probably know and use, is PyPI. You can access +it at <a class="reference external" href="http://pypi.python.org">http://pypi.python.org</a>.</p> +</div> +<div class="section" id="pypi-index-crawling"> +<h2>PyPI index crawling</h2> +<p>There is two ways to get these informations from PyPI: using the +simple API, or via xml-rpc calls.</p> +<p>A goal was to use the version specifiers defined +in`PEP 345 &lt;<a class="reference external" href="http://www.python.org/dev/peps/pep-0345/">http://www.python.org/dev/peps/pep-0345/</a>&gt;`_ and to +provides a way to sort the grabbed distributions depending our +needs, to pick the version we want/need.</p> +<div class="section" id="using-the-simple-api"> +<h3>Using the simple API</h3> +<p>The simple API is composed of HTML pages you can access at +<a class="reference external" 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's why I've preferred to pick up +the good ideas, and some implementation details, plus re-thinking +the global architecture.</p> +<p>The rules are simple: each project have a dedicated page, which +allows us to get informations about:</p> +<ul class="simple"> +<li>the distribution download locations (for some versions)</li> +<li>homepage links</li> +<li>some other useful informations, as the bugtracker address, for +instance.</li> +</ul> +<p>If you want to find all the distributions of the &quot;EggsAndSpam&quot; +project, you could do the following (do not take so attention to +the names here, as the API will probably change a bit):</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>We also could use version specifiers:</p> +<div class="highlight"><pre><span></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 (&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> +</pre></div> +<p>Internally, what's done here is the following:</p> +<ul class="simple"> +<li>it process the +<a class="reference external" href="http://pypi.python.org/simple/FooBar/">http://pypi.python.org/simple/FooBar/</a> +page, searching for download URLs.</li> +<li>for each found distribution download URL, it creates an object, +containing informations about the project name, the version and the +URL where the archive 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 &quot;final&quot; distribution (rather +than beta, alpha etc. ones)</li> +</ul> +<p>So, nothing hard or difficult 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're curious, please browse the +<a class="reference external" href="http://distutils2.notmyidea.org/">distutils2 documentation</a>.</p> +</div> +<div class="section" id="using-xml-rpc"> +<h3>Using xml-rpc</h3> +<p>We also can make some xmlrpc calls to retreive informations from +PyPI. It's a really more reliable way to get informations from from +the index (as it's just the index that provides the informations), +but cost processes on the PyPI distant server.</p> +<p>For now, this way of querying the xmlrpc client is not available on +Distutils2, as I'm working on it. The main pieces are already +present (I'll reuse some work I've made from the SimpleIndex +querying, and +<a class="reference external" 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's on what I'm actually working on.</p> +</div> +</div> +<div class="section" id="processes"> +<h2>Processes</h2> +<p>For now, I'm trying to follow the &quot;documentation, then test, then +code&quot; path, and that seems to be really needed while working with a +community. Code is hard to read/understand, compared to +documentation, and it's easier to change.</p> +<p>While writing the simple index crawling work, I must have done this +to avoid some changes on the API, and some loss of time.</p> +<p>Also, I've set up +<a class="reference external" 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 +...)</p> +</div> +Sprinting on distutils2 in Tours2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/sprinting-on-distutils2-in-tours.html<p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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 …</p><p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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'd really enjoyed this +time, because Éric knows a lot of things about mercurial and python +good practices, and I'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 had.</p> +<div class="section" id="documentation"> +<h2>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'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 those:</p> +<ul class="simple"> +<li><strong>Packagers</strong> who want to distribute their softwares.</li> +<li><strong>End users</strong> who need to understand how to use end user +commands, like the installer/uninstaller</li> +<li><strong>packaging coders</strong> who <em>use</em> distutils2, as a base for +building a package 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 API +description ? etc. That's maybe seems to be not so important, but I +guess the readers would appreciate to have the same structure all +along distutils2 documentation.</p> +</div> +<div class="section" id="mercurial"> +<h2>Mercurial</h2> +<p>I'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'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've not used them so far, so consider this as +a personal note.</p> +<ul class="simple"> +<li>hg histedit, to edit the history</li> +<li>hg crecord, to select the changes to 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 class="reference external" 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 ... Great. I'm a powerful merger now !</p> +</div> +<div class="section" id="on-using-tools"> +<h2>On using 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've +discovered vimdiff and hgtk, which will completely change the way I +navigate into the mercurial history. We aren't &quot;power users&quot;, so we +have learned from each other about vim tips. You can find +<a class="reference external" href="http://github.com/ametaireau/dotfiles">my dotfiles on github</a>, +if it could help. They're not perfect, and not intended to be, +because changing all the time, as I learn. Don't hesitate to have a +look, and to propose enhancements if you have !</p> +</div> +<div class="section" id="on-being-pythonic"> +<h2>On being 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 class="reference external" 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 do.</p> +</div> +<div class="section" id="conclusion"> +<h2>Conclusion</h2> +<p>It was really great. Next time, we'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'll probably do +another sprint in a few weeks, stay tuned !</p> +</div> +Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html<p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 …</p><p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 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 class="reference external" href="http://docutils.sourceforge.net/rst.html">restructured text</a>, so +I've wrote a simple file containing our different bullet points. In +fact, there is quite nothing to do then, to have a working +presentation.</p> +<p>So far, I've used +<a class="reference external" href="http://code.google.com/p/rst2pdf/">the rst2pdf program</a>, and a +simple template, to generate output. It's probably simple to have +similar results using latex + beamer, I'll try this next time, but +as I'm not familiar with latex syntax, restructured text was a +great option.</p> +<p>Here are +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.pdf">the final PDF output</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.rst">Rhe ReST source</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/slides.style">the theme used</a>, +and the command line to generate the PDF:</p> +<pre class="literal-block"> +rst2pdf couchdb.rst -b1 -s ../slides.style +</pre> +first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html<p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I've not worked as much as I +wanted, and this will continues until the end of …</p><p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I'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 class="reference external" 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 class="reference external" href="http://pypi.python.org/">PyPI</a>), and there is at +least two ways to retreive informations from here: XML-RPC and the +&quot;simple&quot; API.</p> +<p>So, I've been working on porting some +<a class="reference external" href="http://bitbucket.org/tarek/distribute/">Distribute</a> related +stuff to <a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a>, cutting +off all non distutils' things, as we do not want to depend from +Distribute's internals. My main work has been about reading the +whole code, writing tests about this and making those tests +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've taken some time to improve the work +<a class="reference external" href="http://bitbucket.org/konrad">Konrad</a> makes about this mock.</p> +<div class="section" id="a-pypi-server-mock"> +<h2>A PyPI Server 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 class="reference external" href="http://wsgi.org">WSGI</a> and +<a class="reference external" 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 class="reference external" 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 +Distutils2).</p> +<p>So, we switched to +<a class="reference external" href="http://docs.python.org/library/basehttpserver.html">BaseHTTPServer</a> +and +<a class="reference external" href="http://docs.python.org/library/simplehttpserver.html">SimpleHTTPServer</a>, +and updated our tests accordingly. It's been an opportunity to +realize that <a class="reference external" href="http://wsgi.org">WSGI</a> has been a great step +forward for making HTTP servers, and expose a really simplest way +to discuss with HTTP !</p> +<p>You can find +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/changesets">the modifications I made</a>, +and the +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/src/tip/docs/source/test_framework.rst">related docs</a> +about this on +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket distutils2 clone</a>.</p> +</div> +<div class="section" id="the-pypi-simple-api"> +<h2>The PyPI Simple API</h2> +<p>So, back to the main problematic: make a python library to access +and request information stored on PyPI, via the simple API. As I +said, I've just grabbed the work made from +<a class="reference external" 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 tests.</p> +</div> +<div class="section" id="the-work-to-come"> +<h2>The work to come</h2> +<p>So, once all use cases covered with tests, I'll rewrite a bit the +grabbed code, and do some software design work (to not expose all +things as privates methods, have a clear API, and other things like +this), then update the tests accordingly and write a documentation +to make this clear.</p> +<p>Next step is to a little client, as I've +<a class="reference external" href="http://github.com/ametaireau/pypiclient">already started here</a> +I'll take you updated !</p> +</div> +A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html<p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python …</blockquote><p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python application (pip, setuptools, distribute, distutils, etc.) +so&nbsp;there is a huge effort to make in order to make all this +packaging stuff interoperable, as pointed out by +the&nbsp;<a class="reference external" href="http://www.python.org/dev/peps/pep-0376/">PEP 376</a>.</blockquote> +<p>In more details, I'm going to work on the Installer / Uninstaller +features of Distutils2, and on a PyPI XML-RPC client for distutils2. +Here are the already defined tasks:</p> +<ul class="simple"> +<li>Implement Distutils2 APIs described in PEP 376.</li> +<li>Add the uninstall command.</li> +<li>think about a basic installer / uninstaller script. (with deps) +-- similar to pip/easy_install</li> +<li>in a pypi subpackage;</li> +<li>Integrate a module similar to setuptools' package_index'</li> +<li>PyPI XML-RPC client for distutils 2: +<a class="reference external" href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> +</ul> +<p>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.</p> + \ No newline at end of file diff --git a/feeds/all-fr.atom.xml b/feeds/all-fr.atom.xml new file mode 100644 index 0000000..c47a416 --- /dev/null +++ b/feeds/all-fr.atom.xml @@ -0,0 +1,1387 @@ + +Carnets Webhttps://blog.notmyidea.org/2013-08-16T00:00:00+02:00Des carnets d'esquisse2013-08-16T00:00:00+02:002013-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-08-16:/des-carnets-desquisse-fr.html<p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir …</p><p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir un &quot;carnet&quot; et d'y jeter juste quelques +notes. Pas grand chose: mes quelques pensées ou alors des liens 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.</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'accueil, mais vous pouvez les +trouver dans <a class="reference external" href="https://blog.notmyidea.org/category/notes.html">la section notes</a>.</p> +<p>Je ne sais pas encore si il s'agit du meilleur endroit pour ça, mais peu importe, +essayons. A bas la pudeur rédactionelle.</p> +<p>J'ai du au passage chambouler un peu vos agrégateurs, pardonnez moi :)</p> +<div class="section" id="le-retour-des-commentaires"> +<h2>Le retour des commentaires</h2> +<p>Au passage, je ne me rappelle plus quand exactement, mais j'avais décidé de +supprimer les commentaires de cet espace. Paf, apu. Comme ça, sans prévenir.</p> +<p>Les raisons en étaient à la fois techniques (je ne souhaitait pas avoir recours +à disqus qui est un silo propriétaire de plus) et parce que je considérais que +les commentaires n'avaient que peu d'intérêt. Ceci dit, le manque d'échange me +manque; j'aimerais bien savoir ce que vous pensez de ce que j'écris des fois, +et avoir des débats si nos opinions divergent.</p> +<p>Et puis bon, partager dans un seul sens, c'est un peu dommage !</p> +<p>Il est maintenant possible, avec <a class="reference external" href="http://talka.tv">talka.tv</a> d'héberger soi +même ses commentaires. J'ai dans l'idée d'héberger une instance de ce service +sur <cite>discus.notmyidea.org</cite>, 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 !)</p> +</div> +Des profils de confiance partout et pour tout ?2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/confiance-fr.html<p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site …</p><p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site et de les appeler soi même, chose maintenant automatisée.</p> +<p>Dès que cette décision à été prise, il y a eu des émules. Le site <a class="reference external" href="http://covoiturage-libre.fr">Covoiturage +Libre</a> à été d'ailleurs créé pour faire en sorte +de garder &quot;l'esprit&quot; du covoiturage. Bref ça jasait dans les chaumières.</p> +<p>Il y à peu, j'ai reçu un <em>couriel</em> contenant un lien vers une vidéo d'<a class="reference external" href="http://www.covoiturage.fr/blog/2013-confiance">une +conférence animée par le fondateur de covoiturage.fr</a>.</p> +<p>Ils semblent vouloir parler de confiance, alors ça m'intrigue, d'autant que la +présentation en question est donnée lors d'un évènement TEDx, auquel j'accorde +un certain crédit.</p> +<div class="section" id="un-capital-de-confiance"> +<h2>Un &quot;capital de confiance&quot;</h2> +<p>Cette vidéo parle entre autres du <em>capital de confiance</em> que nous pouvons +nous accorder les uns aux autres; et notamment du fait que ce capital de +confiance n'est malheureusement pas partagé au dela d'un cercle de +connaissances assez limité. Il reste dans notre cercle de connaissances proche, les +amis des amis.</p> +<p>C'est donc une chose regrettable, parce que ça nous fait perdre du temps (et +donc, <em>ohmygod</em> de l'argent) à tous pour construire cette confiance. Temps qui +pourrait être mieux employé.</p> +<p>La solution proposée, attention les yeux, est de faire appel un maximum aux +profils en ligne, une manière de &quot;prouver au monde&quot; que nous sommes des +personnes de confiance. Selon les termes de la présentation, nous pourrions +alors tous devenir des &quot;super héros du trust&quot;, des &quot;trustman&quot;.</p> +<p>Grâce à des profils en ligne ou monsieur et madame tout le monde pourraient +aller voter et donner leur avis sur les personnes qu'ils ont rencontré.</p> +</div> +<div class="section" id="l-avenement-du-paiement-en-ligne"> +<h2>L'avènement du paiement en ligne</h2> +<p>On nous dit maintenant que le paiement en ligne est une révolution, un moyen de +tracer le fait qu'il y à effectivement eu une transaction entre deux personnes; +et que donc il en deviendrait un outil pour vérifier que la confiance est bien +légitime, et non pas créée de toute pièce sur le profil de la personne en +question.</p> +<p>Plu</p> +<p>Plus exactement, ce qui est dit est que le paiement en ligne permet de +justifier qu'il y a bien eu transaction entre deux personnes, et que donc les +commentaires et &quot;notations&quot; effectuées sont donc légitimes.</p> +</div> +<div class="section" id="ce-n-est-pas-un-probleme-de-confiance"> +<h2>Ce n'est pas un problème de confiance !</h2> +<p>Bien que j'arrive à suivre le raisonnement, il soulève certaines questions :</p> +<p>Si j'accorde de la confiance à quelqu'un dans mon cercle de connaissances, +c'est justement parce qu'il fait partie de ce cercle de connaissances. Pas +parce qu'une personne que je ne connait pas me dit qu'il s'agit d'une personne +de confiance. En d'autres termes, <strong>pourquoi ne garderions nous pas ces +relations privilégiées de personne à personne ?</strong></p> +<p>Dans le cadre du covoiturage, j'arrive à comprendre le raisonnement du paiement +<em>à l'avance</em>, pour avoir souvent entendu parler de désistements à la dernière +minute de la part des voyageurs. Le paiement à l'avance permet d'éviter ce +genre de désagréments.</p> +<p>Mais cela n'as rien à voir avec la confiance, il s'agit d'engagement de la part +des deux parties.</p> +<p>Et c'est bien ce qui semble poser problème: lorsqu'on s'attend à partager le +prix d'un trajet avec quelqu'un, c'est bien d'avoir quelque chose qui nous +y engage. J'aime beaucoup l'idée de payer une fois dans la voiture, de garder +cette transaction manuelle; et de laisser peu de place au paiements en ligne +dans cette histoire, mais je n'ai pas d'autre solution miracle.</p> +<p>En tout cas, la question n'est pas la question de savoir avec qui on embarque, +mais bel et bien la question de l'engagement des deux parties.</p> +<p>Nous sommes malheureusement dans une société qui est dirigée par la peur. On +à peur de se faire agresser par le gars qui tends le pouce sur le bord de la +route, peur de se faire envoyer un produit qui ne fonctionne pas via Amazon, +etc.</p> +<p>En poussant l'idée dans ses retranchements, j'aurais bientôt peur de mes +voisins alors je ne leur parlerais plus, parce qu'ils n'ont pas leur profil +disponible en ligne ou parce que quelqu'un à eu une mauvaise expérience avec +eux ?</p> +<p>Exposer des choses qui relèvent de ma vie privée en ligne de la sorte me +pose des problèmes éthiques: d'abord parce que je ne veux pas juger les gens +a priori, ensuite parce que l'expérience d'une personne n'est peut-être pas +représentative, tout simplement.</p> +<p>Donc non, ce n'est pas un problème de confiance, il s'agit d'un problème +d'engagement, dans le cadre du covoiturage, et les profils en ligne n'ont rien +à faire la dedans. Le principe du paiement à l'avance me semble intéressant, +mais il n'est à mon avis pas lié au profils en ligne.</p> +<p>La vidéo termine sur un &quot;libérez la valeur de la confiance&quot;. Oui, mais la +libérer pour qui ? Quels sont les problèmes liés à cette confiance rendue +nécessaire partout et pour tout ? Cela ne nous ferait-il pas évoluer uniquement +dans des cercles fermés ? Quelle place laisser à l'inconnu, à la surprise ?</p> +<p>Cette volonté de &quot;confiance partout&quot; semble découler tout droit des délires +sécuritaires que l'on nous sert à toutes les sauces. Et maintenant cela +serait rendu accessible à tous grâce à &quot;l'intelligence collective&quot;; gommant au +passage les différences de valeur; Préférant éviter de rencontrer les inconnus +aux profils &quot;légers&quot;.</p> +<p>Je sais pas vous, mais elle me fait peur cette idée.</p> +</div> +Status board2012-12-29T00:00:00+01:002012-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-29:/status-board-fr.html<p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org …</cite></p><p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org</cite>, mon serveur.</p> +<p>Jusqu'à très récemment, rien de tout ça n'était sauvegardé, et non plus monitoré. +Après quelques recherches, je suis tombé sur <a class="reference external" href="http://www.stashboard.org/">stashboard</a>, un &quot;status board&quot; qu'il est bien fait. Le seul +problème, c'est écrit pour se lancer sur GAE, <em>Google App Engine</em>. +Heureusement, c'est open-source, et ça a été forké pour donner naissance +à <a class="reference external" href="https://github.com/bfirsh/whiskerboard">whiskerboard</a> (la planche +moustachue, pour les non anglophones).</p> +<img alt="Capture d'écran du site." src="images/status_board.png" /> +<div class="section" id="verifier-le-statut-des-services"> +<h2>Vérifier le statut des services</h2> +<p>Donc, c'est chouette, c'est facile à installer, tout ça, mais… mais ça ne fait +en fait pas ce que je veux: ça ne fait que m'afficher le statut des services, +mais ça ne vérifie pas que tout est bien &quot;up&quot;.</p> +<p>Bon, un peu embêtant pour moi, parce que c'est vraiment ça que je voulais. Pas +grave, je sais un peu coder, autant que ça serve. J'ai ajouté quelques +fonctionnalités au soft, qui sont disponibles sur mon fork, sur +github:: <a class="reference external" href="https://github.com/ametaireau/whiskerboard">https://github.com/ametaireau/whiskerboard</a> .</p> +<p>Entres autres, il est désormais possible de lancer <a class="reference external" 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 spécifique.</p> +<p>C'é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 dépote).</p> +<p>Les modifications sont assez simples, vous pouvez aller jeter un œil aux +changements ici: +<a class="reference external" href="https://github.com/ametaireau/whiskerboard/compare/b539337416...master">https://github.com/ametaireau/whiskerboard/compare/b539337416...master</a></p> +<p>En gros:</p> +<ul class="simple"> +<li>ajout d'une <cite>connection_string</cite> aux services (de la forme +protocol://host:port)</li> +<li>ajout d'une commande <cite>check_status</cite> qui s'occupe d'itérer sur les services et +de lancer des taches celery qui vont bien, en fonction du protocole</li> +<li>ajout des taches en question</li> +</ul> +</div> +<div class="section" id="deploiement"> +<h2>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, forcément.</p> +<p>Après un essai (plutôt rapide en fait) sur <a class="reference external" href="http://heroku.com">heroku</a>, je me +suis rendu compte qu'il me fallait payer pas loin de 35$ par mois pour avoir un +process <cite>celeryd</cite> qui tourne, donc j'ai un peu cherché ailleurs, pour +finalement déployer la chose chez <a class="reference external" href="https://www.alwaysdata.com/">alwaysdata</a></p> +<p>Après quelques péripéties, j'ai réussi à faire tourner le tout, ça à été un peu +la bataille au départ pour installer virtualenv (j'ai du faire des changements +dans mon <cite>PATH</cite> pour que ça puisse marcher), voici mon <cite>.bash_profile</cite>:</p> +<pre class="literal-block"> +export PYTHONPATH=~/modules/ +export PATH=$HOME/modules/bin:$HOME/modules/:$PATH +</pre> +<p>Et après y'a plus qu'à installer avec <cite>easy_install</cite>:</p> +<pre class="literal-block"> +easy_install --install-dir ~/modules -U pip +easy_install --install-dir ~/modules -U virtualenv +</pre> +<p>Et à créer le virtualenv:</p> +<pre class="literal-block"> +virtualenv venv +venv/bin/pip install -r requirements.txt +</pre> +<p>Dernière étape, la création d'un fichier <cite>application.wsgi</cite> qui s'occupe de +rendre l'application disponible, avec le bon venv:</p> +<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span> +<span class="kn">import</span> <span class="nn">sys</span> + +<span class="n">activate_this</span> <span class="o">=</span> <span class="s1">&#39;/home/lolnet/venv/bin/activate_this.</span> +<span class="nb">execfile</span><span class="p">(</span><span class="n">activate_this</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="vm">__file__</span><span class="o">=</span><span class="n">activate_this</span><span class="p">))</span> + +<span class="n">paths</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;/home/lolnet/public&#39;</span><span class="p">,]</span> + +<span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">paths</span><span class="p">:</span> + <span class="k">if</span> <span class="n">path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="p">:</span> + <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> + + <span class="kn">import</span> <span class="nn">django.core.handlers.wsgi</span> + <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;DJANGO_SETTINGS_MODULE&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;settings&#39;</span> + <span class="n">application</span> <span class="o">=</span> <span class="n">django</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIHandler</span><span class="p">()</span> +</pre></div> +</div> +<div class="section" id="ssl-et-requests"> +<h2>SSL et Requests</h2> +<p>Quelques tours de manivelle plus loin, j'ai un celeryd qui tourne et qui +consomme les taches qui lui sont envoyées (pour des questions de simplicité, +j'ai utilisé le backend <cite>django</cite> de celery, donc pas besoin d'AMQP, par +exemple).</p> +<p>Problème, les ressources que je vérifie en SSL (HTTPS) me jettent. Je sais pas +exactement pourquoi à l'heure qu'il est, mais il semble que lorsque je fais une +requête avec <a class="reference external" 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 <cite>CURL</cite> fonctionnent, donc j'ai fait <a class="reference external" href="https://github.com/ametaireau/whiskerboard/blob/master/board/tasks.py#L17">un fallback +vers CURL lorsque les autres méthodes échouent</a>. +Pas super propre, mais ça fonctionne.</p> +<p><strong>EDIT</strong> Finalement, il se trouve que mon serveur était mal configuré. +J'utilisais haproxy + stunnel, et la négiciation SSL se passait mal. Une fois +SSL et TLS activés, et SSLv2 désactivé, tout fonctionne mieux.</p> +</div> +<div class="section" id="et-voila"> +<h2>Et voilà</h2> +<p>Finalement, j'ai mon joli status-board qui tourne à merveille sur +<a class="reference external" href="http://status.lolnet.org">http://status.lolnet.org</a> :-)</p> +</div> +Lifestyle2012-11-05T00:00:00+01:002012-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-11-05:/lifestyle-fr.html<p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre …</p><p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre une vie connectée et +une vie <em>réelle</em> (oui, celle avec des vrais gens qui ont d'autres +préoccupations que l'informatique !). Comment réussir à trouver un juste +milieu entre le geek inconditionnel et le bon vivant, qui à du temps à +consacrer à autre chose qu'à son travail ?</p> +<div class="section" id="voyages"> +<h2>Voyages</h2> +<p>Un des premiers trucs que j'ai trouvé surprennant en arrivant à Mozilla, c'est +la fréquence des voyages que l'on peut être amené à avoir. Ah, c'est pour la +bonne cause, c'est tellement plus sympa d'avoir les collègues à coté pour +bosser, plutôt qu'à l'autre bout du monde. Mais quand même, si je le voulais, +entre les semaines de travail et les conférences, je pourrais être tous les +deux mois aux États-Unis !</p> +<p>Une aubaine, penserons certains. Voyager, c'est <em>cool</em> ! Bon, si on mets de +coté le cout écologique d'un voyage (nécessairement en avion), la chose qui me +dérange le plus c'est cette impression de venir pour repartir. Voyager, c'est +sympa, mais avoir le temps de prendre un rythme de vie différent, de rencontrer +des gens, de construire quelque chose, ça me manque.</p> +<p>Donc je décline quand je n'en ai pas l'envie, tout simplement. Je loupe des +choses intéressantes (<a class="reference external" href="http://pycon.us">PyCon</a> à Santa Clara avait vraiment l'air +chouette !), mais ça me permet également d'avoir plus de temps pour vivre là ou +j'habite, pour construire quelque chose localement. Et puis des évènements, il +y en à tellement en France et en Europe auquel je n'assiste pas que ça me fait +mal au cœur d'aller à l'autre bout du monde pour faire la même chose !</p> +<p>Bien sur, je serais amené à voyager. Et autant que faire se peut je le +ferais avec plaisir et je tenterais de rester un peu plus avant et après sur +place (plus question de faire un aller/retour en une semaine !), question de me +faire à l'atmosphère ! <a class="reference external" href="http://ziade.org">Tarek</a> est par exemple resté un mois à San Francisco +en janvier pour son dernier séjour, alors pourquoi ne pas prendre exemple ? +Tout de suite ça me parles plus.</p> +</div> +<div class="section" id="et-quand-est-ce-qu-on-arrete"> +<h2>Et quand-est-ce qu'on arrête ?</h2> +<p>Une autre chose assez difficile à gérer, c'est le temps.</p> +<p>J'ai vraiment une chance monstrueuse, celle de faire un travail qui me plait, +éthiquement et techniquement. Je pourrais y passer mes journées et mes nuits +que je n'aimerais pas moins ça (même si il m'arrive bien sur de saturer !).</p> +<p>Mais j'ai aussi d'autres envies, qui signifient aussi passer du temps +hors-ligne, parce que bizarrement, c'est là que j'ai l'impression de réfléchir +le plus. Loin de ce surplus d'informations…</p> +<p>Facile à dire.</p> +<p>D'autant que quand il est possible de travailler depuis n'importe où, +la séparation physique entre le lieu de travail et le lieu de vie tends à +disparaitre assez facilement. Et sans séparation physique, il faut une sacré +motivation pour savoir quand commencer et quand s'arrêter.</p> +<p>J'essaye de me donner une règle simple: point trop n'en faut. Aucun intérêt à +rester travailler des heures durant sans s'arrêter, ou en tout cas pas +d'intérêt à le faire de manière trop régulière. Une journée qui commence tôt +(~9h) me permet de me concentrer le matin (les collègues californiens dorment) +et d'avoir un rythme assez &quot;normal&quot;. Et puis, avec ce soleil qui commence à +inonder les terrasses, autant faire autre chose que de rester enfermé à coder +en fin d'après midi !</p> +</div> +<div class="section" id="surplus"> +<h2>Surplus</h2> +<p>Tiens, je parlais de surplus, nous y sommes. Que ça soit le surplus +d'informations ou le surplus d'objets, ça m'encombre ! Une journée, pour ma +part est faite de communications diverses, de code et de lectures (se tenir au +courant de ce qui se passe dans le monde du logiciel n'est pas une tâche des +plus facile, et qui peut facilement prendre énormément de temps).</p> +<p>Je me demande si je ne devrais pas aspirer à la frugalité de ce coté là +également. Je reçois des mails toute la journée, et mon aggrégateur rss/atom se +remplit également très vite. Mais je n'ai aucunement besoin d'avoir toutes ces +informations dans l'heure, et de les vérifier de manière fréquente. De la même +manière, j'ai simplement arrêté de lire mes flux rss.</p> +<p>Quelques (longues) fois dans la semaine semblent suffire et me permettent de +réussir à rester concentrer.</p> +</div> +<div class="section" id="resolutions"> +<h2>Résolutions</h2> +<p>Soyons fous, tentons quelque chose de nouveau, c'est le printemps ! Pas de +communication dans la matinée, je n'en ai probablement pas besoin, sauf cas +extrêmes. Le matin, c'est pour se concentrer sur le travail à faire.</p> +<p>Une fois les mails du matin dépilés (à 9h30), pas la peine de garder un œil +sur ma boite mail, j'irais y faire un tour en début et en fin d'après midi.</p> +<p>Je pense même à débrancher internet, pour éviter les interactions et pour me +concentrer, mais j'ai comme l'impression que c'est un peu trop abrupt comme +approche.</p> +<p>Aussi, définir en début de journée la liste des choses prévues, et revenir +dessus jour après jour me permettra surement d'avoir un aperçu un peu plus +global du travail accompli.</p> +<p>L'avenir dira si tout ça fonctionne :-)</p> +</div> +Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla-fr.html<p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi …</p><p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi je me suis dit que ça pouvait avoir du sens de l'écrire +quelque part.</p> +<p>Ça parle bien sur de logiciel libre, de protection de la vie privée et de +contre-pouvoirs.</p> +<p>Je ne m'adresse pas ici aux afficionados du logiciel libre et du non contrôle +du web, mais aux potentiels intéressés, qui souhaitent comprendre ce qu'on fait +à Mozilla, pourquoi et comment, et plus particulièrement quel est le rôle que +je joue la dedans.</p> +<div class="section" id="logiciel-libre"> +<h2>Logiciel libre</h2> +<p>Une des premières choses qui vient à l'esprit des gens quand on parle de +Mozilla, et par extension de Firefox, c'est qu'il s'agit d'un logiciel gratuit. +D'un logiciel soit disant &quot;libre&quot;. Avouez que le concept est de prime abord +curieux. Un logiciel qui serait libéré, mais libéré de quoi ?</p> +<p>Je ne vais pas refaire la génèse du logiciel et du logiciel libre, mais pour +résumer et expliquer ça très grossièrement, le logiciel libre c'est pour moi +l'idée de la collaboration. &quot;Plutôt que de travailler chacun dans son coin, +construisons ensemble quelque chose qui nous sera utile à tous&quot;. Ça marche dans +le domaine de l'informatique parce qu'on est exposé à un bien commun non +matériel. Ce n'est pas parce que je te donne un logiciel que je ne l'ai plus. +La duplication est possible et elle rend la collaboration plus facile.</p> +<div class="section" id="euh-oui-mais"> +<h3>Euh, oui mais…</h3> +<p>Ok, ok. Et comment on coopère ? Derrière un logiciel, il faut écrire des lignes +de code, il faut décrire comment doit se comporter le logiciel dans l'ensemble +des cas qu'il peut rencontrer. Mais pas seulement. Beaucoup de personnes +travaillent pour faire en sorte que Firefox soit disponible dans près de 100 +langues et dialectes par exemple.</p> +<p>J'aime beaucoup penser que le logiciel libre réussit à réunir des personnes +avec des objectifs differents. Linux, qui est un logiciel libre, est par exemple +utilisé dans beaucoup de domaines très différents tels que la médecine, +l'automobile ou l'énergie.</p> +<p>Le logiciel libre est une valeur clé que nous défendons chez Mozilla.</p> +</div> +</div> +<div class="section" id="protection-de-la-vie-privee"> +<h2>Protection de la vie privée</h2> +<p>Mozilla en fait un peu sa devise. Nous ne sommes pas une entreprise, nous +n'avons aucun intérêt à enfermer les utilisateurs chez nous, et surtout nous +n'exploitons et n'exploiterons pas les données utilisateurs à des fins +commerciales. Jamais.</p> +<div class="section" id="stockage-des-donnees"> +<h3>Stockage des données</h3> +<p>Un exemple qui est frappant est celui de <a class="reference external" href="https://www.mozilla.org/en-US/mobile/sync/">Sync</a>, l'outil qui permet de +synchroniser les données de navigation entre plusieurs périphériques (Cela peut +être utile pour avoir votre historique de navigation partagé entre votre +ordinateur de bureau et un téléphone portable par exemple)</p> +<p>Les données qui sont stockées dans un service tel que sync sont cruciales: vos +mots de passe et votre historique de navigation par exemple. Imaginez ce que +des annonceurs publicitaires pourraient faire avec ces données. Il est assez +facile de connaître votre profil et donc d'ensuite faire de la publicité +ciblée à partir de ces informations. Voire pire. Donner ces données à qui fait +suffisemment pression sur vous pour les récupérer.</p> +<p>Heureusement, les données qui sont stockées sur les serveurs Sync sont +chifrées, et seul l'utilisateur a accès a la clé de chiffrement et de +déchiffrement. En d'autres termes, en ayant accès aux serveurs de Mozilla, même +de l'intérieur, je pourrais avoir accès à vos données mais je ne pourrais rien +en faire car celles-ci me sont impossibles à déchiffrer.</p> +<p>Mozilla essaye de mettre le doigt là où ça fait mal dans l'innovation web&nbsp;: la +publicité et le respect de la vie privée des utilisateurs. Facebook, Google, +Twitter sont autant d'entreprises qui gagnent de l'argent grâce à leurs +utilisateurs et à leurs données privées.</p> +<p>Cela n'est pas <em>nécessairement</em> un mal mais il me semble important d'informer +les utilisateurs d'Internet la dessus, et de leur proposer des méthodes qui +leur permettent de protéger leur vie privée.</p> +</div> +<div class="section" id="decentralisation"> +<h3>Décentralisation</h3> +<p>Un autre aspect important est le fait que vous n'avez pas besoin de dépendre des +serveurs de Mozilla si vous ne souhaitez pas en dépendre. Bien que nous +fassions tout ce qui est en notre pouvoir pour avoir des serveurs très réactifs +et capables de tenir la charge, nous ne sommes pas à l'abri de pannes. Auquel +cas il vous faudra simplement vous armer de patience.</p> +<p>Mais il est possible pour vous de maintenir votre propre serveur et de ne pas +dépendre de Mozilla pour stocker vos données privées. J'ai parlé de Sync mais +Mozilla (j'en parle un peu plus bas) travaille aussi sur un système +d'exploitation pour téléphone portable, nommé Firefox OS (anciennement Boot 2 +Gecko), et sur l'écosystème qui va avec.</p> +<p>Actuellement, si vous souhaitez synchroniser vos contacts par exemple, vous +dépendez quasiment toujours d'une autorité à qui vous ne faites peut être pas +confiance: Apple, Microsoft ou bien Google.</p> +<p>On ne vous propose pas simplement de nous faire confiance, on vous propose la +possibilité de ne faire confiance qu'à ceux à qui vous souhaitez accorder votre +confiance, et ça peut être vous si vous le souhaitez.</p> +<p>La décentralisation à ceci de bon qu'elle vous laisse le choix d'où vous +souhaitez stocker vos données.</p> +</div> +</div> +<div class="section" id="innovation-et-standardisation"> +<h2>Innovation et standardisation</h2> +<p>Mozilla, dès ses débuts, a été un laboratoire. Firefox (si je ne me trompe pas) +a été le premier navigateur à avoir des onglets. Le web, c'est cool parce que +ça bouge tout le temps ! (Edit: en fait, <a class="reference external" href="http://en.wikipedia.org/wiki/Tabbed_document_interface">ce n'était pas le premier</a>, mais l'idée est là)</p> +<p>La dernière innovation en date est Firefox OS: utilisons les technologies du +web pour créer un téléphone: utilisons le web comme plateforme, et profitons de +tout l'écosystème qui existe déjà autour de celui-ci.</p> +<p>C'est bien que ça bouge mais il faut qu'on se mette d'accord sur comment on +veut faire bouger les choses. La guerre des navigateurs a eu lieu. Ne pas +reproduire ça est parfois un challenge. La standardisation, tout le monde s'y +met.</p> +<p>On a gagné une guerre: aux utilisateurs de choisir les outils qu'ils souhaitent +et non pas aux développeurs d'imposer leurs choix.</p> +</div> +<div class="section" id="et-moi-qu-est-ce-que-je-fais-la-dedans"> +<h2>Et moi, qu'est-ce que je fais la dedans ?</h2> +<p>Je travaille dans l'équipe nommée Services. On travaille à la mise en +place de services web qui sont capables de tenir la charge, de fonctionner de +manière décentralisée.</p> +<p>Ce travail a plusieurs objectifs:</p> +<ul class="simple"> +<li>Mettre à disposition des outils pour les développeurs, leur permettant de +créer des services de bonne qualité rapidement;</li> +<li>Permettre aux utilisateurs d'héberger eux mêmes leurs propres serveurs s'ils +le souhaitent, réduisant leur dépendance a des services externes.</li> +<li>Écrire les services en question de telle manière que les utilisateurs (vous +!) puissent les utiliser sans avoir trop de tracas :)</li> +</ul> +<p>Ça semble peu, mais j'aime ce boulot. Éthiquement et techniquement. C'est ça, +pour moi, la mission de Mozilla. Si vous avez des suggestions sur ce qui +pourrait être amélioré dans les services de Mozilla en termes de protection de +la vie privée, de décentralisation et de haute disponibilité, vous savez vers +qui vous tourner !</p> +<p>La liste des projets sur lesquels je travaille ou j'ai travaillé à Mozilla pour +l'instant:</p> +<ul class="simple"> +<li><a class="reference external" href="https://github.com/mozilla-services/tokenserver">https://github.com/mozilla-services/tokenserver</a></li> +<li><a class="reference external" href="http://circus.io/">http://circus.io/</a></li> +<li><a class="reference external" href="http://powerhose.rtfd.org/">http://powerhose.rtfd.org/</a></li> +<li><a class="reference external" href="https://github.com/mozilla-services/server-aitc">https://github.com/mozilla-services/server-aitc</a></li> +<li><a class="reference external" href="http://cornice.readthedocs.org/en/latest/index.html">http://cornice.readthedocs.org/en/latest/index.html</a></li> +<li><a class="reference external" href="https://github.com/mozilla/PyBrowserID/">https://github.com/mozilla/PyBrowserID/</a></li> +<li><a class="reference external" href="http://chaussette.readthedocs.org/en/0.3/index.html">http://chaussette.readthedocs.org/en/0.3/index.html</a></li> +</ul> +</div> +Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-30:/bidouille-fr.html<p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de …</p><p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de comprendre comment les choses fonctionnent, +et depuis peu cette envie de mettre en pratique ces connaissances dépasse la +bidouille logicielle. J'ai passé une grosse partie de mon week-end à Main +d'Œuvre, où l'association <a class="reference external" href="http://www.underconstruction.fr">Under Construction</a> faisait se rencontrer le milieu de +l'éducation populaire et le milieu de la bidouille.</p> +<p>Forcement, ni une ni deux, je saute dans le bateau en marche et, n'étant ni un +très grand bidouilleur ni un très grand animateur, j'en ressort enrichi de +toutes ces rencontres, de tous ces préjugés qui tombent, et de quelques +découvertes bluffantes, des idées plein la tête.</p> +<p>J'avais entendu parler des &quot;<a class="reference external" href="http://www.reprap.org">rep-raps</a>&quot;, des +imprimantes en 3 dimensions capables de produire des pièces en plastique +mais je n'avais jamais eu l'occasion de voir le bousin en vrai. Et +c'est impressionnant. Vraiment. (&quot;Bienvenue dans le 21ème siècle !&quot;)</p> +<p>Ça laisse énormément à penser autour des questions d'émancipation +technologique, et de non dépendance envers les constructeurs, dans le milieu de +l'électro-ménager, par exemple. &quot;Ah tiens, cette pièce est cassée, je vais +aller utiliser la rep-rap du coin pour me la fabriquer&quot;. Et hop, on mets fin à +tout un cycle d'obsolescence programmée…</p> +<p>Mais au delà du défi technique et technologique, j'ai pu refaire un petit peu +d'électronique, et découvrir que j'y prends vraiment gout rapidement. Il y a +bien évidemment un coté très ludique (la led s'allume quand on la branche), +mais il y a surtout cette notion de DIY (Do It Yourself) sous jacente: une fois +que je sais comment ça fonctionne, je peux vraiment faire des choses utiles de +mes 10 doigts, réparer des petits objets, bidouiller ceux existants etc.</p> +<p>De la récupération de composants on essaye de voir ce qu'on peut faire, on a +terminé par faire un &quot;vibro-bot&quot;, un vibreur de téléphone portable monté sur +une tête de brosse à dents, faisant donc avancer cette dernière.</p> +<p>C'est pour s'amuser, c'est pas sérieux ! Pour autant, les concepts de +l'électricité sont appris et je me retrouve avec cette envie de comprendre un +peu plus ce monde de l'électronique qui, je m'en rends compte, m'échappe encore +complètement. De l'éducation à la bidouille !</p> +<p>Allez, demain c'est fer à souder, piles, leds, interrupteurs, potars et c'est +parti !</p> +Djangocong 20122012-04-16T00:00:00+02:002012-04-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-16:/djangocong-2012-fr.html<p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une …</p><p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une qualité d'é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 :)</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'ai eu l'occasion de discuter de projets tournant autour de +l'entraide, que ça soit pour mettre en lien des associations d'économie sociale +et solidaire (ESS) ou simplement pour que les populations <em>non tech</em> <a class="reference external" href="http://blog.notmyidea.org/quels-usages-pour-linformatique-fr.html">puissent +utiliser toute la puissance de l'outil qu'est le web</a>.</p> +<p>Au niveau du format des conférences, je ne savais pas trop à quoi m'attendre, +au vu des échos de l'an dernier, mais c'était adapté: des mini-confs de 12mn le +samedi matin + début d'aprem, en mode no-wifi pour récupérer une qualité +d'écoute. Et contrairement à mes attentes, ce n'est pas trop court. Pas mal de +retours d'expérience pour le coup, et une matinée pas vraiment techniques, mais +ça pose le décor et permet de savoir qui fait quoi.</p> +<p>Parmi l'ensemble des conférences du matin, je retiens principalement +celle de Mathieu Leplatre, &quot;des cartes d'un autre monde&quot;, qui m'a réellement +bluffée quand à la facilité de créer des cartes avec <a class="reference external" href="http://mapbox.com/tilemill/">TileMill</a>, et qui me pousse à reconsidérer le fait que &quot;la +carto, c'est compliqué&quot;. <a class="reference external" href="https://www.youtube.com/watch?v=7NPQo54NbJ8">La vidéo est (déja !) disponible en ligne</a>, je vous invite à la regarder +(c'est une 15aine de minutes) pour vous faire un avis ;)</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 &quot;notre&quot; projet <a class="reference external" href="http://blog.notmyidea.org/carto-forms-fr.html">&quot;carto +forms&quot;</a>, qui à finalement pu se +redéfinir un peu plus et donner naissance à un <a class="reference external" href="https://github.com/spiral-project/daybed/blob/master/README.rst">README</a>. On en +à profité pour lui choisir un nouveau nom: &quot;daybed&quot;, en référence à couchdb.</p> +<p>Ça devrait se transformer en code d'ici peu. La curiosité aidant, on a pu +discuter du projet avec d'autres personnes et affiner les attentes de chacun +pour finalement arriver à quelque chose d'assez sympathique.</p> +<p>J'ai aussi pu me rendre compte que pas mal de monde utilise <a class="reference external" href="http://pelican.notmyidea.org">pelican</a>, le bout de code que j'ai codé pour générer ce +blog, et avoir des retours utiles ! Probablement des réflexions à venir +sur comment éviter qu'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 contributeurs.</p> +<p>Bien évidemment, c'était aussi l'occaz de rencontrer des gens qu'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 chouette.</p> +<p>Entres autres faits notoires, JMad a perdu au baby-foot face à Exirel, même +en m'ayant à ses cotés pour le déconcentrer (et je suis un joueur d'un autre +monde - en d'autres termes, je suis nul), David`bgk ne s'est pas levé pour +aller courir le dimanche matin (il avait dit 5 heures!), Les suisses ont essayé +de me convertir à coup d'abricotine, j'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'ils mentent avec leur soit disant +soleil).</p> +<p>Et c'est sans parler de <a class="reference external" href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la brasucade</a> …</p> +<p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une présentation +!)</p> +Bière maison !2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/biere-maison-fr.html<p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si …</p><p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si pire comme on dit !</p> +<p>Cette fois-çi, on s'est penché sur la confection d'une IPA (Indian Pale Ale, une +bière un peu plus amère que celle qu'on à l'habitude de trouver en France).</p> +<p>Elle est plus amère car elle comporte plus de houblon que les autres, et +(dans notre cas en tout cas) parce qu'on fait la première fermentation en +présence de houblon.</p> +<div class="section" id="comment-qu-on-fait-de-la-biere"> +<h2>Comment qu'on fait de la bière ?</h2> +<p>Machine arrière; n'allons pas trop vite: comment est-ce qu'on fait de la bière, +d'abord ?</p> +<p>En fin de compte, les quelques étapes nécessaire à la confection de la bière ne +sont pas bien sorcières; concassage de l'orge maltée, cuisson (libération de +l'amidon dans l'eau), infusion du houblon, refroidissement, première +fermentation, embouteillage et seconde fermentation.</p> +<p>L'idée principale est transformer l'amidon d'orge maltée en sucre, pour le +&quot;donner à manger&quot; à des levures. Vous ajoutez un peu de houblon au milieu pour +donner un petit goût amer et le tour est joué. Enfin presque.</p> +</div> +<div class="section" id="etape-par-etape"> +<h2>Étape par étape</h2> +<p>Première étape: <strong>le concassage</strong>. On avait 6kg d'orge maltée à concasser (plus +exactement 6kg de malt pâle <em>7EDC</em> et 500g de malt cara <em>50EDC</em>).</p> +<img alt="Image de concassage." src="images/concassage.jpg" style="width: 400px;" /> +<p>Attention, pas trop fin dis donc ! On ne veut pas de la poudre, on veut +simplement permettre à l'amidon de se dissoudre dans l'eau. Si on concasse le +malt trop fin, on se retrouve avec un dépôt dégeulasse au fond de toutes les +bouteilles (c'est l'expérience qui parle, notre première bière avait plus goût +de céréale que de bière…)</p> +<p>Contrairement aux fois précédentes où nous avions utilisé la technique du +marteau et du torchon (oui, comme vous pouvez l'imaginer, c'est assez long et +fastidieux), On a utilisé… un moulin à malt ! Qui nous à permis de concasser les +6kg en 30 minutes (heureusement qu'on était trois pour se relayer sur le +moulin, parce que nos petits muscles fatiguaient assez vite; vous pouvez +envisager de faire ça tout seul si vous êtes un tennisman).</p> +<img alt="C'est dur !" src="images/concasse.jpg" style="width: 700px;" /> +<p>La seconde étape, <strong>l'empatage</strong>. Il s'agit de faire chauffer notre orge maltée +à différentes températures. Les fois précédentes, on avait utilisé plusieurs +paliers de température, mais il semble que ça ne soit pas si nécessaire que ça, +selon les informations de l'ami Fred. On à donc tenté de faire chauffer notre +malt directement à 50°C. Une petite erreur sur la route, on à eu peur de la +contamination bactérienne et on à décidé de faire bouillir nos 26L d'eau pour +être sur que les bactéries s'enfuient en courant. Je dis erreur parce que ça +nous à pris pas loin de 3h30, inertie quand tu nous tiens!</p> +<p>On se rends compte de la taille de la marmite un peu là:</p> +<img alt="Une grosse marmite" src="images/marmite.jpg" style="width: 400px;" /> +<p>Une fois l'eau à température (54°C), il faut ajouter le malt et le laisser +durant 30mn à cette température, puis augmenter jusqu'à 65°C durant 1h.</p> +<p>La troisième étape, c'est <strong>le rinçage</strong>, l'idée est de récupérer l'amidon qui +s'est dissout dans l'eau et de mettre de côté l'orge maltée (la partie solide). +Pour ça, il faut faire chauffer de l'eau de rinçage. On a utilisé 10L d'eau de +rinçage qu'on a fait chauffer à 78°C, en comptant sur le fait qu'elle perdra de sa +température (20°C à peu près) en étant utilisée. On a filtré deux fois pour +être sûr de ne rien perdre.</p> +<img alt="Filtrage filtrage..." src="images/filtrage.jpg" style="width: 700px;" /> +<p>L'étape d'après (la quatrième, vous suivez), c'est <strong>le houblonnage</strong>. +On va faire infuser notre &quot;solution aqueuse&quot; (wouah, on dirait de la chimie !) +avec du houblon. Il faut porter l'eau à ébullition et laisser faire durant 1h.</p> +<p>Dernière étape: <strong>le refroidissement</strong>. On dirait que c'est tranquilou comme +ça, mais en fait ça ne l'est pas tant que ça: il faut réussir à passer notre +liquide qui était en ébullition à 54°C en un temps acceptable. Pour ça, on +a utilisé un serpentin confectionné main.</p> +<img alt="Notre refroidisseur fait main par Fred." src="images/refroidisseur.jpg" style="width: 400px;" /> +<p>Ça nous a permis de passer de 100°C à 54°C en… 35 minutes quand même ! (Nous avions essayé les fois précédentes +de gérer ça à coup de baignoire et de glaçons, les temps n'étaient absolument +pas au rendez-vous).</p> +<img alt="Décidement pas." src="images/refroidissement.jpg" style="width: 700px;" /> +<p>Je disais dernière étape, mais il ne faut pas oublier de rajouter les +levures, qui elles vont faire tout le travail et transformer tout ça en… alcool +! Dans notre cas, on ajoute aussi dans la cuve de fermentation du houblon +question de donner l'amertume dont on a envie.</p> +<p>On à mesuré une densité de 1046, ce qui veut dire 6° d'alcool. La cuve est +maintenant en train de buller tranquillement (les levures produisent du gaz qui +est évacué), et ça doit durer 15 jours approximativement.</p> +</div> +<div class="section" id="mise-en-bouteille"> +<h2>Mise en bouteille</h2> +<p>Une fois ces deux semaines passées, il faut mettre en bouteille. Dans notre cas +nous avons récupéré des bouteilles à bouchon mécanique (vous savez, les +bouteilles de limonades) qu'on à bien rincé et nettoyé.</p> +<p>On s'équipe d'un siphon (pensez à prendre un tuyau avec un diamètre assez +important, le notre était petit et c'était assez long) et après avoir ajouté du +sucre dans le mélange (pour réactiver les levures), on remplit les bouteilles +! Il s'agit de la seconde fermentation, celle qui va faire les bulles (la +première fermentation se charge de l'alcool, la seconde des bulles).</p> +<p>Et voilà ! Il ne reste plus qu'à mettre les bouteilles de coté durant deux +semaines de plus et… à déguster le moment venu.</p> +<p>On a donc pu tester notre bière la semaine dernière et, ma foi, elle est pas +mal du tout. Elle ne mousse pas trop et à un goût un peu amer. Malheureusement +pas assez à mon goût, mais ça viendra. En comparaison à nos précédents essais, +c'est plutôt positif: la première était ratée puisque trop de pression et trop +de dépôt (et donc un fort goût de levures) alors que la seconde (on avait tenté +d'ajouter de la lavande) avait un goût de lavande amère, pour ne pas dire de +savon.</p> +<p>Cette dernière bière a un goût de… de bière ! Il nous reste encore à 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 !</p> +</div> +Motivation, bénévolat et participation2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/motivation-benevolat-et-participation-fr.html<p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux …</p><p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux luttes +contre l'oligarchie et les profits d'une minorité aux dépends du reste du monde, +et à encore bien d'autres choses.</p> +<p>Pendant un bout de temps, j'ai parlé d'entraide, de collaboration, j'ai essayé +de sensibiliser autour de la question environnementale et aux alternatives +sociales. C'est d'ailleurs de cette manière que je me suis moi-même le plus +sensibilisé à ces questions qui me préoccupaient.</p> +<p>J'ai tenté de le faire sans tomber dans la critique des choix des uns et des +autres. Je respecte profondément la diversité des points de vues <strong>mais</strong> je +souhaite également que ces choix soient faits en connaissance de cause.</p> +<p>Une des choses difficile à supporter (pour les autres) quand on fait de la +sensibilisation, c'est le syndrôme du jeune con, du donneur de leçons.</p> +<p>On dirait qu'on parle de sauver le monde. &quot;Nous qui avons tout compris, on peut +vous aider à aller dans la <em>bonne direction</em>&quot;, mais c'est en oubliant que +la bonne direction pour l'un ne l'est pas nécessairement pour les autres…</p> +<div class="section" id="just-do-it"> +<h2>Just do it !</h2> +<p>Se battre <em>contre quelque chose</em> permet de facilement trouver des personnes qui +partagent les même craintes alors que se battre <em>pour</em> permet d'engager des +discussions avec des personnes qui partagent une vision commune.</p> +<p>Proposer des choses, trouver des personnes qui partagent des points de vue est +un bon point de départ pour le changer ce monde, a notre échelle. Le récent +documentaire <a class="reference external" href="http://justdoitfilm.com/">&quot;Just do it&quot;</a> porte un message assez +clair: toute initiative compte, aussi petite et insignifiante qu'elle puisse +sembler.</p> +<p>Des initiatives locales, il y en a, plein. Et si ce que nous avons dans notre +quotidien nous pèse (aller au supermarché, subir la sur-médiatisation +télévisuelle, ne pas parler à nos voisins de quartier…), qu'est-ce qui nous +empêche d'y substituer des modèles alternatifs ?</p> +<p>Monter une <a class="reference external" href="https://fr.wikipedia.org/wiki/AMAP">AMAP</a> (Association Pour le Maintien d'une Agriculture Paysanne) +n'est pas aussi compliqué qu'il y parait. Pour avoir fait l'expérience par deux +fois, j'ai été très agréablement surpris par la facilité des choses, pour peu +qu'on ne cherche pas à s'encombrer de l'inutile (tiens encore une fois on +parle de frugalité !): il est facile de vouloir faire trop, de recréer les +processus complexes auxquels nous sommes souvent confrontés.</p> +<p>Vous souhaitez partager des connaissances (cuisine, musique, danse, bricolage, +écriture), il suffit de le faire. En fait, pour la plupart des choses, il +suffit de tenter l'expérience, c'est rarement décevant. Surtout quand on +s'embarque dans des choses saugrenues ou personnellement inédites.</p> +<p>Pour moi, la frugalité, la simplicité volontaire, la sobriété heureuse, appelez-ça +comme vous le voulez, représente ce qui me convient et me permet d'être en +ligne avec les idées que je défends.</p> +</div> +<div class="section" id="faciliter-la-participation"> +<h2>Faciliter la participation</h2> +<p>Beaucoup de personnes sont à même de participer à des projets locaux, pour peu +qu'ils soient au courant mais pour autant peu franchissent le pas, et encore +moins persévèrent, pourquoi ?</p> +<p>Et pourquoi pas laisser les présents, les motivés, s'investir par eux-mêmes ? +Avoir des responsabilités est souvent pour ma part un frein à la réalisation +d'un projet lorsque je suis bénévole.</p> +<p>Décider à l'avance des choses qui semblent utiles et/ou importantes est parfois +indispensable, mais ne pas trop en faire permet de laisser libre court +à l'imagination (souvent débordante) des participants.</p> +<p>J'aime beaucoup l'idée de faire des camps de quelques jours, où rien n'est +réellement décidé à l'avance, mise à part un thème et quelques temps de +plénière ou il est possible à chacun de s'exprimer sur les projets qui +pourraient êtres réalisés.</p> +<p>Pas besoin de tant de formalisation: mettez une équipe de bidouilleurs ensemble +durant une semaine sans objectif commun à priori et sans distractions, vous +verrez bien ce qui en ressortira !</p> +</div> +Génération de formulaires, geolocalisés ?2012-02-04T00:00:00+01:002012-02-04T00:00:00+01:00Alexis Métaireau, Mathieu Leplatretag:blog.notmyidea.org,2012-02-04:/carto-forms-fr.html<p>On a un plan. Un &quot;truc de ouf&quot;.</p> +<p>À plusieurs reprises, des amis m'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 l'information.</p> +<p>L'idée fait …</p><p>On a un plan. Un &quot;truc de ouf&quot;.</p> +<p>À plusieurs reprises, des amis m'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 l'information.</p> +<p>L'idée fait son bout de chemin, et je commence à penser qu'on peut même avoir +quelque chose de vraiment flexible et utile. J'ai nommé le projet <em>carto-forms</em> +pour l'instant (mais c'est uniquement un nom de 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 plus?</p> +<p>Si vous ne connaissez pas Google forms, il s'agit d'une interface simple +d'utilisation pour générer des formulaires et récupérer des informations depuis +ces derniers.</p> +<p>Google forms est un super outil mais à mon avis manque deux choses importantes: +premièrement, il s'agit d'un outil propriétaire (oui, on peut aussi dire +privateur) et il n'est donc pas possible de le hacker un peu pour le faire +devenir ce qu'on souhaite, ni l'installer sur notre propre serveur. +Deuxièmement, il ne sait pas vraiment fonctionner avec des informations +géographiques, et il n'y à pas d'autre moyen de filtrer les informations que +l'utilisation de leur système de feuilles de calcul.</p> +<p>Après avoir réfléchi un petit peu à ça, j'ai contacté <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu</a> et les anciens +collègues de chez <a class="reference external" href="http://makina-corpus.com">Makina Corpus</a>, puisque les projets libres à base de carto +sont à même de les intéresser.</p> +<p>Imaginez le cas suivant:</p> +<ol class="arabic simple"> +<li>Dans une &quot;mapping party&quot;, on choisit un sujet particulier à cartographier et +on design un formulaire (liste des champs (tags) a remplir + description + +le type d'information) ;</li> +<li>Sur place, les utilisateurs remplissent les champs du formulaire avec ce +qu'ils voient. Les champs géolocalisés peuvent être remplis automatiquement +avec la géolocalisation du téléphone ;</li> +<li>À la fin de la journée, il est possible de voir une carte des contributions, +avec le formulaire choisi ;</li> +<li>Un script peut importer les résultats et les publier vers OpenStreetMap.</li> +</ol> +<div class="section" id="quelques-cas-d-utilisation"> +<h2>Quelques cas d'utilisation</h2> +<p>J'arrive à imaginer différents cas d'utilisation pour cet outil. Le premier est +celui que j'ai approximativement décrit plus haut: la génération de cartes de +manière collaborative, avec des filtres à facettes. Voici un flux d'utilisation +général:</p> +<ul> +<li><p class="first">Un &quot;administrateur&quot; se rend sur le site web et crée un nouveau formulaire +pour l'ensemble des évènements alternatifs. Il crée les champs suivants:</p> +<ul class="simple"> +<li>Nom: le champ qui contient le nom de l'évènement.</li> +<li>Catégorie: la catégorie de l'évènement (marche, concert, manifestation…). +Il peut s'agir d'un champ à multiples occurrences.</li> +<li>Le lieu de l'évènement. Celui-ci peut être donné soit par une adresse soit +en sélectionnant un point sur une carte.</li> +<li>Date: la date de l'évènement (un &quot;date picker&quot; peut permettre cela +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, +etc.)</p> +</li> +<li><p class="first">Une fois terminé, le formulaire est généré et une URL permet d'y accéder. +(par exemple <a class="reference external" href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>).</p> +</li> +<li><p class="first">Une API REST permet à d'autres applications d'accéder aux informations et d'en +ajouter / modifier de nouvelles.</p> +</li> +<li><p class="first">Il est maintenant possible de donner l'URL à qui voudra en faire bon usage. +N'importe qui peut ajouter des informations. On peut également imaginer une +manière de modérer les modifications si besoin est.</p> +</li> +<li><p class="first">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 +API REST, soit via une jolie carte et quelques contrôles bien placés, dans le +navigateur.</p> +</li> +</ul> +<p>Vous avez dû remarquer que le processus de création d'un formulaire est +volontairement très simple. L'idée est que n'importe qui puisse créer des +cartes facilement, en quelques clics. Si une API bien pensée suit, on peut +imaginer faire de la validation coté serveur et même faire des applications +pour téléphone assez 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 +génériques.</p> +<p>On imagine pas mal d'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'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'affichage publicitaires, participation citoyenne +(graffitis, nids de poule, voir <a class="reference external" href="http://fixmystreet.ca">http://fixmystreet.ca</a>), geocaching, +trajectoires (randonnées, coureurs, cyclistes)…</p> +<p>Voici quelques exemples où ce projet pourrait être utile (la liste n'est pas +exhaustive):</p> +<div class="section" id="un-backend-sig-simple-a-utiliser"> +<h3>Un backend SIG simple à 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 SIG! +Vous avez besoin de <em>Carto-Forms</em>! Une API simple vous aide à penser vos +modèles et vos formulaires, et cette même API vous permet d'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 gérées.</p> +<p>En d'autres termes, vous faites une distinction entre le stockage des +informations et leur affichage.</p> +<p>Si vous êtes un développeur django, plomino, drupal etc. vous pouvez développer +un module pour &quot;plugger&quot; vos modèles et votre interface utilisateur avec celle +de <em>Carto-Forms</em>. De cette manière, il est possible d'exposer les formulaires +aux utilisateurs de vos backoffices. De la même manière, il est possible +d'écrire des widgets qui consomment des données et les affichent (en utilisant +par exemple une bibliothèque javascript de webmapping).</p> +</div> +<div class="section" id="un-outil-de-visualisation"> +<h3>Un outil de visualisation</h3> +<p>Puisque les données peuvent être proposées de manière automatisée en utilisant +l'API, vous pouvez utiliser la page de résultat de Carto-forms comme un outil +de visualisation.</p> +<p>Il est possible d'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'impressoin d'être en face +d'un système d'aide à la décision !</p> +<p>Évidemment, il est possible de télécharger les données brutes (geojson, xml). +Idéalement, le mieux serait d'obtenir ces données filtrées directement depuis +une API Web, et un lien permet de partager la page avec l'état des filtres et +le niveau de zoom / la localisation de la carte.</p> +</div> +<div class="section" id="un-service-generique-pour-gerer-les-formulaires"> +<h3>Un service générique pour gérer les formulaires</h3> +<p>Si vous souhaitez générer un fichier de configuration (ou ce que vous voulez, +messages emails, …) vous aurez besoin d'un formulaire et d'un template pour +injecter les données proposées par les utilisateurs et récupérer un 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 &quot;nettoyées&quot; et +&quot;validées&quot;.</p> +<p>On peut imaginer par exemple l'utilisation d'un système de templates externe +reposant sur <em>carto-forms</em>. Celui-ci &quot;parserait&quot; le contenu des templates et +pourrait le lier aux informations ajoutées par les utilisateurs via un formulaire.</p> +<p>Pour ce cas particulier, il n'y a pas besoin d'informations géographiques +(SIG). Il s'agit quasiment du service proposé actuellement par Google forms.</p> +</div> +</div> +<div class="section" id="ca-n-existe-pas-deja-tout-ca"> +<h2>Ça n'existe pas déjà tout ça ?</h2> +<p>Bien sur, il y a Google forms, qui vous permet de faire ce genre de choses, +mais comme je l'ai précisé plus haut, il ne s'agit pas exactement de la même +chose.</p> +<p>Nous avons découvert <a class="reference external" href="https://webform.com">https://webform.com</a> qui permet de créer des formulaires +avec un système de drag'n'drop. J'adorerais reproduire quelque chose de +similaire pour l'interface utilisateur. Par contre ce projet ne gère pas les +appels via API et les informations de géolocalisation …</p> +<p>L'idée de <a class="reference external" 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 +SIG (point, ligne, polygone).</p> +<p><a class="reference external" 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 formulaires…</p> +</div> +<div class="section" id="on-est-parti"> +<h2>On est parti ?!</h2> +<p>Comme vous avez pu vous en rendre compte, il ne s'agit pas d'un problème +outrageusement complexe. On a pas mal discuté avec Mathieu, à propos de ce +qu'on souhaite faire et du comment. Il se trouve qu'on peut sûrement s'en +sortir avec une solution élégante sans trop de problèmes. Mathieu est habitué à +travailler autour des projets de SIG (ce qui est parfait parce que ce n'est pas +mon cas) et connaît son sujet. Une bonne opportunité d'apprendre!</p> +<p>On sera tous les deux à <a class="reference external" 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'hésitez pas!</p> +<p>On ne sait pas encore si on utilisera django ou quelque chose d'autre. On a +pensé un peu à CouchDB, son système de couchapps et geocouch, mais rien n'est +encore gravé dans le marbre ! N'hésitez pas à proposer vos solutions ou +suggestions.</p> +<p>Voici le document etherpad sur lequel on a travaillé jusqu'à maintenant: +<a class="reference external" href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. N'hésitez pas à l'éditer et à ajouter vos +commentaires, c'est son objectif!</p> +<p>Merci à <a class="reference external" href="http://sneakernet.fr/">Arnaud</a> pour la relecture et la correction de quelques typos dans le +texte :)</p> +</div> +Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique-fr.html<p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable …</p><p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable à lire que sa version papier, il reste quand même quelques problèmes, la plupart liés au format de distribution de l’œuvre.</p> +<p>J'avoue ne pas trop savoir quoi penser de tout ça. D'un coté le livre électronique permet de franchir les frontières plus facilement, et semble avoir un tas d'avantage (notamment le fait que se trimbaler avec l'ensemble de sa collection de bouquins est désormais possible).</p> +<p>A mon avis, ce qui pose vraiment problème, ce sont les formats sous lesquels ces livres sont mis à disposition, non pas les livres eux même. Encore une question de DRMs donc…</p> +<p>Encore une problématique liée au copyright et au fait que le copie privée pose des problèmes à l'industrie en place. Ça renvoie à des questions plus profondes, et principalement à la mise en perspective du producteur de contenu et du consomateur de ce même contenu. Exactement ce qu'on essaye de résoudre dans le milieu agricole par le biais des AMAPs.</p> +<p>Sauf qu'ici, on est face au simple problème de la dématérialisation. Est-ce qu'une responsabilisation des consommateurs ne pourrait pas résoudre ce problème de publication ?</p> +<p>Recemment, j'ai récupéré une version piratée d'un livre technique, simplement parce que je ne trouvais pas une version de ce livre en numérique qui me permette de faire une copie privée de celui ci. Un Epub, par exemple. J'ai fait en me disant que c'était un acte militant. Sauf que non, ce n'est pas une solution soutenable, et j'en viens maintenant presque à le regretter. On en discutait rapidement avec <a class="reference external" href="http://ziade.org">Tarek</a> il y à quelques jours et il pointait du doigt que ceux qui en patissent sont les auteurs des livres, non pas les éditeurs (qu'il ne faut pas non plus diaboliser selon moi, ils cherchent à trouver des manières de garder leur coeur de métier).</p> +<p>Or, avoir des auteurs, des personnes qui sont prêtes à partager leur savoir à de larges audiences me semble primordial pour que la répartition du savoir continue à se répendre. Certes, le blogging permet cela dans une faible mesure, mais de manière bien moins construite, et surtout, est fait de manière bénévole (à moins que certains bloggeurs aient trouvé des moyens de rémunération dont j'ignore l'existance ?), donc il est plus difficile pour les auteurs de se dégager du temps pour travailler sur de gros ouvrages (ceci est bien évidemment une généralisation).</p> +<p>Quelles sont nos solutions, donc ? Peut être se tourner vers des solution de publication alternatives, couplées à une résponsabilisation des lecteurs. Je ne pense pas necessairement aux plateformes alternatives comme <a class="reference external" href="http://framabook.org">framabook</a>, parce que je me demande toujours si cela est une solution viable pour les auteurs, du moins dans les premières années, mais au moins des éditeurs qui ne font pas le choix du grand verrou numérique.</p> +<p>On demande pas grand chose, pourtant… Peut être même que de telles initiatives existent déjà ?</p> +<p>Et vous, vous les achetez ou vos livres ?</p> +La simplicité volontaire contre le mythe de l'abondance2011-10-14T00:00:00+02:002011-10-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-14:/la-simplicite-volontaire-contre-le-mythe-de-labondance-fr.html<p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car …</blockquote><p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car il finira par nous poignarder, au moment ou nous pensions +justement pouvoir le vaincre… Entendons-nous bien, il ne s'agit pas +d'apprendre à &quot;positiver&quot; sous prétexte que l'on pourrait &quot;moraliser&quot; ou +repeindre en vert le capitalisme, il s'agit, bien au contraire, d'être aussi +intraitables lorsque nous créons cet autre monde, que lorsque nous étions +ces militants purs mais un peu durs à jouir, il s'agit d'être aussi +indomptables mais sans oublier que le capitalisme ne pourra être arrété que +par du non-capitaliste… c'est-à-dire en multipliant les expérimentations +sociales, en acceptant de faire au maximum sécession, en inventant +(réinventant?) une gauche buissonière et maquisarde, en faisant, au +quotidien, la part belle à la dérive, à des modes de comportement +expérimentaux. 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.</blockquote> +Un coup de main pour mon mémoire!2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire-fr.html<p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de main.</p> +<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui connaissent +last.fm, je …</p><p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de 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'avis des personnes qui +ont des profils similaires au votre.</p> +<p>Le projet est loin d'ê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 &quot;tournée +générale&quot;).</p> +<p>J'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'enverra des +information sur les sites que vous visitez (si vous avez l'habitude d'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'un simple clic si vous souhaitez garder votre vie privée privée ;-)</p> +<p>Le site est par là: <a class="reference external" 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'est 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 correctement.</p> +<p>Merci pour votre aide !</p> +Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler-fr.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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un …</p><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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un brin!).</p> +<p>Bosser en extérieur est un réel plaisir et faire quelque chose de manuel +également. Je n'ai pas pour habitude de bricoler autre chose que du logiciel et +c'est vraiment quelque chose que j'apprécie.</p> +<p>J'avoue, je mens un peu quand je dis que j'étais complètement déconnecté: +j'ai vérifié mes mails assez régulièrement en utilisant mon téléphone +(merci Arnaud pour le prêt du gadget!) et j'ai limité ma présence web au strict +minimum. Je veux dire par là pas de twitter, pas d'IRC et autres mailing-lists.</p> +<p>Quand je dis hors-ligne, je ne dis pas que je n'ai pas travaillé sur mon +ordinateur. J'ai à fournir beaucoup plus de travail que ce que je ne pensait en +premier lieu pour la rédaction de mon mémoire et j'ai passé quelques heures par +ci par là à lire des articles et livres sur le sujet ainsi que rédigé une bonne +partie de mon mémoire durant ces 10 jours. Résultat ? Les heures que j'ai passées à travailler ont +été étonnement plus productives que celles que j'ai l'habitude de passer derrière +un écran. Je ne parles pas uniquement du fait de procrastiner; évidemment c'est +une des causes principales de ma perte de productivité, mais je pense également +au fait de laisser le cerveau reposer, au moins en ce qui concerne la partie +informatique. Bricoler demande de la concentration et de la réflexion mais +permet également de laisser son esprit vagabonder. J'ai pu donc avancer mes +sur certaines parties de mon mémoire alors que j'étais en train de poser le +bardage sur la garage par exemple.</p> +<p>Passer du temps sur autre chose (qui demandait également de la concentration +par ailleurs) m'a permis d'être réellement plus efficace lors de mes phases de +rédaction et de lecture.</p> +<p>Je me demande depuis quelques temps quel sera mon futur travail et quelle forme +il prendra. Éééh oui, la fin des études arrive pour la fin de l'année, c'est +pas une blague. Et je me pose sérieusement la question du travail aux 3/4 +temps. La raison principale étant que je ne souhaites pas passer la majeure +partie de mon temps à travailler derrière un écran et que la formation que j'ai +m'y rattache beaucoup. Ne me comprenez pas de travers: j'aime ce que je fais; +mais j'aime aussi ce que je fais à coté de l'informatique: associatif, projets +alternatifs, permaculture et autres.</p> +<p>Viens s'ajouter à ça le fait d'avoir une qualité de vie qui me semble pouvoir +passer par le fait de travailler moins (&quot;il est marant ce gamin, il à pas encore commencé +à travailler qu'il veut bosser moins, regarde moi cette feignasse!&quot;) et +travailler plus efficacement. Bien sur, on n'est jamais 100% productif et c'est +d'autant plus vrai pour moi, alors si gagner en productivité peut passer par +travailler moins, pourquoi pas s'y essayer !</p> +<p>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 ?</p> +Quels usages pour l'informatique ?2011-01-12T00:00:00+01:002011-01-12T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-01-12:/usages-informatique-fr.html<p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas …</p><p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas vous pourrir la vie. Oui, parce que de +l'informatique on en a partout, des &quot;geeks&quot; et des &quot;accros&quot; aussi, et que ça +vient s'immiscer dans nos vies même quand d'autres moyens ou médias sont plus +utiles ou pertinents.</p> +<p>Certes, l'informatique nous permet de communiquer et travailler plus efficacement, +Mais à quel prix ? Ce n'est pas parce qu'il est possible d'<a class="reference external" href="http://retourdactu.fr/2011/11/07/la-non-communication-nouveau-modele-de-societe/">industrialiser +l'éducation</a> +(ou l'agriculture !), que l'on doit le faire. Oui, ça me dérange d'être une des +nombreuses personnes à l'œuvre derrière cette soit disant &quot;révolution&quot;, qui +n'est pas toujours pour le meilleur. Attention, je ne remets pas l'informatique +et son intérêt en cause: je me pose des questions quand à la place que je veux +lui donner et la place que je souhaites occuper dans son évolution. Ce n'est +pas parce qu'on peut tuer avec un marteau (avec un peu de volonté) qu'il s'agit +d'un mauvais outil, mais si tout le monde se met à tuer avec des marteaux (y a +des malades partout, hein), alors se poser la question de son rôle, en tant que +fabricant de marteaux me semble nécessaire (oui, je vous l'accorde, on aura vu +des comparaisons plus perspicaces).</p> +<p>Donc: à partir de quel moment l'informatique cesse d'être un outil utile pour +transformer nos modes de vies d'une manière qui me dérange ? Peut être avec son +arrivée sur des périphériques mobiles ? Peut être quand elle se fait +l'instrument du consumérisme et de l'individualisme.</p> +<div class="section" id="et-alors-on-fait-quoi"> +<h2>Et alors, on fait quoi ?</h2> +<p>Mais si je continue à faire de l'informatique, il y a bien des raison. J'ai +d'ailleurs trouvé mon intérêt de par le coté collaboratif qui est permis et +développé par l'outil informatique, et notamment par le réseau des réseaux +(internet). Faisons ensemble, mes amis. Prouvons que la collaboration a de +meilleurs jours à vivre que la compétition. Le web, notamment, est une avancée +majeure en ce qui concerne la liberté d'expression et le partage de +connaissances (oui, kipédia). Je vous conseille d'ailleurs à ce propos +<a class="reference external" href="http://owni.fr/2011/11/30/vers-une-economie-de-la-contribution/">l'excellent discours tenu par Bernard Stiegler</a> paru +récemment sur <a class="reference external" href="http://www.owni.fr">owni</a>.</p> +<p>Et c'est cet avenir qu'il me plait de défendre: l'ouverture d'esprit, la +possibilité que chacun puisse contribuer et participer à une base de savoir +commune, en apprenant des autres. Mais par pitié, n'imposons pas la +technologie là où elle n'est pas nécessaire, et utilisons la avec tact quand +elle peut nous être profitable.</p> +<p>Il me plait de repenser l'informatique comme outil et non plus comme mode de +vie. Faisons le l'outil de la collaboration. À l'école, apprenons à nos enfants +à collaborer, à susciter le partage, pas uniquement avec l'outil informatique, +mais aussi avec celui ci, tout en leurs apprenant à avoir un regard critique +sur les informations qu'ils reçoivent.</p> +<p>En bref, questionner le rôle que l'on souhaite avoir dans notre société par le +biais de l'informatique est nécessaire. Comme d'autres, je suis arrivé +à l'informatique par le biais du premier ordinateur familial, il y a de ça une +bonne quinzaine d'années. Ça intrigue, on touche un peu à tout (on en fait des +conneries !) et on finit par apprendre/comprendre comment ça marche, petit +à petit. Cette curiosité n'est d'ailleurs pas le propre de l'informatique +puisqu'on la retrouve dans la cuisine, dans le bricolage et dans un tas de +domaines de notre vie quotidienne.</p> +<p>Finalement, c'est aimer bidouiller, et comprendre comment ça fonctionne, quitte +à sortir les compétences de leur domaine de prédilection (qui a dit que +l'informatique ne pouvait être artistique ?) Le mouvement hacker (bidouilleurs) +aime à sortir l'informatique de son carcan et l'appliquer ailleurs.</p> +<p>C'est de cette manière que j'ai envie de considérer mon métier, qui avant tout +est une passion. Je suis un bidouilleur, j'aime découvrir comment les choses +fonctionnent et avoir une panoplie d'outils qui me permettent de répondre à des +besoins réels.</p> +</div> +<div class="section" id="favoriser-la-collaboration"> +<h2>Favoriser la collaboration</h2> +<p>Et donc, en tant qu'individu, pourquoi faire de l'informatique ? Qu'est-ce qui +m'attire dans cet outil ?</p> +<p>Ce qu'on pourrait qualifier de &quot;recherche fondamentale&quot;, l'écriture de +bibliothèques logicielles, est important mais n'est pas tout. Ce qui importe ce +sont les usages qui en découlent. Je souhaite <strong>savoir écrire des outils qui +sont utiles</strong>, <strong>qui favorisent la collaboration et participent à l'ouverture +des esprits</strong>.</p> +<p>Je choisis de faire de l'informatique pour créer les outils qui répondent à des +problématiques réelles, pour trouver de meilleures manières de communiquer et +de travailler ensemble. Mais, comme me le disait David, d'<a class="reference external" href="http://outils-reseaux.org/PresentationProjet">Outils-Réseaux</a>, on ne crée pas de la +coopération: rien ne sert d'essayer de faire coopérer des gens qui ne veulent +pas. On peut, cependant, la faciliter, en utilisant les bons outils et en +formant les gens à leur utilisation, ainsi qu'aux pratiques collaboratives +(qui, je le répète, ne s'arrêtent pas du tout aux frontières informatique).</p> +<p>Le logiciel libre, avant d'être une force pour le marché logiciel, est une +application du partage. Une démonstration qu'il est possible de travailler +ensemble pour fabriquer quelque chose de fonctionnel et d'utile pour tous. Une +sorte d'antithèse de ce modèle capitaliste incarné par les brevets logiciel.</p> +<p>A plusieurs reprises, j'ai été bluffé par la réalité du logiciel libre. Oui, il +est facile de collaborer lorsqu'on crée un logiciel, pour peu qu'on explique +les tenants et les aboutissants aux participants. Les contributeurs sortent +d'on ne sait où, pour peu que le projet leur soit utile. Je ne parle pas +d'outils &quot;corpo compliant&quot; (bien que ça soit probablement aussi le cas), mais +d'outils que j'ai pu développer pour mon propre usage, et sur lesquels il a été +possible de collaborer avec d'autres.</p> +<p>Parce que l'informatique est utile dans bien des milieux, parce qu'elle peut +être (et elle l'est) un vecteur de participation et de collaboration, défendons +les valeurs qui nous sont chères (logiciels libres et ouverts!) et construisons +des ponts entre les initiatives qui nous parlent (fermes autogérées, +initiatives d'éducation populaire) et l'informatique.</p> +<p>Faisons en sorte de rendre l'informatique accessible et utile dans les milieux +ou elle peut apporter quelque chose !</p> +</div> +Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y-fr.html<p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un …</p><p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un répis +d'une semaine, pour récupérer des folies organisatrices (c'est ça +qui fait du bien, ceci dit -- les folies, pas le repos), je me +retrouve de nouveau sur ces mêms réflexions, grâce aux journées +organisées par +<a class="reference external" href="http://www.fne.asso.fr/">France Nature Environnement</a>, qui +proposaient ce jeudi soir une projection de &quot;Le temps des grâces&quot;, +un documentaire sur l'agriculture.</p> +<p>Parce que depuis 60 ans, il est pratiqué le remembrement des +parcelles à gogo, parce que nos sols deviennent completement morts +à cause des tonnes d'intrants qu'on leur fait absorber, et parce +que les exploitations s'agrandissent sans en finir pour tenter de +réagir façe à un marché financier toujours plus insaisissable, mené +de très loin par la PAC, il fallait un film pour en parler. C'est +ce que fait &quot;le temps des grâçes&quot;, avec un bon sens et une facilité +à faire passer des messages, qu'on ne peut qu'applaudir.</p> +<p>Malheureusement il s'agissait de la dernière diffusion à +<a class="reference external" href="http://www.cinemas-utopia.org/toulouse/">L'Utopia de Toulouse</a>... +Si vous en avez l'occasion, sautez dessus et profitez le temps de +ces 2 heures, ou vous pourrez écouter à la fois des discours +d'agronomes, d'agriculteurs, de chercheurs et bien d'autres, qui +dressent un constat pas si brillant de notre agriculture. On n'est +pas sorti de l'auberge, enfin, c'est l'expression.</p> +<p>Je vous laisse avec le synopsis et une bande annonce.</p> +<blockquote> +Une enquête documentaire sur +le monde agricole français aujourd'hui à travers de nombreux récits +: agriculteurs, chercheurs, agronomes, écrivains... Un monde qui +parvient à résister aux bouleversements qui le frappent - +économiques, scientifiques, sociaux - et qui, bon gré mal gré, +continue d'entretenir les liens entre générations. Un monde au +centre d'interrogations majeures sur l'avenir.</blockquote> +<p>Ainsi qu'un commentaire que je ne peux m'empécher de relayer, +trouvé sur allocine.fr (oui, vous savez, ce site rempli de pubs).</p> +<blockquote> +Le temps des grâces c'est je pense le plus grand film traitant de +l'écologie en tant que documentaire ou en sujet principal, on y +apprend une multitude de choses, on en ressort en colère contre le +système, le film propose différents points de vues, ici on a pas de +voix off moralisatrice à deux balles avec des gros titres bien +surlignés pour que même les beaufs matant TF1 puissent comprendre, +ici même si ça reste accessible au citoyen lambda, le film ne fait +pas de compromis avec le monde agroalimentaire, il ose dénoncer les +filière d'agronomie qui apprennent pas les bonnes choses à leurs +étudiants, aux lobbys de cette agro-industrie qui n'en fait qu'à sa +tête pour amasser de l'argent, cette tendance à tout uniformiser et +détruire… Franchement j'ai trouvé ça génial de bout en bout, +captivant, on explore cette campagne française, on comprend les +dilemmes des paysants. Le film n'étant pas opposé à la modernité, +ni même réactionnaire, il propose juste un constat alarmant du +monde agricole français, tout en proposant des alternatives qui +pourraient être utilisée, si les pouvoirs publics lâchaient un peu +la main des lobbys. Passionnant, vraiment.</blockquote> +<p>Courrez-y, je vous dis.</p> +Semaine de l’environnement: La consommation étudiante2010-02-24T00:00:00+01:002010-02-24T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-02-24:/semaine-de-lenvironnement-la-consommation-etudiante-fr.html<p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres …</p><p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres), et a tout un tas d'autres associations que je ne peux pas citer ici exhaustivement... Ce sont eux qui sont porteurs de messages alternatifs, et qui sont les initiateurs de débats publics, qui permettent de faire avancer des thématiques aussi importantes que le logiciel libre ou la protection de l'environnement.</p> +<p>Dans cette optique, depuis près de 3 ans (déjà !), au sein du +<a class="reference external" href="http://www.reseaugrappe.org">réseau GRAPPE</a>, on <em>essaye</em> +d'aborder des thématiques qui touchent de près ou de loin à +l'environnement, parce que c'est un sujet qui nous importe et nous +passionne. L'année dernière, c'était l'alimentation étudiante, ce +qui à abouti à la publication de +<a class="reference external" href="http://public.reseaugrappe.org/alimentation.pdf">la revue &quot;les étudiants se mettent à table&quot;</a>. +Cette année c'est la consommation étudiante qui est au programme.</p> +<div class="section" id="la-consommation-etudiante"> +<h2>La consommation étudiante ?</h2> +<p>L'idée principale de cette étude est de tenter de faire une analyse +de la &quot;société de consommation&quot;, souvent questionnée par les +étudiants et par d'autres, et de jeter un œil sur le rapport des +étudiants à cette société: Quoi et comment consomment-ils ? Les +universités et les écoles ne poussent-elles pas d’une certaine +manière les étudiants à la consommation ? Quelles sont les +alternatives face aux dérives de surconsommation ?</p> +<blockquote> +Analyse des pratiques, réflexions et mobilisations des étudiants en +termes de consommation seront réalisés pour comprendre leur modes +de vie, mais aussi leurs attentes, leurs propositions sur cette +thématique</blockquote> +</div> +<div class="section" id="la-semaine-de-l-environnement"> +<h2>La semaine de l'environnement !</h2> +<p>A travers l'ensemble des villes du réseau, +des projections de films et des débats auront donc lieu sur ce +thème, lors de la semaine de l'environnement 2010, qui se déroulera +d'ailleurs durant le mois de Mars +<a class="reference external" href="http://www.reseaugrappe.org/la-semaine-de-lenvironnement-programme/">partout en france</a>, +et <strong>du 6 au 14 Mars sur Toulouse</strong>. +<a class="reference external" href="http://docs.notmyidea.org/sde/prog-toulouse.pdf">Jetez un oeil au programme</a> +! Avec pour objectif de sonder un peu le ressenti des étudiants en +terme de consommation, nous avons mis en place +<a class="reference external" href="http://spreadsheets.google.com/viewform?formkey=dHV2bVllS2lWbzhyV3NBN3NUbi1TM2c6MA">un questionnaire en ligne</a>, +que vous pouvez compléter en une petite 10aine de minutes, +n'hésitez pas ! +<a class="reference external" href="http://www.reseaugrappe.org/consommation/">La page sur la consommation étudiante sur le site du GRAPPE</a></p> +</div> +Python ? go !2009-12-17T00:00:00+01:002009-12-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-12-17:/python-go-fr.html<p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à …</p><p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à l'esprit à propos de Python, sont &quot;logique&quot; et +&quot;simple&quot;. Et pourtant puissant pour autant. Je ne manque d'ailleurs +pas une occasion pour faire un peu d'<em>évangélisation</em> auprès des +quelques personnes qui veulent bien m'écouter.</p> +<div class="section" id="the-zen-of-python"> +<h2>The Zen of Python</h2> +<p>Avant toute autre chose, je pense utile de citer Tim Peters, et +<a class="reference external" href="http://www.python.org/dev/peps/pep-0020/">le PEP20</a>, qui +constituent une très bonne introduction au langage, qui prends la +forme d'un <em>easter egg</em> présent dans python</p> +<div class="highlight"><pre><span></span>&gt;&gt;&gt; import this +The Zen of Python, by Tim Peters + +Beautiful is better than ugly. +Explicit is better than implicit. +Simple is better than complex. +Complex is better than complicated. +Flat is better than nested. +Sparse is better than dense. +Readability counts. +Special cases 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 Dutch. +Now is better than never. +Although never is often better than *right* now. +If the implementation is hard to explain, 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="k">do</span> more of those! +</pre></div> +<p>J'ai la vague impression que c'est ce que j'ai toujours cherché à +faire en PHP, et particulièrement dans +<a class="reference external" href="http://www.spiral-project.org">le framework Spiral</a>, mais en +ajoutant ces concepts dans une sur-couche au langage. Ici, c'est +directement de <em>l'esprit</em> de python qu'il s'agit, ce qui signifie +que la plupart des bibliothèques python suivent ces concepts. Elle +est pas belle la vie ?</p> +</div> +<div class="section" id="comment-commencer-et-par-ou"> +<h2>Comment commencer, et par ou ?</h2> +<p>Pour ma part, j'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'est bien évidemment pas exhaustive et vos +commentaires sont les bienvenus) :</p> +<ul class="simple"> +<li><a class="reference external" href="http://diveintopython.adrahon.org/">Dive into python</a></li> +<li><a class="reference external" href="http://www.swaroopch.com/notes/Python_fr:Table_des_Matières">A byte of python</a></li> +<li><a class="reference external" href="http://www.amazon.fr/Python-Petit-guide-lusage-développeur/dp/2100508830">Python: petit guide à l'usage du développeur agile</a> +de <a class="reference external" href="http://tarekziade.wordpress.com/">Tarek Ziadé</a></li> +<li><a class="reference external" href="http://docs.python.org/index.html">La documentation officielle python</a>, +bien sûr !</li> +<li><a class="reference external" 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 :)</li> +</ul> +<p>J'essaye par ailleurs de partager au maximum les ressources que je +trouve de temps à autres, que ce soit +<a class="reference external" href="http://www.twitter.com/ametaireau">via twitter</a> ou +<a class="reference external" href="http://delicious.com/ametaireau">via mon compte delicious</a>. +Allez jeter un œil +<a class="reference external" href="http://delicious.com/ametaireau/python">au tag python</a> sur mon +profil, peut être que vous trouverez des choses intéressantes, qui +sait!</p> +</div> +<div class="section" id="un-python-sexy"> +<h2>Un python sexy</h2> +<p>Quelques fonctionnalités qui devraient vous mettre l'eau à la +bouche:</p> +<ul class="simple"> +<li><a class="reference external" 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 condition)</li> +<li>Assignation de valeurs multiples (il est possible de faire a,b,c += 1,2,3 par exemple)</li> +<li><a class="reference external" href="http://docs.python.org/tutorial/datastructures.html">Les listes</a> +sont simples à manipuler !</li> +<li>Les <a class="reference external" 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 simple.</li> +<li>Les +<a class="reference external" 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 exemples.</li> +<li>Les +<a class="reference external" 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 construisent</li> +<li>Python est +<a class="reference external" 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'est ce qui m'agaçait avec PHP qui est un langage à typage faible +dynamique.</li> +</ul> +<p>Cous pouvez également aller regarder +<a class="reference external" href="http://video.pycon.fr/videos/free/53/">l'atelier donné par Victor Stinner durant le Pyconfr 09</a>. +Have fun !</p> +</div> +AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e-fr.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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à …</p><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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à expliquer que justement, l'AMAP c'est +avant tout, pour nous, une notion de solidarité envers les +agriculteurs, malgré le fait que le message soit plus profond que +simplement aller acheter du bio (ça, c'est possible aussi en +supermarché), malgré le fait qu'il s'agisse en fait d'une remise en +cause plus profonde de la société, les journalistes n'ont choisi de +prendre que les quelques secondes qui leurs convenaient, celles qui +ne faisaient pas tache, celle ou je dis que &quot;l'AMAP permet aux +étudiants de réapprendre à cuisiner, plutôt que de manger des +nouilles et de se faire des plats réchauffés&quot;. Bien sur, je l'ai +dit et je le pense d'ailleurs, là n'est pas le problème, mais mon +message n'était pas celui là.</p> +<p>Jamais, dans les quelques minutes du reportage, on ne dit ce que +AMAP signifie: Association de <strong>Maintien</strong> d'une Agriculture +<strong>Paysanne</strong>. On ne parles même pas des agriculteurs ! C'est +simplement plus facile pour les étudiants de venir récupérer leurs +paniers, puisque les points de distribution sont sur les facs, et +en plus ça ne coute que 5 euros ! ...</p> +<p>Alors je crois bon de rappeler que L'AMAP n'est pas seulement un +service, c'est un engagement. Sur 5 mois, un engagement solidaire, +c'est la donnée principale de l'équation, celle sans quoi ça ne +peut fonctionner. Par le biais de cette AMAP, on essaye de montrer +que d'autres agricultures sont possibles, que la solidarité c'est +bien réel, et qu'il est possible de sortir du +<em>tout, tout de suite</em>.</p> +<p>Mais bon, apparemment, ça passe pas bien à la télé.</p> + \ No newline at end of file diff --git a/feeds/all.atom.xml b/feeds/all.atom.xml new file mode 100644 index 0000000..282a63f --- /dev/null +++ b/feeds/all.atom.xml @@ -0,0 +1,7239 @@ + +Carnets Webhttps://blog.notmyidea.org/2019-07-03T00:00:00+02:00Ours2019-07-03T00:00:00+02:002019-07-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-07-03:/ours.html<p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>De manière plus large, est-ce normal …</p><p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>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 ?</p> +<p>Suis-je en train de devenir un ours ?</p>velotaf2019-06-27T00:00:00+02:002019-06-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-27:/velotaf.html<p>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 …</p><p>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 personelle et le taf à la brasserie.</p>Un espace des communs Rennais ?2019-06-26T00:00:00+02:002019-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-26:/un-espace-des-communs-rennais.html<p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le …</p><p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le sujet des <em>communs</em>; +2. Monter une structure Rennaise pour proposer de l’hébergement de services web.</p> +<p>Élaborons un peu...</p> +<h2>1. Un espace pour fédérer</h2> +<p>L'idée qui à été développée est celle d'avoir un espace (un ou des lieux, à différents moments dans l'année) pour que les rencontres entre les projets <em>du libre</em> à Rennes puissent se dérouler. Le constat est qu'il existe différentes structures actuellement en place, mais que a) certaines personnes ne se retrouvent pas dans ces espaces et b) la porosité entre ces différents groupes est assez faible.</p> +<p>Pour l'instant pas d'idée précise de ce qui pourrait être proposé, mais quelques pistes ont été évoquées. l'envie est de faire un document d'intention et de proposer à d'autres de rejoindre le collectif en création.</p> +<h3>Fréquence</h3> +<p>Deux pistes ont été évoquées:</p> +<ul> +<li> +<p><strong>Faire des rencontres suffisamment espacées les unes des autres</strong>, pour que leur caractère « exceptionnel » soit une force. Si la fréquence des réunions est assez faible, alors l'incitation pour y prendre part est peut-être plus grande ?</p> +</li> +<li> +<p>ou au contraire, <strong>avoir des rencontres avec une fréquence assez forte</strong>, pour qu'en cas d'incapacité à participer il n'y ait pas trop longtemps à attendre ?</p> +</li> +</ul> +<h3>Charte éthique</h3> +<p>Le fait d'avoir un <em>code de conduite</em> pour de tels évènements à été discuté, un des arguments évoqués étant le fait qu'un tel code n'est pas considéré nécessaire par certaines personnes, puisque les règles évoquées tiennent du bon sens.</p> +<p>Il a été précisé que l'établissement de ce type de document a pour objectif de: +- Faire que des minorités et/ou oppressés se sentent protégés et considérés, et donc bienvenues à ce type d'évènements; +- En cas de situations considérées comme problématiques, des personnes référentes soient désignées pour aider à leur résolution</p> +<h3>Gouvernance</h3> +<p>Le sujet de la gouvernance à été également abordé : pour avoir de tels rendez-vous, peu importe leur nature, il faut que ceux-cis soient organisés. La possibilité d'avoir des organisat·rices·eurs· tournantes à été proposé.</p> +<p>Pour :</p> +<ul> +<li>Cela permet de ne pas reposer uniquement sur quelques personnes;</li> +<li>Faire des fiches explicatives qui permettent à tou·te·s de s'impliquer</li> +</ul> +<p>Contre : </p> +<ul> +<li>Quand tout le monde est responsable, personne ne l'est.</li> +</ul> +<p>Peut-être que des solutions intermédiaires sont à trouver, en désignant d'une fois sur l'autre les personnes qui s’occupent du prochain rendez-vous, par exemple.</p> +<h2>2. Hébergement de services Web</h2> +<p>On a discuté très rapidement de la possibilité de monter une structure pour faire de l’hébergement de services web sur Rennes. Le sujet n'a pas été vraiment développé, mais la question de la relation entre avoir un espace pour fédérer (le 1.) et être un hébergeur de service (le 2.) a été rapidement abordé.</p> +<p>Faut-il avoir une seule et même structure / groupe de personnes pour ces deux projets ? Dans le cas ou l'un s'arrête, entraînerait-il l'autre dans sa « chute » ? Est-il logique de lier les deux ?</p> +<h2>Et donc ?</h2> +<p>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 :-)</p>De Mozilla à la Brasserie du Vieux Singe2018-05-27T00:00:00+02:002018-05-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2018-05-27:/de-mozilla-a-la-brasserie-du-vieux-singe.html<p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que …</em></p><p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que d'autres ont pris plus de place que prévu. J'avais donc envie de reprendre mes notes pour les transformer en billet de blog, question d'élaborer sur le sujet.</em></p> +<hr> +<p>J'ai toujours été motivé par mes passions. Quand j'ai commencé à travailler professionnellement, je me suis rendu compte que même si je faisais quasiment la même chose qu'auparavant, ça n'avait plus le même goût. J'étais maintenant <em>obligé</em> de le faire, et je n'en tirais pas le même plaisir.</p> +<p>Quand j'étais plus jeune au lycée j'écrivais des programmes en <em>Visual Basic</em> que je partageais en ligne sur mon site en <code>.free.fr</code>. Programmes que probablement personne n'a lu, mais l'intention était bel et bien celle de partager mes créations, et d'échanger à leur propos.</p> +<p>Cette culture du partage — celle du logiciel libre — est celle qui m'anime.</p> +<p>Quelques années plus tard, je découvre le langage de programmation Python, et avec lui toute une communauté, mue par ces mêmes valeurs de partage et d'amélioration de nos pratiques. Puis je rencontre le Logiciel Libre, avec l'écriture d'un programme (<a href="https://getpelican.com">pelican</a>) qui reste encore largement utilisé aujourd'hui. Autant dire que c'est une bonne claque que de voir des inconnus contribuer à un bout de code qu'eux aussi jugent utile.</p> +<p>À la fin de mes études, alors que je reste passionné par le développement logiciel, je ne veux ni travailler pour l'industrie, ni pour la finance. Je songe même déjà à cette époque à changer de métier (avant même d'avoir commencé !). Coup de bol, une structure qui m'est chère cherche des développeurs Python: Mozilla. Sans trop y croire, je passe une série d'entretiens qui se déroulent bien (!) et je commence quelques mois plus tard à travailler pour cette organisation incroyable, porteuse d'espoir et de toute une symbolique pour moi.</p> +<p>Je bosse sur du Logiciel Libre, en Python, en télétravail parfois, avec une bonne paie, sans parler du côté prestigieux. Grisant.</p> +<p>Mais au fur et à mesure je découvre l'envers du décors: une méritocratie ancrée et assumée, une hiérarchie de plus en plus importante, menant à une lourdeur administrative assez présente. À ajouter à la barrière de la langue, et aux différences culturelles. Finalement tout n'est pas rose ici.</p> +<p>Je décide alors de (je pense) faire un de mes meilleurs choix de vie à ce jour: passer aux 4/5èmes. Je récupère tous mes vendredis. Des weekends de 3 jours, toutes les semaines. Un espace précieux pour me reposer, et pour rêver un peu.</p> +<p>C'est à ce moment que Fred, un ami de longue date, en revenant du Québec (ou les brasseries sont légion), me propose de faire de la bière avec lui. Moi qui ne savais même pas qu'il était <em>possible</em> de faire de la bière. On tente donc l'expérience, et nos premières expériences sont des journées bien <em>funky</em>, à faire toutes les erreurs possibles.</p> +<p>Peu à peu, on découvre un nouveau monde: celui des brasseurs amateurs. De nouvelles compétences sont nécessaires, de la physique à la biochimie. On se met à rencontrer des professionnels, des passionnés, à échanger sur les forums. On se forme, petit à petit. Tout comme il y a la communauté des gens qui font du Python, il y a la communauté des gens qui font de la bière. Pas encore autant fédérés, ça semble balbutiant alors mais la passion elle est bien présente.</p> +<p>Tout comme le monde du Logiciel Libre est constitué autour d'un ennemi commun (les GAFA), le monde de la bière artisanale à la sien: les brasseries industrielles, qui uniformisent les goûts et les processus.</p> +<p>Je continue en parallèle mon travail chez Mozilla, pendant 4 années. Et puis un jour, une annonce d'arrêt d'un projet sur lequel je travaillais me fait réaliser que cette situation m'épuise. La fameuse goutte de trop.</p> +<p>Je décide alors de partir, de faire une pause, sans trop savoir ce que l'avenir me réserve. Une petite période de blanc de deux mois. Le regard des autres est parfois culpabilisant. Mes parents me demandent si « je ne veux pas attendre encore un peu ». La transition me fait peur, mais je choisis quand même de troquer mon confort matériel pour de la cohérence.</p> +<p>Petit à petit, l'idée de monter ce qui est maintenant devenu <a href="https://www.vieuxsinge.com">La Brasserie du Vieux Singe</a> se pose en évidence. Mais monter une brasserie ce n'est pas uniquement faire de la bière: c'est se mettre d'accord sur des valeurs, trouver comment les défendre, monter un projet pour, et tenir le cap.</p> +<p>Quelques mois après mon départ, on se retrouve donc à parler de ces valeurs de partage, de documentation, de goût. De gouvernance et de collaboration aussi. +Dans nos pratiques courantes, on décide d'intégrer du temps pour documenter la vie de la brasserie.</p> +<p>À titre d'exemple, nos étiquettes contiennent l'ensemble des ingrédients que l'on utilise de la manière la plus détaillée possible. On travaille aussi sur un projet de laveuse de fûts, qui sera publié sous licence libre, avec l'idée de pouvoir, petit à petit, constituer un ensemble d'outils utiles à tous les brasseurs, et peut être même réussir à favoriser les échanges entre toutes ces personnes.</p> +<p>Nous sommes deux brasseurs, deux chefs d'entreprise, mais aussi deux développeurs. Nos compétences de développeurs nous sont utiles quotidiennement: pour notre laveuse de fûts, pour nos créations de recettes (j'ai découvert la puissance des tableurs !), pour notre site de préventes, notre site Web, nos outils du quotidien. On se rend compte qu'il s'agit de compétences précieuses.</p> +<p>Mais monter une entreprise, c'est aussi assumer une partie administrative. Vous vous rappelez cette histoire de réactions face aux activités subordonnées ? Et bien quand je fais mes déclarations aux douanes, ce n'est pas de gaîté de cœur. Je sais par contre pourquoi je le fais: ce sont les règles du jeu. Des obligations, mais peut-être moins de coercition. J'y trouve plus de sens.</p> +<p>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.</p> +<p>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. </p>Groupement d'achats & partage d'expérience2018-03-03T00:00:00+01:002018-03-03T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.html<p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers …</p><p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers et une 60aine de 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'expérience et quelques astuces / outils, au cas où l'envie vous prenne à vous aussi :)</p> +<h1>Organisation</h1> +<p>On organise environs trois ou quatre distributions par an. Le <em>modus operandi</em> est le suivant:</p> +<ul> +<li>chaque product·eur·rice à un·e référent·e, qui s'occupe de faire le lien;</li> +<li>une personne est désignée pour coordonner la distribution;</li> +<li>4 semaines avant la distribution, les référent·e·s mettent à jour les prix / produits dans le tableau de commandes;·e·</li> +<li>3 semaines avant la distribution, les commandes sont ouvertes;</li> +<li>2 semaines avant la distribution, les commandes sont closes;</li> +<li>Les référent·e·s ont ensuite deux semaines pour récupérer les commandes pour la distribution</li> +</ul> +<h1>Quels produits ?</h1> +<p>On essaye d'avoir uniquement des produits qui se conservent (on a également quelques autres produits plus frais, mais avec d'autres modalités).</p> +<p>Entre autres: bières, légumes secs, conserves, jus, miel, pâtes, semoule, café, vinaigres, pommes de terre, oignons, huiles, 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'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'est pas animé par la même éthique !).</p> +<h1>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'attendre la date de la distribution pour l'encaissement. La plupart des producteurs acceptent d'être payés sous quinzaine.</p> +<p>Le jour de la distribution, tout le monde apporte son chéquier. Nous avons mis +en place une moulinette qui s'occupe de faire la répartition des chèques automatiquement, chaque membre se retrouve à faire en moyenne un ou deux chèques.</p> +<p>Chaque référent·e est ainsi remboursé·e de la somme avancée, et chaque +membre du groupement d'achat paye ce qu'il doit payer. Nous n'avons +volontairement pas de structure juridique et pas de compte en banque. Les +paiements s'effectuent directement entre nous.</p> +<h1>Transports</h1> +<p>Chaque référent·e commande les produits, puis ensuite s'occupe de les rapatrier. À Rennes, on a la chance d'avoir pas mal de producteurs aux alentours, donc c'est assez simple.</p> +<p>Le mieux est de ramener les produits juste un peu avant la distribution au lieu de distribution, ça permet d'éviter de les stocker trop longtemps, et d'éviter aux producteurs d'attendre trop longtemps avant d'encaisser les chèques.</p> +<p>Pour les grosses commandes, les voitures se remplissent bien, mais ma petite Clio suffit, que ce soit dit !</p> +<h1>La distribution</h1> +<p>Un peu en amont de la distribution, il faut organiser l'espace. Des tas par membre sont constitués pour faciliter les choses le jour de la 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 pour:</p> +<ul> +<li>discuter de la date de la prochaine distribution;</li> +<li>trouver une nouvelle personne pour la coordonner;</li> +<li>discuter de nouveaux produits;</li> +<li>refaire le monde;</li> +<li>changer de référents pour les producteurs.</li> +</ul> +<p>Et c'est reparti pour un tour ;)</p> +<h1>Nos outils</h1> +<p>On utilise un tableur en ligne pour partager les prix et prendre les commandes. On a essayé d'utiliser <em>ethercalc</em> au début mais ça ne fonctionnait pas pour nous à l'époque (trop de petits bugs). On a donc préféré utiliser Google docs (ouch).</p> +<p>Il est d'ailleurs possible d'y intégrer de nouvelles fonctionnalités assez facilement, du coup Fred et Rémy ont planché sur un moyen d'automatiser la répartition des chèques (qu'on faisait dans un premier temps à la main - assez péniblement).</p> +<p>Le système n'est pas parfait mais fonctionne quand même assez bien !</p> +<p>Quelques ressources, donc:</p> +<ul> +<li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des 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'en faire une copie !).</li> +</ul> +<p>Bon groupement d'achat ;)</p>Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière …</p><p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c'est à dire:</p> +<ul> +<li>enregistrer une sélection de texte ainsi que son contexte: heure, site web.</li> +<li>fonctionner sur Firefox;</li> +<li>stocker mes notes à un endroit que je contrôle (ce sont mes données, après tout !)</li> +<li>rester en dehors de mon chemin: je suis en train de lire, pas en train d'organiser mes notes.</li> +<li>automatiquement partager les notes sur une page web.</li> +</ul> +<p>J'ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j'ai baptisé « Webnotes ». C'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'est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué !</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 !</p>Faire moins2018-02-19T00:00:00+01:002018-02-19T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-19:/faire-moins.html<p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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 …</p><p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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'occasion de contribuer à éviter notre société d'experts.</p> +<p>Le hic, c'est que trop, c'est trop. J'ai donc décidé d'arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j'ai même arreté de faire des choses que j'avais commencé à faire (par exemple de l'escalade), me libérant du temps.</p> +<p>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.</p> +<p>Et surtout, c'est se retrouver à contrôler son engagement.</p>NEIPA #32017-12-29T00:00:00+01:002017-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-29:/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les trouvailles des deux premières versions;</li> +<li>Hop stand de 40mn;</li> +<li>Contrôle du pH à 5.2;</li> +<li>Refroidissement dans l'évier;</li> +<li>Ajouter plus d'avoine;</li> +<li>Faire un mash out;</li> +<li>Augmenter un peu la quantité de grain.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1055 (atteint) +pH: 5.2 (5.4 mesuré)</p> +<h2>Grains:</h2> +<ul> +<li>75% de Pale Ale</li> +<li>12.5% de blé</li> +<li>12.5% flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Mosaic (Hop Stand 40mn)</li> +<li>2g/L Citra (Hop Stand 40mn)</li> +<li>4g/L Citra à cru (en deux fois)</li> +<li>4g/L Mosaic à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li> +<h2>Gypse: 1g</h2> +<dl> +<dd>1.8g (=4.05ml)</dd> +</dl> +</li> +<li>Acide lactique: 0.4ml</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>68°C durant 40mn;</li> +<li>75°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>GigaYeast «Vermont Ale». Le nombre de cellules n'est pas indiqué sur le packaging, ni en ligne.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>12h50: empâtage à 68°C</li> +<li>pH = 5.5. Ajout de 0.2 d'acide.</li> +<li>Pas mal de mesures du pH:<ul> +<li>5.2@23°C (13h05)</li> +<li>5.4@18°C (13h05)</li> +<li>5.2@27°C (13h15)</li> +<li>5.3@19°C (13h20)</li> +<li>5.4@25°C (13h30)</li> +</ul> +</li> +<li>13h33: Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: OK</li> +<li>14h11: 1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>31/12/2017 - Fermentation à 20°C</li> +<li>01/01/2018 - Ajout de 12g de Citra et 12g de Mosaic après deux jours.</li> +<li>10/01/2018 - 1.040 SG = 1.008 corrigé</li> +<li>15/01/2018 - Ajout de 12g de Citra et 12g de Mosaic</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>En mettant 1.5ml d'acide, si on mesure le pH de l'eau, il est à 3.5. Ça nous à pas mal effrayé, puisque on a pas trop l'habitude de monitorer le pH. On refait: 0.4ml d'acide = pH de 4.1. Au final, cela ne semble pas utile de mesurer le pH de l'eau avant de mettre son grain.</li> +<li>Je le savais déjà, mais travailler à deux en discutant n'est pas vraiment une bonne idée: sur les opérations un peu technique, un manque de concentration se fait tout de suite ressentir.</li> +<li>BeerSmith semble proposer un outil pour calculer les modifications de pH, je devrais l'utiliser la prochaine fois.</li> +<li>Baisser le ration d'empâtage: On s'est retrouvé avec beaucoup trop d'eau de rincage, alors qu'on était sur une bière assez faible en densité.</li> +<li>Au final, ajouter l'acide au départ est problématique pour le pH de l'eau qui baisse énormement. Après quelques recherches, il semble qu'il faille faire confiance au logiciel, et prendre une seule mesure de pH à 10mn (cela devrait être stable). Le pHmetre est aussi peut-être en cause.</li> +<li>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 ?</li> +</ul>NEIPA #22017-12-18T00:00:00+01:002017-12-18T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-18:/neipa-2.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le fermenteur</li> +<li>Ne pas se laisser avoir par la baisse de température durant l'empâtage.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1060 (1050 mesuré) +pH: 5.2 (atteint)</p> +<h2>Grains:</h2> +<ul> +<li>90% Pils</li> +<li>10% Flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Wakatu (au Whirlpool)</li> +<li>2g/L Motueka (au Whirlpool)</li> +<li>4.5g/L Wakatu à cru (en deux fois)</li> +<li>2.5g/L Motueka à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li>Gypse: 0.9g</li> +<li>CaCl2: 3.4g</li> +<li>Acide lactique: Au batch précédent, j'avais mesuré 5.6, donc: ajout de +2ml d'acide (=2.4g).</li> +<li>Utilisation d'Irish Moss (2g) pour coaguler les protéines.</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>65°C durant 90mn (68°C au départ, 65 visé)</li> +<li>78°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>London Ale III.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>18h36 - empatage à 65°C</li> +<li>19h16- pH = 5.2</li> +<li>Densité 1er moût: 1070</li> +<li>Ébullition importante pour atteindre 6,2L avec la bonne densité.</li> +<li>Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: NOK</li> +<li>1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>18/12/2017 - Fermentation à 18°C</li> +<li>21/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Passage à 10°C.</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>Je change de technique, et mets l'acide lactique directement dans l'eau.</li> +<li>Je concasse moins fin mais reteste quand même l'avoine. Aucun souci de filtration (mais l'avoine n'est pas concassé).</li> +<li>1g de CaCl2 ~= 2.25ml en solution à 33%.</li> +<li>Les deux thermomètres n'affichent pas la même température. Super :(.</li> +<li>Au final, j’empâte dans une casserole pour pouvoir faire un mash-out.</li> +<li>Le pH oscille pas mal durant l'empâtage. J'ai mesuré des pH de 4.9 à certains moments, mais au final la dernière lecture est de 5.2, ce qui me semble bon.</li> +<li>Le système que j'utilise (refroidisseur en cuivre) pour refroidir mon moût n'est pas génial parce que ça mélange pas mal ce qu'on veut voir se déposer au fond de la cuve. Refroidir directement dans l'évier est vachement plus simple (c'est pratique de faire du 6L pour çà !)</li> +<li>Le teste à l'iode était positif: tout n'était pas converti. Mais à 90mn de mash, je ne crois pas pouvoir faire grand chose de plus.</li> +<li>Idée en vrac, à voir à la dégustation, mais ajouter un peu de cara pourrait être sympa.</li> +<li>L'irish moss à vraiment bien fonctionné. Je me demande si je ne devrais pas même laisser décanter un peu plus longtemps durant le whirlpool pour avoir un effet encore plus impressionnant.</li> +<li>Je trouve que l'efficacité de cette brasserie est vraiment pourrie.</li> +<li>Un peu d'eau est venue diluer le moût (DI = 1050 au lieu de 1060 souhaité)</li> +<li>Au goût, le moût à vraiment un goût qui m'assèche la gorge. Trop de modifications de l'eau ? A voir si l'effet persiste après fermentation.</li> +<li>A priori, d'après un article de Scott Janish, empâter avec de l'avoine cru ne fonctionne que si on empate haut. Ca à un impact sur l'efficacité générale (2h pour conversion totale, c'est peut-être pour ça que mon teste à l'iode était positif)</li> +<li>Sur l'avoine toujours, il faut <strong>dépasser 18%</strong> pour avoir un côté moelleux. Certains mettent jusqu'à 40% !</li> +</ul>Un club des brasseurs amateurs Rennais2017-11-06T00:00:00+01:002017-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-11-06:/un-club-des-brasseurs-amateurs-rennais.html<p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante …</p><p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante autour de la brasserie artisanale dans le coin.</p> +<p>En six mois, on est maintenant une grosse trentaine de personnes à être inscrits sur les listes et à se retrouver de temps à autres.</p> +<p>On en profite pour s'échanger des bons plans, déguster nos créations, (essayer de) faire des commandes groupées de malt, et pour se rencontrer pour papoter entre passionnés.</p> +<p>On a pas mal d'idées de trucs sympa a faire, entre autres:</p> +<ul> +<li>brasser une fois en gros puis se séparer le batch en plein de petits fermenteurs pour essayer différentes levures, différents houblons en <em>dry hop</em>, etc.</li> +<li>A la dernière rencontre, on s'est mis d'accord sur un style de bière pour se lancer un petit défi: tous brasser <a href="https://blog.notmyidea.org/larrivee-du-trouble-ou-comment-faire-des-neipa.html">une NEIPA</a> pour ensuite comparer nos résultats.</li> +</ul> +<p>Bref, c'est plutôt chouette ! Je me suis rendu compte qu'on avait quasiment aucune existence en dehors des réseaux sociaux, alors je me permet de publier ce petit bout d'article avec quelques liens…</p> +<p>Si tu es dans le coin et que tu souhaite nous rencontrer, n'hésite pas à rejoindre <a href="https://www.facebook.com/groups/899071153568179/">notre groupe de discussion Facebook</a> et notre <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">liste de diffusion mail</a>.</p> +<p>A bientôt ;)</p>L'arrivée du trouble (ou comment faire des NEIPA ?)2017-10-17T00:00:00+02:002017-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-10-17:/larrivee-du-trouble-ou-comment-faire-des-neipa.html<p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir …</p><p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir leur propre bataille qui divise au moins autant: une IPA peut elle être aussi trouble qu'une hefeweizen ? En provenance du coin Nord Est des  États-Unis, l'IPA trouble est en passe de devenir culte depuis quelques années. Mais la mode ne vient pas sans contrecoup. En fait, tout le monde y va de son opinion chez les brasseurs artisanaux. Pour ceux qui apprécient ce type d'IPA, l'apparence trouble signifie que les gorgées qui suivent seront extrèmenent riches en huiles de houblons; pour les autres, l'apparence est un affront à des principes ancestraux. Que vous les appeliez des rince-bouches, des soupes boueuses, brillantes ou horribles, ne vous faites pas de fausse idée: ces ales troubles sont là pour rester.</p> +<p>Pour commencer cette histoire, revenons un peu au début des années 1990. La scène brassicole artisanale était en train de vivre son premier boom et les nouvelles brasseries faisaient leur apparition dans tous les coins des États-Unis. Menée par Sierra Nevada Brewing Company, les American Pale Ale et les American IPA étaient en train d’émerger en tant que styles populaires parmi les amateurs de bière, pour leurs caractéristiques riches en houblon.</p> +<p>Le niveau d'amertume était un trait notoire, et avoir la bonne morsure d'amertume était essentiel pour une IPA. L'innovation a ensuite commencée à arriver sur la cote Ouest des États Unis à la fin des années 1990, et au début des années 2000, quand quelques doubles ou impériales IPA telles que Pliny the Elder de Russian River et Ruination IPA de Stone Brewing ont commencées à sortir des fermenteurs. Alors que celles ci contenaient énormement de « morsure du houblon», ce qui séparaient ces bières de beaucoup d'autres versions du style était le fait que le nez et la saveur du houblon semblaient éclater de la bière.</p> +<p>Du point de vue du brasseur, les huiles essentielles de ces houblons étaient bien plus présents que les acides alpha. En utilisant un profil de malt neutre et une souche de levure neutre, ces bières laissaient la part belle aux houblons. Ces brasseurs utilisaient aussi des houblons souvent critiqués, forts en acides alpha, tels que Columbus, Centennial, Simcoe et Chinook à la fin de l'ébullition ou en houblonnage à cru... et en grosses quantitées. Cela peut sembler comme une pratique courante pour une IPA actuellement, mais il y a à peine 15 ans, la plupart de la littérature évitaient d'utiliser ces variétés de houblon pour une utilisation autre que de l'amérisant. Lévolution d'une nouvelle American IPA était en train de prendre forme, sur la cote Ouest des étants unis, un style que les buveurs de bière ont nommé la « West Coast IPA».</p> +<h1>La phase de démarrage</h1> +<p>De retour sur la cote Est des États-Unis, dans un petit brewpub de Burlington à Vermont, deux brasseurs commencent innocemment à développer un type d'American IPA avec des objectifs similaires que les brasseurs de la côte Ouest, mais en utilisant une stratégie différente. Crée en 1988 par Greg Noonan et Steve Polewacyk, le « Vermont Pub &amp; Brewery » deviendra le berceau d'une nouvelle révolution autour des IPA.</p> +<p>Souvent citée comme étant les premiers brasseurs des Black IPA modernes ainsi que des New England IPA, offrant une variété de bières qui était extrèmement rare à cette époque, le « Vermont Pub &amp; Brewery » a des racines provenant de la connaissance du brassage et de la chimie de Greg Noonan, ainsi que son flair pour la créativité.</p> +<p>Se reposant sur la révolution de la bière mondiale (menée par Michael Jackson), Greg Noonan à exploré des styles de bières qui étaient en dehors des sentiers battus, même pour les brasseurs qui étaient déjà en avance sur leur temps.</p> +<p>Arrive John Kimmich, qui, en 1994 à déménagé dans le Vermont avec l'objectif de brasser sous la tutelle de Greg Noonan. John à travaillé un temps à Pittsburg (en Pennsylvanie) dans un <em>home brewshop</em> nommé Country Wines. Il a travaillé avec Alexis Hartung et sa grande bibliothèque sur le brassage maison et a eu son premier éclair de génie brassicole en lisant le livre de Greg Noonan « New Brewing Lager Beer ». Un an plus tard, il commence à travailler au « Vermont Pub &amp; Brewery ». En quelques mois, Greg commence à avoir confiance dans les capacités de son nouveau protégé. Avec chaque bière que John travaillait, le mentor était impressionné. Après douze mois, Greg donne la liberté à John d’expérimenter seul sur les recettes.</p> +<p>En 1997, John part du « Vermont Pub &amp; Brewery » et cofonde avec sa femme Jen un brewpub en 2003, le « Alchemist Pub &amp; Brewery », situé 30mn à l'est de Burlington à Waterbury dans le Vermont. A cette époque, Waterbury était un petit village dormant du New England, n'attirant pas grand monde autre que quelques touristes. Il était par contre assez bien situé, à un croisement des chemins, juste à la sortie d'une autoroute majeure, Waterbury est facilement accessible par à la fois les voyageurs en route pour les endroits touristiques et pour les locaux en allant / revenant du travail ou pour leurs excursions shopping. Grâce à ces quelques éléments, Waterbury s'est donc révélé êre un excellent spot pour Jen et John.</p> +<p>Une caractéristique unique des bières houblonnées de Kimmich était que lorsque servies fraîches et non filtrées, elles étaient souvent assez troubles. Il trouvait que filtrer ses bières pouvait introduire de l'oxygène non souhaité, enlevant de la bière beaucoup d'aspects intéressants. Il utilisait une souche nommée Conan (VPB1188), une levure que son mentor a développé et que maintenant beaucoup connaissent. Avec les dérivés Anglais, la souche de levure Conan, les bonnes connaissances en brassage de John, ainsi que son habitude à expérimenter avec les houblons, on se retrouve avec une combinaison gagnante pour une révolution du brassage sur la côte est.</p> +<h1>La phase de croissance</h1> +<p>En 2007, alors que j'allais au festival des brasseurs du Vermont, la queue pour accéder au stand de The Alchemist était d'au moins 20 minutes pour un verre. Certaines personnes remplissaient leurs verres et retournaient faire la queue pour avoir la chance de goûter une autre de ces bières tant acclamées, en particulier pour Heady Topper. Pour la première fois brassée en 2003, Heady Toper retenait alors l'attention, alors qu'elle n'était réellement qu'une parmi les nombreuses IPA acclamées de chez The Alchemist. Des histoires circulaient comme quoi certaines personnes amenaient leurs pintes aux toilettes pour remplir des bouteilles, les capsuler et les ramener chez eux, puisque le bar ne proposait pas de remplir de Growlers à l'époque, ni ne vendait de bouteilles. Je pensais alors que l'engouement pour ces IPAs avait atteint une sorte de paroxysme. Je n'avais pas encore compris que le feu était seulement en train de se construire.</p> +<p>J'ai récemment demandé à Shaun Hill, de la brasserie « Hill Farmsted » à Greensborrow Bend dans le Vermont, classée « meilleure brasserie du monde » 3 des 4 dernières années sur RateBeer.com, quel était sa relation avec John Kimmich à l'époque. Shaun brassait à l'époque 30mn plus loin, à Stowe, dans un brewpub appelé « The Shed».</p> +<p>« En 2005, je ne tarissais pas d'éolges pour les bières de John me faisait le plaisir de critiquer mes bières » me dit Hill, « Cette relation à évoluée avec le temps, plus specialement lorsque j'ai déménagé au Danemark et que cette conversation est devenue une conversation entre pairs, poussant l'autre dans de nouvelles directions.». Avec le decès de Greg Noonan en 2009, l'ancien protégé est devenu le nouveau mentor. Lors d'un échange avec Joel Mahaffey de Foundation brewing Co, à Portland à propos des IPAs influentes pour cette nouvelle révolution, il dit de The Alchemist « Quiconque réponds à cette question et oublie Heady Topper, ils sont à coté de la plaque. Il s'agit de la première IPA trouble, et à laissée une marque sur la communauté brassicole.»</p> +<p>Ce qui à emergé dans le coin nord-est des états unis est une explosion de nouvelles brasseries produisant des Pale Ale, des IPA et des double IPA basées sur la non filtration, l'explosion de saveurs, et un corps doux, un style que Greg Noonan et John Kimmich ont découvert, et qu'ensuite Shaun Hill à continué à affiner. John et Shaun ont séparemment pointé du doigt le fait qu'ils brassaient juste des bières à leur convenance, et qu'ils appréciaient le produit fini. Le terme « Juicy IPA » s'est retrouvé être un nom pour ces bières, et la texture est souvent aussi importante que le nez et le gout de houblons. Et comme les IPA de la côte Ouest se sont répendues en 2008, les bières troubles, non filtrées, les New England IPA se répendent en 2016.</p> +<h1>C'est parti !</h1> +<p>Il est maintenant temps de passer à la brasserie et de regarder comment faire pour brasser une IPA, New England style. Shaun Hill dit « soyez vous mêmeet faites une bière qui goute, sent et ressemble à ce que vous voulez qu'elle soit », JC Tetreault de Trillum à Boston dans le Massachussetts ajoute « la réponse courte… tout est important ! Vous devez vous concentrer sur chaque aspect pour arriver à la bière que vous souhaitez. » L'objectif est d'arriver à une bière douce, un peu ronde, presque tropicale, à la texture ressemblant presque à un jus de fruit, laissant une morsure subtile sur la langue en fin de bouche graçe au houblon.</p> +<h2>Les malts</h2> +<p>Tout comme les IPAs de la cote Ouest, les NEIPA sont relativement simples en malts. Le style évite les malts qui ajoutent des saveurs de pain et de crackers. Les malts cristals et autres malts au dessus de 20°L (ndt: 52 EBC) sont d'une manière générale évités. Ces bières peuvent bénéficier de certains ajouts de malts cristal clairs, mais gardez les à l’œil. Des flocons d'avoine, d'orge, de blé et autres peuvent être ajoutés pour contribuer au corps, mais ne pensez pas qu'ils soient une necessité. J'ai pu jouer avec des pourcentages de 15% de flocons dans mes recettes, et les résultats étaient presque excessifs. JC Tetreault dit que « à propos des ajouts de céréales non maltés et de flocons… nous ne les utilisons pas dans toutes nos bières basées sur le houblon. En fait, une proportion plutôt petite de nos bières basées sur le houblon en font usage». Les ajouts de sucre tels que les dextrose, saccharose et sucres crus augmentent la densité du moût pour s'assurer de la sécheresse dans les versions plus alcoolisées. Si vous choisissez d'ajouter du sucre cru, encore une fois, faites en sorte que l'ajout soit modeste; j'ai trouvé que certaines saveurs de mélasses avaient tendance à arriver à partir de 10% du total du grain. L'objectif est de garder les houblons comme caractéristique principale de la bière, tout en ayant une base de malt douce mais présente.</p> +<h2>Les levures</h2> +<p>Et c'est ici que les NEIPA dérivent des IPA de la cote Ouest. L'ajout des levures ainsi que le traitement à partir de la fermentation semble être la plus grosse différence entre les deux styles. D'abord, regardons comment ces bières sont fermentées. La plupart des NEIPA ne sont pas clarifiées dans le fermenteur avec des agents clarifiant tels que de la gélatine, du Biofine® ou du Polyclar™, et elles ne sont pas filtrées ou centrifugées plus tard pour clarifier la bière. La pensée derrière ce process est qu'enlever les levures de la bière à également pour effet d'enlever les huiles essentielles ainsi que d'autres nuances subtiles qui permettent à la bière d'avoir son caractère propre. Cela permet de garder un niveau d'huiles assez elevé dans le produit fini. Deuxièmement, les brasseurs de New England fermentent en utilisant une souche de levure d'origine anglaise. Ashton Lewis, l'éditeur technique de Brew Your Own précise « D'après des études ADN, la levure California Ale (White Labs WLP001, Wyeast 1056 et les autres souches de Chico) viendraient plutôt de Cologne, en Allemagne ». Ces souches américaines ont été choisies pour leur capacité à produire des bières claires, transparentes et amères sans ajouter de caractère. Les souches de levure utilisées par les brasseurs de New England IPA sont utilisées pour ajouter des esters, qui aident à produire le profil juteux de ces bières. Les IPAs brassées avec ces souches ne semblent pas être aussi transparentes que les souches Americaines lorsqu'elles sont exposées à des niveaux d'huiles elevés. Ceci vient en désaccord avec la plupart de la littérature sur les souches Anglaises. Si vous lisez la description de la plupart des souches de levures utilisées pour produire ces IPA troubles, la plupart sont considéeées « hautement floculantes », alors que la souche Chico, souvent utilisée pour les IPA de la cote Ouest annonce plutôt une floculation moyenne à faible. Pourquoi alors ces bières ne se clarifient pas lorsqu'elles sont sujettes à des hautes doses de houblon en fin d'ébullition ou en houblonnage à cru ? Cela reste encore une zone floue, j'ai donc demandé à quelques personnes dans l'industrie à propos de ce flou. Certains brasseurs pointent du doigt le fait que ces souches de levures floculent trop rapidement. Cela ne laisse pas le temps aux polyphénols de s'attacher aux levures, laissant ces composés ainsi que d'autres composés dérivés du houblon dans la solution plutôt que des les en enlever. Ashton Lewis nous rappelle aussi que le trouble trouvé dans les hefeweizen est principalement causé par les interactions entre les protéines et les polyphénols, et non pas par les levures.</p> +<p>Donc, quelles sont les souches de levure que vous devriez utiliser ? Le choix est en fait assez large, pour ceux qui souhaitent brasser ces types de American IPA, referez vous donc aux suggestions données dans les recettes jointes pour quelques idées.</p> +<h2>L'eau</h2> +<p>L'eau joue un rôle prépondérant dans le développement des New England IPA. Concentrez vous sur les niveaux de dureté de votre eau. Si vous avez une eau assez douce, alors vous avez un bon point de départ. Si vous avez une eau plutôt dure, obtenez un relevé d'eau (ndt: allez faire un tour sur le site « Eau du bassin Rennais » !). Si vous n'avez pas ces relevés d'eau, vous pouvez aussi faire analyser votre eau par des laboratoires, ou vous pouvez le faire vous même grâce à des kits de test de l'eau. Peu importe ce que vous choisissez, utiliser de l'eau distillée ou osmosée peut vous fournir une bonne base pour construire le profil d'eau que vous souhaitez obtenir. Essayez de garder votre niveau de bicarbonate en dessous de 50 PPM pour votre eau d’empâtage et votre eau de rinçage.</p> +<p>La prochaine chose sur laquelle se concentrer est vos sulfates et vos chlorures. Ceci est parfois controversé, mais encore une fois peut potentiellement être un facteur différenciant entre les IPA de la côte Est et les IPA de la côte Ouest. Quand j'ai commencé à jouer avec la composition de mon eau, j'ai traité l'eau de mes IPA pour atteindre un rapport 2:1 de sulfates / chlorures, ce qui s'est traduit par 100:50 PPM. J'ai produit plusieurs bières qui pouvaient rivaliser (selon moi) avec certaines que mes idoles produisaient. Mais, dans l'esprit du brassage amateur, j'ai continué à expérimenter. J'ai changé l'équilibre de sulfate / chlorures à 200:50PPM sans que je perçoive un changement. J'ai ensuite essayé 100:100 et trouvé que ça me plaisait un peu plus. Mes trouvailles ne sont pas la seule preuve anecdotique que booster le niveau de chlorures peut bénéficier à ce style de bières. Si vous cherchez à ajuster vos sulfates et for chlorures pour votre eau d'empâtage et de rincage, je vous encourage à jeter un oeil à l'article de Scott Janish du 7 Mars 2016 intitulé « Mouthfeel softness ». Scott y parle des effets négatifs d'un taux de sulfates elevé et des aspects positifs d'un niveau de chlorures elevé.</p> +<h2>Les houblons</h2> +<p>Généralement, l'amertume des houblons dans ce type d'IPA joue un rôle support, qui vient équilibrer le corps et la douceur des malts. Premièrement, gardez l'ajout de houblons amérisants modéré à faible. Vous pouvez expérimenter avec l'ajout de houblons amérisants mais je n'ai jamais eu l'occasion de trouver qu'une utilisation importante de houblons amérisants menait à une meilleure New-England IPA. Utilisez des houblons hauts en alpha tels que Magnum, Warrior™ ou Bravo si vous choisissez d'utiliser des houblons en cône ou en pellets, et je recommande de garder les ajouts d'amérisants assez faibles. D'habitude, j'essaye houblonner pour un rapport de 1:3 BU:GU (amertume sur densité). Cela signifie que quand je vise une densité cible de 1.066, l'ajout de houblons à 60mn est de 22 IBUs. Cela est fait pour éviter d'ajouter une dureté qui peut provenir d'une ébullition d'une quantité plus elevée de houblons. L'autre option est d'utiliser des extraits de houblon, qui peuvent contribuer les acides alpha nécessaires pour obtenir la bonne amertume, sans ajouter de polyphénols, que certains brasseurs pensent être à l'origine d'une certaine dureté.</p> +<p>Les ajouts de houblons en fin d'ébullition jouent un rôle beaucoup plus important pour la production de New-England IPA. Des apports copieux à la fin de l'ébullition ou au <em>flame-out</em> sont utiles pour tout type d'IPA hautement aromatique. Cela ajoutera des IBUs pour compléter votre apport en houblons amérisants et commencera à créer votre profil d'huiles. Je trouve que des variétés plus mordantes / piquantes comme le Simcoe®, Columbus, Chinook et Apollo fonctionnent bien à cette étape. Chaque brasseur semble trouver sa technique ici, qu'il s'agisse de faire plusieurs ajouts à 20mn ou moins puis de baisser à une température précise pour faire un <em>hop stand</em>, ou bien de simplement ajouter tous les houblons au <em>flame-out</em> et de les laisser durant 20 minutes ou plus. Il ne semble pas qu'il y ait de mauvaise manière de faire, juste plusieurs manières d'extraire les huiles essentielles des houblons à une température pas trop haute.</p> +<p>Le houblonnage à cru est votre prochain objectif. J'aimerais me concentrer sur les techniques plutôt que sur les quantités ou variétés puisque la technique semble être le plus important ici. Ceci dit, une chose est sure, ne soyez pas trop timide avec les ajouts durant le houblonnage à cru. 7.5g/L est certainement un bon point de départ. Vous pouvez ajuster en fonction de vos résultats. Les brasseurs Scott Janish et Michael Tonsmeir ajoutent que mettre ces bières en fûts à quelques avantages. Houblonner dans le fût, purger au CO2 et le fait de ne pas avoir de période prolongée de carbonatation sont déjà deux des avantages des fûts sur les bouteilles.</p> +<p>Alors, quand est le meilleur moment pour faire son houblonnage à cru ? Biern que ce ne soit pas une necessité, le fait de faire son houblonnage à cru en deux fois semble être un bon choix pour ce genre d'IPA. Prenez ce que vous pensiez ajouter lors du houblonnage à cru et séparez le en deux. Le premier ajout se fera durant la phase active de fermentation alors que le second se fera quand la fermentation se sera calmée et que les levures auront flocculées. Le premier ajout peut se faire à différents stades de la fermentation primaire; certains brasseurs les ajoutent au même moment qu'ils ensemencent, certains autres lorsque le krausen est haut, alors que la plupart l'ajoutent vers la fin de la fermentation. Je préfère faire le premier ajout une fois que le krausen est redescendu. Les hétérosides et les bio-transformations sont des éléments importants dans cette discussion à propos de comment la levure intéragit avec les huiles des houblons et les autres dérivés du houblon. Je trouve que les houblons ajoutés à la fin de l'ébullition vont apporter des caractéristiques similaires que les huiles de houblons ajoutés durant le ébut de la fermentation. Pour ce qui est du second ajout, l'objectif est d'attendre que la fermentation se soit calmée. Le timing n'est pas vraiment un facteur important ici, mais l'introduction d'oxygène est un point crutial. Prenez bien soin d'introduire le moins possible d'oxygène dans la bière à ce moment çi.</p> +<p>Dernièrement, quelque chose qui est nouveau pour moi: le houblonnage à cru sous pression. Cela vous demandera de l'équipement supplémentaire, principalement quelque chose apellée une « Spunding Valve». Il s'agit d'une valve qui permet de garder une certaine pression dans le fermenteur. Si la pression dépasse la valeur cible, alors la valve s'ouvre pour faire redescendre le fermenteur à la valeur souhaité. Mais, en quoi cela pourrait-être interéssant pour nous ? Parce que nous cherchons à garder un maximum de houblons aromatiques, en évitant d'en perdre. Les brasseurs amateurs ainsi que les brasseurs pros se sont penchés sur la question des spuinding valve de plus en plus dernièrement pour la fermentation primaire et pour le houblonnage à cru.</p> +<p>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.</p> +<p>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 !</p>Brasserie du Vieux Singe — Installation en cours.2017-06-26T00:00:00+02:002017-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-06-26:/brasserie-du-vieux-singe-installation-en-cours.html<p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour …</p><p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour être à portée de main.</p> +<p>La chose la plus frappante, c'est la vitesse à laquelle passent les journées: j'ai <em>vraiment</em> l'impression d'avoir quitté Mozilla hier. Si les collègues me +manquent, je ne ferais machine arrière pour rien au monde: je trouve finalement ce sens qui me manquait cruellement.</p> +<p>Après quelques hésitations au départ, j'ai décidé de mettre de côté mes activités liées à l'informatique: difficile à assumer quand on croise les copin.e.s avec qui on avait l'habitude de discuter énormement de ces sujets, mais ça permet de laisser plus de place pour l'humain. Plus de place pour les «Au fait, comment ça va toi ?» quand j'ai l'occasion de les recroiser, ce qui n'est pas plus désagréable :)</p> +<p>Les journées sont donc organisées autour de la brasserie: beaucoup plus de planification que ce que j'imaginais au départ. Peut-être que c'est aussi du au fait que nous soyons tous les deux des ex-informaticiens un peu perfectionnistes sur les bords. On se voit très souvent pour avancer sur des sujets de fond tout comme sur du pratico-pratique. Pour vous donner un ordre d'idée des questionnements: Quelle taille d'entreprise ? Quelles valeurs communes ? Quelles bières ? Quelle image donner ? Quelle place donner au confort ? Comment éviter la compétitivité ? Comment réussir à impacter les producteurs (houblon / malt) de manière positive ? Quels salaires se donner ?</p> +<p>Un peu de production quand même (pour les amis) mais on se garde la grosse partie pour le lancement.</p> +<h2>Apprentissage</h2> +<p>Je profite de ces quelques mois pour apprendre: autour de la fabrication et de la dégustation de bière bien sûr (encore un milieu en constante évolution !), mais pas que. J'ai maintenant quelques bases de gestion d'entreprise, en comptabilité, en biologie et en chimie. J'ai bien dit quelques <em>bases</em>, mais qu'est-ce que c'est agréable !</p> +<p>C'est assez agréable de se remettre dans une posture d'apprenant, et d'avoir le temps pour cet apprentissage.</p> +<h2>Questionner la posture de «Chef d'entreprise» et son rapport au temps</h2> +<p>Décider de créer sa boîte, c'est aussi se poser la question de comment organiser son temps: combien de temps travailler ? Quel temps donner aux loisirs ?</p> +<p>Je trouve rassurant de voir ces interrogations abordées avant-même le démarrage de l'entreprise. La plupart des personnes qui nous suivent et nous guident partent du postulat qu'il faudra bosser énormement, là ou nous essayons de trouver un modèle qui soit viable dans le temps, notre souhait est de bosser à 80% (4 jours par semaine).</p> +<p>Certes, il faut travailler pour que ça tourne, mais il faut aussi s'accorder des temps de respiration pour être d'autant plus efficace quand on bosse. C'est d'autant plus intéressant de prévoir ces aspects lors de la phase de <em>design</em> de l'activité: on organise le temps autrement ! Ceux qui me lisent de temps à autre savent que c'est une constante de mes réflexions, on verra si ça fonctionne dans les faits.</p> +<h2>Les projets collectifs</h2> +<p>Un autre point important est la place que le <em>collectif</em> prends dans cette nouvelle expérience. Au départ, quand j'imaginais le projet sur le court-terme, je mettais la composante collective au second plan dans l'immédiat (au delà des intéractions avec Fred, mon associé). L'occasion de travailler à la construction d'un espace collectif s'est présentée, et on y travaille actuellement.</p> +<p>C'est à la fois riche (en partage de points de vue, en entre-aide) et à la fois difficile (beaucoup d'heures de réunions, il faut apprendre à communiquer de manière efficace, il faut parfois faire face à des conflits). Dans l'ensemble, je ne regrette pas ce choix même si il est important de ne pas perdre de vue les objectifs de la brasserie dans l'histoire.</p> +<p>Et puis la collaboration ne s'arrête pas qu'au collectif d'activité: le milieu brassicole est en mutation, et les valeurs de partage font bel et bien partie du lot de changements. Les rencontre avec les brasseurs du coin de Rennes le montrent bien: l'esprit est plus à l'entraide qu'à la concurrence, au vu de la demande qui est toujours croissante. Tant mieux, on a autre chose à faire qu'à se tirer dans les pâtes ;)</p> +<h2>Besoin de concret</h2> +<p>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…</p> +<p>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 ?</p>Comment est-ce que vous générez vos formulaires ?2016-05-31T00:00:00+02:002016-05-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.html<p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est …</em></p><p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est passé par pas mal d'é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'organisateurs d'é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'est +pas libre et que les données sont stockées chez 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'ils puissent y répondre. +Je reviens ensuite plus tard pour voir la liste des réponses apportées.</p> +<p><img alt="Capture de l'interface de création du formulaire" src="{filename}/static/formbuilder-build.png"></p> +<h2>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'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 à +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'opération terminée.</p> +<p><img alt="Capture de l'écran avec les URLs générées" src="{filename}/static/formbuilder-created.png"> +<img alt="Capture d'écran d'un exemple de formulaire" src="{filename}/static/formbuilder-form.png"></p> +<h3>Pas de compte</h3> +<p>Vous n'avez pas besoin d'avoir un compte sur le site pour commencer à l'utiliser. +Vous créez simplement un nouveau formulaire puis envoyez le lien à vos amis pour +qu'eux puissent à leur tour le remplir.</p> +<p><img alt="Capture de la page d'accueil, ou aucun compte n'est requis" src="{filename}/static/formbuilder-welcome.png"></p> +<h3>Gardez la main sur vos 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="{filename}/static/formbuilder-results.png"></p> +<h3>API</h3> +<p>L'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 HTTP. Ce qui fait qu'il est très facile de +réutiliser les formulaires que vous avez construits (ou leurs réponses) depuis +d'autres outils.</p> +<h3>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'instance qui est mise à votre disposition sur +<a href="https://www.fourmilieres.net">wwww.fourmilieres.net</a>, mais vous pouvez +également l'héberger vous même très +simplement, et vous êtes d'ailleurs fortement encouragés à le faire ! Notre +objectif n'est pas de stocker l'ensemble des formulaires du monde, mais de +(re)donner le contrôle aux utilisateurs !</p> +<h2>On commence petit…</h2> +<p>Cette <em>release</em> n'est (bien sur) pas parfaite, et il reste encore pas mal de +travail sur cet outil, mais je pense qu'il s'agit d'une base de travail +intéressante pour un futur où Google n'a pas la main sur toutes nos données.</p> +<p>La liste des champs supportés est pour l'instant assez faible (Texte court, +Texte long, Oui/Non, choix dans une liste) mais elle à vocation à s'étendre, en +fonction des besoins de chacun.</p> +<p>J'ai d'ailleurs créé <a href="https://www.fourmilieres.net/#/form/cfd878264cec4ed2">un formulaire pour que vous puissiez me faire part de vos +retours</a>, n'hésitez pas !</p> +<h2>Et, euh, comment ça marche ?</h2> +<p>Le <em>formbuilder</em>, comme j'aime l'appeler se compose en fin de compte de deux +parties 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 HTTP</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'envoyer les données sur les <em>APIs</em> coté + 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'il génère en fin de compte du +<a href="http://jsonschema.net/">JSON Schema</a>, un format de validation de données <em>JSON</em>.</p> +<p>Donc, reprenons! Vous arrivez sur la page d'accueil puis cliquez sur +"Create a new form", puis vous vous retrouvez face à une interface ou vous pouvez +ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez sur +"Create the form".</p> +<ul> +<li>Le JSON Schema est alors envoyé au serveur Kinto, qui l'utilisera pour valider + les données qu'il recevra par la suite.</li> +<li>Ce JSON Schema sera aussi utilisé lors de l'affichage du formulaire aux + personnes qui le remplissent.</li> +<li>Un jeton d'accès est généré et ajouté à l'URL, il s'agit de l'identifiant du + formulaire.</li> +<li>Un second jeton d'accès administrateur et généré, il vous faut le garder de + coté pour avoir accès aux 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 !</p>Cloisonnement des activités ?2016-05-29T00:00:00+02:002016-05-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-29:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en …</p><p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en faire +un plaisir. Oh, et des fois on parle un peu de technique aussi.</p> +<h1>Alors, brasserie ou code ?</h1> +<p>Ces quelques jours ont été fort inspirants. Alors que je suis en train de +changer de métier (vers celui de brasseur) c'était un moyen de me rendre compte +que bien que je ne souhaite plus faire du Web mon métier <em>la, tout de suite, +maintenant</em>, je reste un passionné par la chose.</p> +<p>En partant de Rennes, je ne savais pas trop quoi penser de cette situation. +Prendre un week-end pour échanger avec les gens sur quelque chose dont je +m'éloigne ? C'est pas une perte de temps ?</p> +<p>Si je passe du temps à écrire des bouts de code, des logiciels, à reflechir +à comment solutionner certains problemes, ce n'est pas parce que je suis payé +pour le faire, mais bel et bien parce que je me sens bien lorsque je le fais, +parce que j'y trouve un équilibre et une utilité.</p> +<p>Alors que je ne trouvais plus cet équilibre dans mon travail, j'ai choisi d'en +changer, mais il n'empèche que je continue à avoir des rèves d'un +monde meilleur, dans lequel l'informatique a sa place. Juste à voir les +discussions (ux, sécurité informatique, décentralisation, architecture +logicielle) que j'ai pu avoir ce weekend, il n'y a pas l'ombre d'un doute !</p> +<p>Jusqu'ici je me suis dit que je devais choisir. J'ai pensé naivement +que je ne pouvais pas être <em>et</em> un brasseur <em>et</em> un developpeur, mais la +réalité c'est que c'est exactement ce que je suis: les deux.</p> +<p>Je ne suis pas pour autant dupe sur le temps necessaire à lancer une activité +brassicole, il va falloir fournir de l'énergie et avancer sur le projet, mais +il n'empèche que même si je décide de faire de la bière mon metier, mes +passions pour le reste sont bien vivantes.</p> +<p>Bref, merci sudweb pour m'avoir accompagné dans ces reflexions, à l'année +prochaine, je ramène des futs ?</p>Avez vous confiance en SSL?2016-03-25T00:00:00+01:002016-03-25T00:00:00+01:00Alexis Métaireautag: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'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop …</p><p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop, c'est parti pour:</p> +<ul> +<li>un tour d'horizon du fonctionnement de SSl</li> +<li>quelques moyens contourner cette "protection" en faisant une attaque en pratique</li> +<li>un tour des solutions existantes actuellement et de pourquoi je ne les trouve + pas vraiment satisfaisantes.</li> +</ul> +<h2>Comment fonctionne SSL?</h2> +<p>Pour expliquer les problèmes de SSL, j'ai d'abord besoin d'expliquer comment +tout ça fonctionne.</p> +<p>SSL repose sur l'utilisation de certificats, qui sont générés par des autorités +de certification (<em>Certificate Authority</em> que je nomme <em>CA</em> dans la suite de +l'article).</p> +<p>Les certificats SSL permettent deux 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 même.</li> +<li>De garantir que le site sur lequel vous vous connectez est bien celui que + vous imaginez.</li> +</ul> +<p>Le navigateur, lors d'une visite d'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>CA</em> en qui il a confiance.</p> +<p>Imaginons maintenant qu'une des <em>CA</em> essaye de savoir ce qui s'échange entre +mon navigateur et le site de ma banque (protégé par SSL). Comment cela se +passerait il ?</p> +<p>N'importe quel <em>CA</em> peut donc générer des certificats pour n'importe quel site, +et le navigateur vérifierait, lui, que le certificat a bien été généré par une +<em>CA</em>.</p> +<p>Tout cela ne poserait pas de soucis si les <em>CA</em> étaient gérés de manière fiable, +mais il s'agit d'un travail compliqué, et certains <em>CA</em> ont par le passé montré +des faiblesses.</p> +<p>Par exemple, <a href="https://en.wikipedia.org/wiki/DigiNotar">DigiNotar</a> (un <em>CA</em> des Pays-Bas) +a été compromise et les attaquant.e.s ont pu générer des certificats SSL +frauduleux, ce qui leur a permis d'attaquer des sites tels que Facebook ou GMail.</p> +<p>Vous pouvez retrouver une liste des risques et menaces autour des <em>CA</em> <a href="http://wiki.cacert.org/Risk/History">sur le +wiki de CACert</a>.</p> +<h2>Attaque de l'homme du milieu avec SSL</h2> +<p>A force de dire que c'était très facile à faire, j'ai eu envie d'essayer +d'espionner des connections protégées par SSL, et effectivement c'est +carrément flippant tellement c'est simple.</p> +<p>En l'espace de quelques minutes, il est possible de faire une <em>attaque de +l'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'ensemble du trafic SSL, j'ai simplement eu à lancer quelques +commandes et avoir un <em>CA</em> dans lequel le navigateur de la victime a confiance. +Je l'ai ajouté dans le navigateur cible pour simuler que je l'avais déjà +(c'est le cas si un des 1200 CA se fait pirater, ce qui me semble une surface +d'attaque assez large).</p> +<p>Je les colle ici si ça vous intéresse:</p> +<div class="highlight"><pre><span></span>$ sudo aptitude install mitmproxy +$ mitm-proxy -T --host +</pre></div> + + +<p>Il faut faire croire à votre victime que vous êtes la passerelle vers +l'extérieur et à la passerelle que vous êtes la victime:</p> +<div class="highlight"><pre><span></span>arpspoof -i wlan0 -t victime gateway +arpspoof -i wlan0 -t gateway victime +</pre></div> + + +<p>Puis dire à notre fausse passerelle de rediriger le trafic des ports 80 et 443 +vers notre proxy:</p> +<div class="highlight"><pre><span></span>sudo sysctl -w net.ipv4.ip_forward<span class="o">=</span><span class="m">1</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">443</span> -j REDIRECT --to-port <span class="m">4443</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">80</span> -j REDIRECT --to-port <span class="m">4443</span> +</pre></div> + + +<p>Et paf, <strong>on voit tout ce qui passe entre la machine et le serveur SSL</strong>. On peut +d'ailleurs même imaginer faire tourner ces quelques commandes sur un +raspberry pi, pour aller encore plus vite…</p> +<h3>Key-pinning dans les navigateurs</h3> +<p>Actuellement, n'importe quel <em>CA</em> peut générer des certificats pour +n'importe quel site, et c'est en grande partie ce qui pose souci. Une des +manières de faire évoluer la situation est d'épingler les certificats de +certains sites directement dans les 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>HTTP Public Key Pinning (HPKP)</h3> +<p><a href="https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning"><em>HTTP Public Key Pinning</em></a> +est également une solution de <em>pinning</em> qui permet d'établir une confiance lors +de la première connexion avec le site. C'est ce qu'on appelle du <em>Trust on First +Use</em> ou <em>TOFU</em>.</p> +<p>Le navigateur va alors mettre ces informations dans un cache et vérifiera que +les certificats correspondent bien lors des prochaines visites.</p> +<p><em>HPKP</em> est disponible dans Firefox depuis Janvier 2015 et dans Chrome +depuis Octobre 2015.</p> +<h3>Certificate transparency: des journaux 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 SSL certificates open to scrutiny by +domain owners, CAs, and domain users.</p> +<p>-- <a href="https://www.certificate-transparency.org/what-is-ct">Certificate Transparency</a></p> +</blockquote> +<p>Autrement dit, avec ce système les <em>CA</em> doivent rendre public le fait qu'ils +aient signé de nouveaux certificats intermédiaires. La signature est ajoutée à +un journal sur lequel il n'est possible que d'écrire.</p> +<p>Les navigateurs vont alors vérifier que les certificats utilisés sont bien des +certificats qui ont été ajoutés au journal.</p> +<p>Ici, toute l'intelligence est dans la vérification de ces journaux, qui +permettent donc de valider/invalider des certificats racines ou intermédiaires.</p> +<p>Il me semble donc qu'il serait possible d'ajouter un certificat frauduleux le +temps d'une attaque (et celui ci serait détecté et supprimé ensuite).</p> +<p><em>Certificate-Transparency</em> n'est donc pas une solution contre une écoute +globale mise en place par les gouvernements par exemple.</p> +<p>Si vous lisez bien l'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 écrite.</p> +<h3>DANE + DNSSEC</h3> +<blockquote> +<p>The DANE working group has developed a framework for securely +retrieving keying information from the DNS [RFC6698]. This +framework allows secure storing and looking up server public key +information in the DNS. 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 service.</p> +<p>-- <a href="https://datatracker.ietf.org/wg/dane/charter/">Dane WG</a></p> +</blockquote> +<p>Une autre solution est appelée "DANE" et repose par dessus le protocole +<em>DNSSEC</em>.</p> +<p>Je connais assez mal <em>DNSSEC</em> donc j'ai passé un peu de temps à lire des +documents. L'impression finale que ça me laisse est que le problème est +exactement le même que pour SSL: 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 confiance.</p> +<blockquote> +<p>Secure DNS (DNSSEC) uses cryptographic digital signatures signed with a +trusted public key certificate to determine the authenticity of data. +-- https://en.wikipedia.org/wiki/DNS_spoofing</p> +</blockquote> +<p>Et aussi:</p> +<blockquote> +<p>It is widely believed[1] that securing the DNS is critically important for +securing the Internet as a whole, but deployment of DNSSEC specifically has +been hampered (As of 22 January 2010) by several difficulties:</p> +<ul> +<li>The need to design a backward-compatible standard that can scale to the + size of the Internet</li> +<li>Prevention of "zone enumeration" (see below) where desired</li> +<li>Deployment of DNSSEC implementations across a wide variety of DNS servers + and resolvers (clients)</li> +<li>Disagreement among implementers over who should own the top-level domain + root keys Overcoming the perceived complexity of DNSSEC and DNSSEC + deployment</li> +</ul> +</blockquote> +<h2>Solutions basées sur la blockchain</h2> +<p>Une dernière piste semble être l'utilisation de la <em>blockchain</em> pour distribuer +des clés par site.</p> +<p>La solution <em>DNSChain</em> me paraissait tout d'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'ont fait changer d'avis.</p> +<p>Reste encore la piste de <em>Namecoin Control</em> que je n'ai pas encore creusée. +Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la +bienvenue sur ces sujets!</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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><p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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, away from news and +agitation.</p> +<p>Working remotely is sometimes hard. Hard because you need to at the same time +be in the discussions channels and work on the interesting projects. A real +myth.</p> +<p>In practice, I'm really bad at multi-tasking. I tried a few times the <em>Pomodoro</em> +technique, which forces me to focus on a task for 25mn, but this split of my day +into slices of 25mn breaks my natural flow.</p> +<p>So, what do I need? I tried to change my tools, it helped a bit. Still, I'm not +focused like I would like to be.</p> +<p>Maybe that's just me who needs some more persuasion over myself, but the best +way I found to work is to unplug the cable. Literally. At work, at some point I +was using a RJ45 cable to connect to the Internet. When I wanted to work on +something, I could just unplug this cable.</p> +<p>And that's amazing how you find yourself in the process to &quot;check&quot; +something on the web. Mails, irc… well, you got the idea. You're litterally, +without even noticing, switching to your browser an opening a new tab…</p> +<p>Of course, that Web isn't filled only with lolcats and twitter messages +(even if I would <strong>love</strong> to see a pie chart with the repartition of lolcats +VS the rest of the web's content), so sometimes you need some precious bit of +information that's there. Fair enough. plug the cable, do what you <strong>need</strong> to +do, and unplug. Alexis, unplug!</p> +<p>It also helps to have some fair bit of documentation available directly on my +machine (I used to have the python docs, I should get it back!)</p> +<p>I'm feeling adventurous, so I'll try something new starting tomorrow, and I'll +report back in here my findings. Here's the challenge:</p> +<ul class="simple"> +<li><strong>Check emails only once a day</strong>. Do <strong>not</strong> do it in the morning, before +working, to keep my mind clear. I would say at 2pm (after lunch). +(This doesn't mean I will not send mails tho)</li> +<li>Stay away from the Internet during the morning. I'll not connect if I don't +need to.</li> +</ul> +<p>Let's see how it goes :)</p> +Retours sur un atelier ZeroNet2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag: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'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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 …</p><p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> +dans les locaux de l'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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'éviter la censure.</p> +<p>Avant toute autre chose, merci énormément à l'équipe de la bibliothèque de +l'INSA pour l'organisation de cet évènement qui à une réelle portée politique.</p> +<h2>Un peu d'histoire</h2> +<p>Il me semble que Tim Bernes Lee (l'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 accéder.</p> +<p>Avec ce fonctionnement, impossible alors d'accéder à des sites si leur auteur +n'est pas en ligne. Qu'à cela ne tienne, on s'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'utilisateurs des sites.</p> +<h2>Un Web 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'une visite d'un +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 site.</li> +<li>Vous validez que les fichiers servis sont bien les bons (en vérifiant la + signature attachée).</li> +</ol> +<p>N'importe quel visiteur devient alors un <em>pair</em>, qui sert le site aux autres +visiteurs.</p> +<p>Parmi les nombreux avantages de cette approche, je note particulièrement que:</p> +<ul> +<li>Il est très difficile de censurer un site — Il est sur l'ensemble des machines + des visiteurs.</li> +<li>Les attaques par <em>fingerprinting</em> sont impossibles: le navigateur Web se + connecte à un serveur <em>proxy</em> local.</li> +<li>Vous détenez directement vos données et (par design) ne les donnez pas à des + silos (Facebook, Google, etc.)</li> +</ul> +<p>Si vous êtes interessés par une démonstration rapide, j'ai enregistré une vidéo +de 10 minutes où je parle en anglais avec une voix très grave.</p> +<video controls="" src="http://alexis.notmyidea.org/zeronet.webm" width=800></video> + +<h2>Atelier</h2> +<p>Pour l'atelier, j'ai choisi de faire une présentation rapide du projet (<a href="{filename}/static/zeronet-presentation-fr.pdf">j'ai +traduit les slides</a> anglais +pour l'occasion — <a href="https://docs.google.com/presentation/d/158C_-V1ueNaaKHMBMBgGOVhunb9xrXzB3hC_g1N53c0/edit?usp=sharing">accès aux sources</a>) +avant d'installer ZeroNet sur les machines et de l'utiliser pour publier un +site.</p> +<h3>Partager sur le réseau 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'avais pas prévu le coup.</p> +<p>Voici donc comment faire pour contourner le 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'est packagé pour debian pour l'instant</a>) + J'ai choisi d'installer <a href="http://erdgeist.org/arts/software/opentracker/#build-instructions">OpenTracker</a></li> +<li>Ensuite lancer ZeroNet avec des options spécifiques.</li> +</ol> +<div class="highlight"><pre><span></span>$ python zeronet.py --trackers udp://localhost:6969 --ip_external <span class="m">192</span>.168.43.207 +$ python zeronet.py --trackers udp://192.168.43.207:6969 --ip_external <span class="m">192</span>.168.43.172 +</pre></div> + + +<p>Il est nécessaire de spécifier l'adresse IP externe que chaque nœud expose pour +éviter qu'elle n'essaye d'aller la trouver par elle même: nous voulons l'adresse +du réseau local, et non pas l'adresse internet.</p> +<p>La prochaine fois je tenterais de venir avec un HotSpot Wifi et un tracker +BitTorrent dans la poche!</p> +<h2>Questions / Réponses</h2> +<p>Il y avait quelques questions intéressantes auxquelles je n'ai pas toujours su +répondre sur le moment. Après quelques recherches, je rajoute des détails ici.</p> +<h3>Torrent + Tor = brèche de sécu ?</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'utilisation de BitTorrent par dessus Tor</a>.</p> +<blockquote> +<p>Dans certains cas, certains clients torrents (uTorrent, BitSpirit, etc) +écrivent directement votre adresse IP dans l'information qui est envoyée +au tracker et/ou aux autres pairs. +— 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'est pas le cas de ZeroNet</a>, ce qui évacue le souci.</p> +<h3>ZeroMail, c'est lent non ?</h3> +<p>Une des applications de démo, <em>ZeroMail</em>, propose un mécanisme qui permet de +s'envoyer des messages chiffrés sur un réseau pair à pair. L'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 siens.</p> +<p>Cela permet de ne <strong>pas</strong> fuiter de méta-données, <a href="{filename}../crypto/2015.05.pgp-problemes.rst">à l'inverse de PGP</a>.</p> +<p>Je n'ai en fait pas de réponse claire à donner à cette question: l'auteur de +ZeroNet me disait que 10MB (la limite de taille d'un site, par défaut) +correspondait à beaucoup de place pour stocker des messages, et qu'il était +possible de supprimer les anciens messages une fois qu'ils sont lus par 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'un +utilisateur peut recevoir.</p> +<p>Je vois plusieurs problèmes avec le design actuel de ZeroMail (il me semble +assez facile d'y faire un déni de service par exemple). A creuser.</p> +<h3>Comment héberger des très gros sites ?</h3> +<p>Par exemple, comment faire pour héberger Wikipedia ?</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 demande)</p> +<h3>Est-ce qu'on à vraiment besoin d'un tracker ?</h3> +<p>Le support d'une DHT <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, +mais pour l'instant pas encore implémenté. L'utilisation de la DHT BitTorrent +n'est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas UDP</a>.</p>L'horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-02:/lhorizon.html<blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont …</p><blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont +eu lieu juste avant une descente de cave en Bourgogne avec Tarek pour +y déguster quelques saveurs de vins différentes.</p> +<p>Quatre ans plus tard, je me retrouve à coder sur Daybed, mon petit projet +perso, devenu <a class="reference external" href="http://kinto.readthedocs.org/">Kinto</a> avec une équipe de +personnes plus talentueuses et sympathiques les unes que les autres (Niko, +Rémy, Mat, si vous me lisez…).</p> +<p>Mozilla a bien évolué en quelques années: les petits bureaux ou j'avais atterri +se sont transformés en palace où il est possible d'accueillir des membres de la +communauté du logiciel libre de manière quotidienne.</p> +<p>De 14 personnes dans les bureaux Parisiens, nous sommes passés à une 40aine (et +de ~500 salariés à 1100 dans le monde).</p> +<p>Grandir autant en si peu de temps est un challenge difficile à tenir, qui +nécessite des réorganisations et bien souvent dans une structure de cette +taille, de la hiérarchisation. En 4 ans j'ai eu au moins 5 changements de +supérieurs, pour finalement arriver à une situation plutôt convenable (mais +quand même !)</p> +<p>J'ai choisi de rejoindre Mozilla parce que j'ai besoin de causes à défendre, +qui me saisissent et qui me guident. Aujourd'hui, une des visions qui m'anime, +c'est celle que d'autres ont déjà ouverte: celle de données et de vie privée +qui sont rendues à leurs utilisateurs.</p> +<p>Et je veux faire en sorte de réaliser ces «rêves d'un monde meilleur», ce qui +veut dire pour moi qu'il est temps de partir vers des horizons plus propices +à cette vision.</p> +<p>Lesquels ? Cela reste à construire (mais je vous le dis, y'a du Kinto dedans !)</p> +<div class="section" id="la-suite"> +<h2>La suite ?</h2> +<p>Sans m'étaler, je veux prendre du temps pour quelques projets autour du +stockage de données (via Kinto), de l'auto défense numérique (via des +formations) et de la fabrication de bière artisanale (parce que bon, on se +refait pas !)</p> +<p>Évidemment, plein d'envies diverses et variées, envie de me balader un peu et +d'expérimenter des choses collectivement...</p> +<p>On se recroisera surement :)</p> +</div> +Let's Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début …</p><blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début Décembre, la nouvelle <em>autorité de certification</em> Let's Encrypt +est passée en version <em>Beta</em>. Les certificats SSL sont un moyen de 1. chiffrer la +communication entre votre navigateur et le serveur et 2. un moyen d'être sur +que le site Web auquel vous accédez est celui auquel vous pensez vous connecter +(pour éviter des <a class="reference external" href="https://fr.wikipedia.org/wiki/Attaque_de_l'homme_du_milieu">attaques de l'homme du milieu</a>).</p> +<p>Jusqu'à maintenant, il était nécessaire de payer une entreprise pour faire en +sorte d'avoir des certificats qui évitent d'avoir ce genre d'erreurs dans vos +navigateurs:</p> +<img alt="Message de firefox lorsque une connexion n'est pas sécurisée." src="{filename}/static/unsecure-connection.png" /> +<p>Maintenant, grâce à Let's Encrypt il est possible d'avoir des certificats SSL +<strong>gratuits</strong>, ce qui représente un grand pas en avant pour la sécurité de nos +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 SSL valides avec Let's Encrypt et +le répartiteur de charge <a class="reference external" href="http://www.haproxy.org/">HAProxy</a>.</p> +<p>Je me suis basé pour cet article sur d'<a class="reference external" href="https://blog.infomee.fr/p/letsencrypt-haproxy">autres</a> <a class="reference external" 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 d'information.</p> +<div class="section" id="validation-des-domaines-par-let-s-encrypt"> +<h2>Validation des domaines par Let's Encrypt</h2> +<p>Je vous passe les détails d'installation du client de Let's Encrypt, qui sont +<a class="reference external" 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 à:</p> +<pre class="literal-block"> +letsencrypt-auto certonly --renew-by-default +--webroot -w /home/www/letsencrypt-requests/ \ +-d hurl.kinto-storage.org \ +-d forums.kinto-storage.org +</pre> +<p>Le <em>webroot</em> est l'endroit ou les preuves de détention du domaine vont être +déposées.</p> +<p>Lorsque les serveurs de Let's Encrypt vont vouloir vérifier que vous êtes bien +à l'origine des demandes de certificats, ils vont envoyer une requête HTTP sur +<tt class="docutils literal"><span class="pre">http://domaine.org/.well-known/acme-challenge</span></tt>, ou il voudra trouver des +informations qu'il aura généré via la commande <tt class="docutils literal"><span class="pre">letsencrypt-auto</span></tt>.</p> +<p>J'ai choisi de faire une règle dans haproxy pour diriger toutes les requêtes +avec le chemin <tt class="docutils literal"><span class="pre">.well-known/acme-challenge</span></tt> vers un <em>backend</em> nginx qui sert +des fichiers statiques (ceux contenus dans +<tt class="docutils literal"><span class="pre">/home/www/letsencrypt-requests/</span></tt>).</p> +<p>Voici la section de la configuration de HAProxy (et <a class="reference external" href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L63-L72">la configuration +complete</a> +si ça peut être utile):</p> +<pre class="literal-block"> +frontend http + bind 0.0.0.0:80 + mode http + default_backend nginx_server + + acl letsencrypt_check path_beg /.well-known/acme-challenge + use_backend letsencrypt_backend if letsencrypt_check + + redirect scheme https code 301 if !{ ssl_fc } !letsencrypt_check + +backend letsencrypt_backend + http-request set-header Host letsencrypt.requests + dispatch 127.0.0.1:8000 +</pre> +<p>Et celle de NGINX:</p> +<pre class="literal-block"> +server { + listen 8000; + server_name letsencrypt.requests; + root /home/www/letsencrypt-requests; +} +</pre> +</div> +<div class="section" id="installation-des-certificats-dans-haproxy"> +<h2>Installation des certificats dans HAProxy</h2> +<p>Vos certificats SSL devraient être générés dans <tt class="docutils literal">/etc/letsencrypt/live</tt>, mais +ils ne sont pas au format attendu par haproxy. Rien de grave, la commande +suivant convertit l'ensemble des certificats en une version compatible avec +HAProxy:</p> +<pre class="literal-block"> +cat /etc/letsencrypt/live/domaine.org/privkey.pem /etc/letsencrypt/live/domaine.org/fullchain.pem &gt; /etc/ssl/letsencrypt/domaine.org.pem +</pre> +<p>Et ensuite dans la configuration de haproxy, pour le (nouveau) <em>frontend</em> https:</p> +<pre class="literal-block"> +bind 0.0.0.0:443 ssl no-sslv3 crt /etc/ssl/letsencrypt +</pre> +<p>Faites bien attention à avoir un <em>frontend</em> <cite>https</cite> pour tous vos sites en HTTPS. +<a class="reference external" 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 !</p> +</div> +<div class="section" id="automatisation"> +<h2>Automatisation</h2> +<p>Pour automatiser un peu tout ça, j'ai choisi de faire ça comme suit:</p> +<ul class="simple"> +<li>Un fichier domaine dans <tt class="docutils literal">letsencrypt/domains/domain.org</tt> qui contient le script <tt class="docutils literal">letsencrypt</tt>.</li> +<li>Un fichier d'installation de certificats dans +<tt class="docutils literal"><span class="pre">letsencrypt/install-certs.sh</span></tt> qui s'occupe d'installer les certificats +déjà générés.</li> +</ul> +<p>Et voila ! <a class="reference external" href="https://github.com/almet/infra/">Le tout est dans un dépot github</a>, si jamais ça peut vous servir, tant mieux !</p> +</div> +Ateliers d'autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de …</li></ul></blockquote><p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, +envers mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins +pour rendre le déchiffrement des messages plus longue, &quot;noyer le +poisson&quot;.</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="http://blog.notmyidea.org/chiffrement.html">Chiffrement</a></p> +</blockquote> +<p>J'ai mis un peu de temps à mettre le pied à l'étrier, mais je ressors +finalement du premier atelier que j'ai co-animé avec geb, auprès d'un public de +journalistes.</p> +<p>Pour cette première édition l'idée était à la fois d'aller à la rencontre d'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'autodéfense numérique.</p> +<p>L'objectif pour ce premier atelier était de:</p> +<ol class="arabic simple"> +<li>Échanger autour des besoins et <strong>faire ressortir des histoires</strong> ou le manque +d'outillage / connaissances à posé problème, dans des situations concrètes;</li> +<li>Se rendre compte des &quot;conduites à risque&quot;, <strong>faire peur</strong> aux personnes formées +pour qu'elles se rendent compte de l'état actuel des 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 appréhender.</li> +</ol> +<div class="section" id="faire-ressortir-les-problemes"> +<h2>1. Faire ressortir les 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 &quot;Groupes d'Interview Mutuels&quot;, +ou &quot;GIM&quot;:</p> +<blockquote class="epigraph"> +<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é vécu.</p> +<p class="attribution">&mdash;«<a class="reference external" href="http://www.scoplepave.org/pour-s-ecouter">Pour s'écouter</a>», SCOP Le Pavé.</p> +</blockquote> +<p>De ces <em>GIMs</em> nous avons pu ressortir quelques histoires, gravitant autour de:</p> +<ul class="simple"> +<li><strong>La protection des sources (d'information)</strong>: Comment faire pour aider +quelqu'un à faire &quot;fuiter&quot; des données depuis l'intérieur d'une entreprise ?</li> +<li><strong>Le chiffrement de ses données</strong>: Comment éviter de faire &quot;fuiter&quot; des données +importantes lors d'une perquisition de matériel ?</li> +</ul> +</div> +<div class="section" id="faire-peur"> +<h2>2. Faire 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'accéder à certaines données. <a class="reference external" href="http://blog.barbayellow.com/">Grégoire</a> m'avait conseillé quelques petites accroches +qui ont ma foi bien marché:</p> +<p>J'ai demandé aux présent.e.s de:</p> +<ul class="simple"> +<li>donner leur mot de passe à voix haute devant les autres: a priori personne ne +le fera;</li> +<li>venir se connecter à leur compte email depuis mon ordinateur. J'ai piégé une +personne, qui est venu pour taper son mot de passe.</li> +</ul> +<p>Cela à été un bon moyen de parler de l'importance des traces que l'on peut +laisser sur un ordinateur, et de la confiance qu'il faut avoir dans le matériel +que l'on utilise, à fortiori si ce ne sont pas les vôtres.</p> +<p>Pour continuer à leur faire peur, après une brève explication de ce qu'est SSL +nous avons montré comment il était facile de scruter le réseau à la recherche +de mots de passe en clair.</p> +</div> +<div class="section" id="proposer-des-solutions-concretes"> +<h2>3. Proposer des solutions concrêtes</h2> +<p>Une fois que tout le monde avait pleinement pris sonscience des problématiques +et n'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 attentes:</p> +<ul class="simple"> +<li>On a expliqué ce qu'était <a class="reference external" href="https://tails.boum.org">Tails</a>, et comment +l'utiliser et le dupliquer.</li> +<li>On a pu faire un tour des outils existants sur Tails, notamment autour de +l'<em>anonymisation</em> de fichiers et la suppression effective de contenus.</li> +<li>Certaines personnes ont pu créer une clé tails avec la persistance de +configurée.</li> +<li>Nous nous sommes connectés au réseau <a class="reference external" href="https://www.torproject.org">Tor</a> et testé +que nos adresses IP changeaient bien à la demande.</li> +<li>Nous avons utilisé <a class="reference external" href="https://crypto.cat">CryptoCat</a> par dessus Tor, afin de +voir comment avoir une conversation confidentielle dans laquelle il est +possible d'échanger des fichiers.</li> +</ul> +</div> +<div class="section" id="retours"> +<h2>Retours</h2> +<p>D'une manière générale, pour une formation de trois heures et demi, je suis +assez content de l'exercice, et de l'ensemble des sujets que nous avons pu +couvrir. Il y a beaucoup de place pour l'amélioration, notamment en amont (j'avais +par exemple oublié d'amener avec moi suffisamment de clés USB pour utiliser +Tails).</p> +<p>La plupart des retours qu'on a pu avoir jusqu'à maintenant sont positifs, et il +y a l'envie d'aller plus loin sur l'ensemble de ces sujets.</p> +</div> +<div class="section" id="la-suite"> +<h2>La suite</h2> +<p>Il y a beaucoup de sujets que nous n'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'après-midi par +exemple).</p> +<p>J'ai choisi volontairement de ne pas aborder le chiffrement des messages via +PGP parce que <a class="reference external" href="https://blog.notmyidea.org/les-problemes-de-pgp.html">je pense que la protection que ce média propose n'est pas +suffisante</a>, mais je suis en train de +revenir sur ma décision: il pourrait être utile de présenter l'outil, à minima, +en insistant sur certaines de ses faiblesses.</p> +<p>Un compte twitter à été créé recemment autour des crypto-party à Rennes, si +vous êtes interessés, <a class="reference external" href="https://twitter.com/CryptoPartyRNS">allez jeter un coup d'œil</a>!</p> +<p>Je n'ai pas trouvé de ressources disponibles par rapport à des plans de +formation sur le sujet, j'ai donc décidé de publier les nôtres, afin de +co-construire avec d'autres des plans de formation.</p> +<p>Ils sont pour l'instant disponibles <a class="reference external" href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The Docs</a>. Tous les retours +sont évidemment les bienvenus !</p> +</div> +Rencontres python francophones, 20152015-11-02T00:00:00+01:002015-11-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2015-11-02:/rencontres-python-francophones-2015.html<p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation …</p><p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation était vraiment impressionnante (merci +, si vous me lisez !). Et puis comme toujours l'occasion de recroiser quelques +copains, et d'en découvrir quelques autres... J'en ai profité pour parler de +Kinto (voici d'ailleurs <a class="reference external" href="http://alexis.notmyidea.org/kinto-pycon/">les slides de la présentation que j'ai faite</a>).</p> +<p>Parmis les conférences qui m'ont marquées, je vous conseille <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-hospital-des-tests-en-prod.html">celle de Benoit +Bryon, sur Hospital</a>, qui parle de +heartbeat, ou de comment tester vos projets en prod, et celle <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-geoalchemy.html">sur Geo Alchemy, +par Éric Lemoine</a>. Et bien sur, <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-cliquet.html">celle +de Mathieu Leplatre sur Cliquet</a>, le +toolkit qui rassemble les bonnes pratiques que nous souhaitons mettre en avant +chez Mozilla services, mais là, je suis tout sauf impartial !</p> +<p>Sinon, il peut être interessant de jeter un coup d'oeil au <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-table-ronde-diversite.html">compte rendu de la +table ronde sur la diversité</a>, si c'est un sujet qui vous +touche. Encore beaucoup de choses à faire sur le sujet, bien sur, mais cette table ronde +était un pas nécessaire dans la bonne direction. Un groupe de travail sur le +sujet est en train de se constituer au sein de l'association.</p> +<p>L'ensemble des notes que j'ai pu prendre sont disponibles dans la section <a class="reference external" href="http://blog.notmyidea.org/category/pyconfr2015.html">PyconFR 2015</a>.</p> +PyconFR 2015 — Assemblée générale2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-assemblee-generale.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes + Marseille +Support pour 2 Django Carrots. +Par rapport au mentoring, très peu de retours, peut etre de nouvelles choses +à faire.</p> +<p>FOSDEM 2015 était complet. Il y avait une salle python tojours pleine. +Dsicussions sur la diversité.</p> +</div> +<div class="section" id="futur"> +<h2>Futur</h2> +<p>Amandine propose d'organiser des soirées à NUMA l'an prochain. +Global code retreat: participation +Migrer le serveur de l'AFPY +Reboot des status: nos pratiques ne sont pas en ligne avec nos status. +Mise en place de mentoring pour python.</p> +<div class="section" id="status"> +<h3>Status</h3> +<p>Comité directeur renouvelé par tiers. Il est composé de 18 personnes. Les +discussions qui sont dans le CD n'en sortent pas, et les discussions sont donc +effectuées en priuvées.</p> +<p>L'idée actuelle serait de réduire le CD de 18 à 9 personnes. Tout le travail +serait fait en dehors du CD. Il est possible de mettre en place un groupe de +travail pour travailler sur l'évolution de la charte.</p> +<p>Il faut faire évoluer les status: ils ne sont pas actuellement bien faits par +rapport à notre utilisation.</p> +</div> +</div> +PyconFR 2015 — Hospital - des tests en prod2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-hospital-des-tests-en-prod.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et +envoi de fichiers).</p> +<p>Pour des applications plus complexes, il y a beaucoup de choses à tester (base +de données, cache, email, etc). Beaucoup de parties sont utiles: reverse +proxy, django, base de données etc.</p> +<p>Lors d'un déploiement, comment faire pour vérifier que tout tourne lorsque tout +est déployé ?</p> +<div class="section" id="comment-faire"> +<h2>Comment faire ?</h2> +<ul class="simple"> +<li>Les tests permettent de tester hors sol.</li> +<li>Le provisionning permet de valider que tout tourne correctement, mais</li> +<li>simplement au démarrage. Les pannes ne sont pas détectées.</li> +<li>Le logging va permettre de detecter les erreurs, mais trop tard.</li> +<li>Le monitoring permet d'avoir une vue de l'exterieur.</li> +</ul> +<p>Hostpital propose de faire des assertions sur la configuration, +l'environnement, <em>en cours de fonctionnement</em>. Ce sont les developeurs qui +ajoutent ces assertions.</p> +<p>Cela peut servir à valider un déploiement, pour etre rassuré une fois que le +déploiement effectué. Cela peut aussi service à surveiller un service et +diagnostiquer les problèmes.</p> +</div> +<div class="section" id="hospital"> +<h2>Hospital</h2> +<dl class="docutils"> +<dt>::</dt> +<dd>pip install hospital</dd> +</dl> +<p>Hospital est un outil en python. On définit des tests, de la même manière que +l'on définit des tests unitaires. On fait des assertions, comme pour les tests +unitaires. Hospital propose des helpers pour les cas courants: +<cite>assert_http_response</cite> ou <cite>assert_ping</cite>.</p> +<p>La vue est une vue de l'intérieur. La différence avec le monitoring est que +l'on teste la connectivité entre les services (exemple d'une requete +elasticsearch qui échoue depuis un service django).</p> +<p>Pour la supervision, les healthchecks sont lancés avec une ligne de commande +<cite>hospital-cli</cite>. Il est possible de lancer également ces tests avec nose ou +py.test.</p> +<p>Il est aussi possible de faire le monitoring avec une API HTTP <cite>hospital +serve</cite>.</p> +<div class="section" id="les-lacunes-de-hospital"> +<h3>Les lacunes de hospital</h3> +<p>Les healthchecks sont fait actuellement en synchrone. Cela peut prendre du +temps. Il pourrait etre interessant de lancer des taches de manière distribuée +/ en paralelle.</p> +<p>Il pourrait etre utile de faire la distinction entre les smoketests et les +diagnostiques: les premiers sont des petits checks qui permettent de dire si ça +marche, de manière très simple. De l'autre coté, les diagnostiques seraient eux +plus fins.</p> +</div> +</div> +<div class="section" id="wrap-up"> +<h2>Wrap up</h2> +<p>Validez votre configuration, la connectivité avec les services externes. Faites +des tests souvent !</p> +</div> +PyconFR 2015 — We don't need your loop2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-we-dont-need-your-loop.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer comment atteindre le resultat.</p> +<p>En python, par exemple, il vaut mieux utiliser <cite>sum</cite> plutôt que de faire +l'addition nous même (pour faire une addition des elements d'une liste).</p> +<p>Actuellement, le compilateur python est lent si on utilise numpy.sum sur des +matrices complexes.</p> +<div class="section" id="comment-aller-plus-vite"> +<h2>Comment aller plus vite?</h2> +<p>Cython est assez compliqué, il faut savoir ce que l'on fait pour optimiser et +écrire du bon code Cython.</p> +<p>Avec pythran, l'intelligence est dans le compilateur, qui permet d'écrire +notemment des boucles correctement.</p> +<p>En donnant plus d'informaitons au compilateur, plutôt que de faire des boucles, +cela lui permet d'avoir un contexte qui lui permet d'optimiser le code.</p> +<p>Par contre, cela veut dire que plus de connaissances sont necessaire pour lire +le code python.</p> +<p>pythran permet de compiler directement vers du C++ sans avoir à changer son +code de base (python). C'est utile pour du code numpy notemment.</p> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<p>Possible de paralelliser de manière explicite <strong>ou</strong> implicite.</p> +<p><strong>C'est très utile pour les gens qui font du &quot;number crunching&quot;. Est-ce que +c'est utile pour d'autres domaines d'application (Web)?</strong></p> +<p>Pas vraiment. CPython est déjà bien fait pour ces cas d'utilisation.</p> +<p><strong>Est-il possible de lancer pythran sans faire de commentaires ?</strong></p> +<p>C'est possible mais cela ne servira pas à grand chose. Il est necessaire de +connaitre le type des objets qui sont utilisés lors des boucles.</p> +<p><strong>Est-ce que vous songez à un compilateur à la volée ?</strong></p> +<p>De gros efforts ont été faits dernièrement pour diminuer le temps de +compilation. Mais pour une fonction qui renvoie None prends de l'ordre d'une +seconde ou une demi seconde. Ce n'est pas très utile pour un compilateur à la +volée puisqu'il faudrait des gains de perfs supérieurs à cela.</p> +</div> +PyconFR 2015 — Cliquet2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-cliquet.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous demande de faire des APIs, tout +le temps.</p> +<p>Souvent, les mêmes questions sont à l'ordre du jour. Heartbeat, codes +d'erreurs, etc. L'inventaire de tout ce qui est attendu d'une API, au dela de +ce qui est la valeur ajoutée du service.</p> +<p>Définition d'un protocole. Définir une API REST n'est pas aussi évident qu'il +y parait. Il faut définir les formats de JSON, les status, etc.</p> +<p>La réutilisation de certaines protocoles existants était possible (Sync, en +production depuis quelques années).</p> +<p>Réutiliser du code nous permettait et faire un template pour démarrer plus +facilement, pour se concentrer sur le métier de l'API. Puisque les besoins ne +sont pas toujours les mêmes, avoir une boite à outil permet de choisir ce que +l'on souhaite.</p> +</div> +<div class="section" id="protocole"> +<h2>Protocole</h2> +<ul class="simple"> +<li>Création d'un protocole qui respecte les bonnes pratiques. CORS, avoir les +bons codes de status, arrêter de se poser toujours les mêmes questions. +Contrairement à ce qu'on imagine, la spécification HTTP n'est pas si facile +à suivre. Plutôt que d'écrire un document, un toolkit à été créé.</li> +<li>Les ops ont besoin de quelques endpoints: un heartbeat (monitoring) des +endpoints de batch, un endpoint &quot;hello&quot;, pour connaitre le type de service, +ses URLs etc.</li> +<li>La service renvoie toujours un JSON avec la description de l'erreur. Cela +permet d'avoir tout le temps la même gestion des erreurs. Utilisation du +header &quot;backoff&quot; qui permet de demander aux clients d'arreter de faire des +requetes durant une durée spécifée par le serveur.</li> +<li>Pour les resources &quot;REST&quot;, quelques règles sont définies: quel est le format +du JSON, quel est la syntaxe du querystring pour filtrer, ordonner, gérer les +opérations concurentes, etc.</li> +<li>Comment la validation fonctionne ? La pagination ? La définition des +permissions ? Les erreurs.</li> +</ul> +<p>Définir le protocole une seule fois permet de se mettre d'accord avec les Ops. +On ne créé pas une RFC pour l'instant, il faut qu'on valide ce qu'on a fait, +il est necessaire de valider notre approche.</p> +</div> +<div class="section" id="toolkit"> +<h2>Toolkit</h2> +<p>La stack en place est basée sur Pyramid et Cornice. Autre chose aurait pu petre +utilisé. Mais pyramid à été choisi pour son approche simpliste et qui permet de +rajouter de la complexité au fur et à mesure.</p> +<p>Cliquet propose de faire l'ensemble du boilerplate, la lecture du protocole, et +vous permet de créer les backends souhaités.</p> +<p>Il est possible de choisir les methodes HTTP acceptables, les URLs à utiliser +etc. Tweaker l'API est possible, la chose qui reste toujouts stable est le +protocole.</p> +<p>le toolkit vise à faire quelque chose de pluggable. Tout est controllable +depuis la configuration.</p> +<p>Pour le deploiement, cela veut dire que le monitoring est déjà connecté, et il +est possible de changer la configuration depuis un fichier <cite>.ini</cite>.</p> +<p>Il est aussi possible de faire du profiling en ajoutant deux lignes de code, +qui permet de générer des graphs qui permettent d'identifier les goulots +d'étranglement.</p> +</div> +<div class="section" id="microservices"> +<h2>Microservices ?</h2> +<ul class="simple"> +<li>Cliquet apporte une manière standard de surveiller, deployer, configurer des +services.</li> +<li>Il est possible de se focaliser sur la logique de l'application, en faisait +une abstraction des backends, etc.</li> +<li>Le fait de figer l'API permet d'avoir des clients génériques que l'on peu +réutiliser d'une application à l'autre.</li> +</ul> +</div> +<div class="section" id="cliquet-est-utilise-pour"> +<h2>Cliquet est utilisé pour</h2> +<ul class="simple"> +<li>Kinto, un service générique de stpclage de données.</li> +<li>Syncto, un proxy pour Sync en utilisant le protocole.</li> +<li>La liste de lecture, service qui à été shutdown.</li> +</ul> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<ul class="simple"> +<li><strong>Qu'est-ce qui est pluggable ?</strong> Les choix qui sont fait dans cliquet +concernent le protocole. Le toolkit est lui fait de manière &quot;pluggable&quot;. Il +est par exemple possible de changer le backend, l'authentification, le cache +ou les permissions.</li> +<li><strong>Quelles sont les parties non standard? Est-il prévu de representer ça via +une RFC ?</strong> Le seul sujet qui pourrait etre utile dans une RFC serait de +définir les headers attendus pour la validation et l'écriture +concurrentielle. L'ensemble de ce qui est proposé est standard.</li> +<li><strong>Existe-il un client JavaScript, comme pour Kinto ?</strong> Actuellement, non. Par +contre, Kinto.js est prévu pour que la partie commune entre les APIs (le +protocole) peut etre extrait.</li> +</ul> +</div> +PyconFR 2015 — Geoalchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-geoalchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des données qui +representent des objets dans un espace géométrique.</p> +<ul class="simple"> +<li>Il est possible d estocker des ligne,s de polygones, des points. Il y a une +colonne géometrie pour stocker ces données.</li> +<li>Il y a aussi des fonctions qui permettent de travailler sur ces données +(transfomrations, projections, etc).</li> +<li>Indexs géographiques qui permettent de faire des recherches de manière +performante.</li> +</ul> +<div class="section" id="postgis"> +<h2>POSTGIS</h2> +<p>POSTGIS s'appuie sur postres pour offrir des types géographiques, des fonctions +et des indexes (R-Tree), qui permettent de ranger les géométries dans des +&quot;boites englobantes&quot;.</p> +<p>Pour créer une base de données postgis, il faut faire un &quot;create extension +postgis&quot;, ce qui installe tout ce dont on a besoin.</p> +<p>il est possible d'apeller <cite>GEOMETRY(POINT)</cite> par exemple.</p> +<p><cite>ST_GeomFromText('POINT(lat long)')</cite> permet de convertir un point dans un objet +geometrie interne à postgres.</p> +<p><cite>ST_DWithin</cite> permet de trouver les personnes qui sont autour d'un rayon donné.</p> +<p>L'ensemble des fonctions proposées par postgres commencent par <cite>ST_*</cite></p> +</div> +<div class="section" id="sqlalchemy"> +<h2>SQLAlchemy</h2> +<p>Il s'agit d'une bote à outil qui permet de faire des requetes de manière +simple. Il y a une philosophie forte.</p> +<ul class="simple"> +<li>Il ne sohaite pas cacher la base de données</li> +<li>C'est un language pour faire du SQL en python</li> +<li>Rien n'est caché.</li> +<li>Fourni un vocabulaire riche pour générer le SQL</li> +<li>L'objectif est de changer la manière dont on pense à SQL, redonner le gout du +SQL aux developeurs.</li> +</ul> +<p>Deux parties: +- ORM +- CORE</p> +<p>Il est possible d'utiliser simplement le core si l'on sohaite (sans utiliser +l'ORM)</p> +<div class="section" id="core"> +<h3>Core</h3> +<p>Il est possible d'utiliser SQL Alchemy pour générer les tables à l'origine. +Core permet d'utiliser des tables, et d'executer une insertion, depuis python. +Il est possible de representer les requetes avec des methodes chainées +<cite>select().where()</cite> etc.</p> +<p>Le &quot;core&quot; ne fait pas de mapping du tout, il manipule des Tables SQLA +directement.</p> +</div> +<div class="section" id="orm"> +<h3>ORM</h3> +<p>L'ORM fait, lui, du mapping. C'est cette couche que l'on va utiliser dans une +application Web complexe par exemple.</p> +<ul class="simple"> +<li>il est possible de travailler avec une session <cite>Session()</cite> puis on effectue +des opérations et on <cite>commit()</cite>.</li> +</ul> +<div class="section" id="geoalchemy"> +<h4>GeoAlchemy</h4> +<ul class="simple"> +<li>Créé en 2009, pour supporter uniquement postgis.</li> +<li>Depuis, d'autres bases de données (MySQL, Spatialite, MySQL server) etc.</li> +<li>Réécriture depuis grace à la nouvelle API de SQLAlechemy, mais perte du +support d'autres backends.</li> +<li>Finalement, retour sur POSTGIS uniquement, pour évite d'avoir à supporter les +différences de tous les backends.</li> +</ul> +</div> +</div> +</div> +<div class="section" id="features"> +<h2>Features</h2> +<p>Très simple de s'intégrer avec les features de POSTGIS, par exemple en +déclarant une colonne en tant que &quot;Géometrie&quot;.</p> +<p>Exemple: session.query(Lake).filter(Lake.geom.ST_Buffer(2).ST_Area) permet de +lister l'ensemble des lacs avec une aire de 2 au moins.</p> +<p>S'intègre bien avec des services existants (shapely, pyramid, etc).</p> +<p>Utilisation de geojsondumps pour representer des features en geojson.</p> +</div> +<div class="section" id="status"> +<h2>Status</h2> +<p>Le projet est completement documenté sur read the docs. La documentation est +assez complete et solide. Il est intégralement testé, sur differentes versions +de python, sqlalchemy et postgres.</p> +<dl class="docutils"> +<dt>3 ou 4 developeurs actifs sur le projet, ça fonctionne plutôt bien. Pour</dt> +<dd><p class="first">contribuer, il est possible de faire cela sur github.</p> +<p class="last">Slides de la presentation sur <a class="reference external" href="http://erliem.net/talks/pyconfr2015">http://erliem.net/talks/pyconfr2015</a></p> +</dd> +</dl> +<p>Resources:</p> +<ul class="simple"> +<li><a class="reference external" href="https://pypi.python.org/pypi/Shapely">https://pypi.python.org/pypi/Shapely</a> - Manipulation and analysis of geometric +objects in the Cartesian plane.</li> +</ul> +<p>Question:</p> +<ul class="simple"> +<li>Dans les exemples geoalchemy, les données geométriques sont passées sous +forme de chaine. Est-ce normal ? Oui.</li> +<li>Les rasters sont également supportés.</li> +</ul> +</div> +PyconFR 2015 — SQL Alchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-sql-alchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent …</li></ul><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent nos tables, et les liaisons entre les +tables, en utilisant <cite>relationship</cite> (qui à énormement d'attributs).</li> +<li>On définit quelles osnt les clés étrangères entre les tables.</li> +<li>Puis on va définir les attributs qui sont liés entre les tables +(relationship).</li> +<li>Pour définir des relations entre les Tables, il est possible d'utiliser des +chaines de caractère <cite>relationship('OtherTable')</cite>.</li> +<li>La session es tun concept important.</li> +<li>Lire efficacement. Attention à ne pas faire énormement de requetes avec +L'ORM.</li> +</ul> +<p><strong>Performance SQL</strong></p> +<ul class="simple"> +<li>Générer le SQL (python)</li> +<li>Ne pas faire énormement de petites requetes.</li> +</ul> +<p>Il est possible de demander à la session de charger les données qui sont +associées. (avec un joinedload). Par defaut, cela risque de charger +l'ensemble des colonnes.</p> +<p>Pour la générer avec SQLAlchemy, il est possible de faire un +<cite>.query(Table).join(Table).join(Table2).filter_by(field=value)</cite></p> +<p>En pratique, le mieux est de lister clairemnet le nom des tables</p> +<p>2ème partie:</p> +<p>Pour de l'import de données,</p> +<ul class="simple"> +<li>first() fait une requete SQL. A éviter dans les boucles</li> +<li>session.flush() c'est quand la session écrit en base tout ce qui est en cours +dans la transaction. Par default, la session fait un flush avant chaque +requete.</li> +<li>une option backçpopulates mets à jour la liste des documents associés à une +table qui à une foreign key. +backref modifie implicitement la classe associée. Il est recommandé +d'utiliser <cite>back_populates</cite> et non pas <cite>backref</cite>.</li> +<li><cite>subqueryload</cite> permet de générer une requete séparée plutôt qu'une jointure.</li> +</ul> +PyconFR 2015 — Table ronde diversité2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-table-ronde-diversite.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et …</strong></p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et Alexia).</strong></p> +<p><strong>JP — Pourquoi</strong>:On a eu une discussion sur la ML de l'AFPy suite à une décision +de l'afpy de ne pas financer un évènement qui n'était pas ouvert à tous-tes +(restreint aux femmes et personnes trans). Cette décision à été prise +conformément a la charte de l'AFPY qui dit que les evènements promus sont +ouverts à tous. Ce qui veut dire que cela n'inclue pas les évènement exclusifs. +(Je n'ai jamais demandé de financement à l'AFPY. J'ai juste demandé la +diffusion sur la mailing interne de la création de Pyladies Paris. Je ne sais +pas d'où vient cette histoire de financement! Pyladies Paris)</p> +<p>Suite à ça, une modification de la charte à été proposée. Demain matin, la +modification de la charte sera proposée lors de l'AG. Suite à la proposition de +modification, les discussions se sont enchainées, avec des points de vue +divergents. Cette table ronde vient donc dans ce contexte. +I +BD d'introduction: +<a class="reference external" href="http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/">http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/</a></p> +<div class="section" id="tour-de-presentation"> +<h2>Tour de présentation:</h2> +<ul class="simple"> +<li>Laurence directrice de l'école qui accueille d'évènement, docteure en Maths. +Contente de voir que la tendance s'inverse un peu (de plus en plus de filles).</li> +<li>Vivianne, maitre de conférence en informatique à paris sud. Études dans un +milieu assez masculin. Dans le domaine du developpement pour la recherche, ou +des environnements techniques, c'est très masculin. Essaye de voir comment +faire pour que les filles s'intéressent plus a l'informatique.</li> +<li>Amandine Neyrolle, diplomée d'école de commerce (plutot 50% fille/garcon dans +ces fillières). Intégrée le monde de l'informatique par la suite en autodidacte +et formations. Rencontré la créatrice de pyladies et discuté de ces questions.</li> +<li>Laurenne Chelan, organistrice des django girls bdx. Nouvelle dans cet +univers. Travaille dans des musées de science depuis quelques années. L'idée de +dj girs bdx part de l'idée de découvrir le code. Les djangogirls viennent de +berlin, créé par ???.</li> +<li>Alexia Sumois. organisatrice de django girls bdx. Nouvelle dans le milieu du +code. Les conférences d'aujourd'hui on donné envie d'apprendre.</li> +<li>Anna, créatrice de 4ideas. Essaye de faire en sorte que plus de femmes +viennent dans l'IT. En reconversion pro. Choisi ce domaine il ya un an. Trouve +que ce sujet est vraiment extremement important, et sur lequel il est possible +de faire quelque chose, et d'influencer positivement. L'idée étant de +démystifier l'IT, et laisser le choix aux femmes de choisir cette profession.</li> +<li>Jean Phillipe Campguillhem, secrétaire de l'AFPY</li> +</ul> +</div> +<div class="section" id="pourquoi-django-girls"> +<h2>Pourquoi Django Girls ?</h2> +<p><strong>Alexia</strong> — Le déclencheur de cette aventure vient des goodies (!). La décoration +de l'évènement a attiré l'attention et donné envie de creuser.</p> +<p><strong>Laurenne</strong> — C’est pour ça qu’on se pose la question « comment attirer ces +publics, ces personnes-là ? », importance de l’image qu’on renvoie. Ce n’est +pas tant une question de genre, mais d’initié·e·s : on a souvent peur d’entrer +dans ce milieu. Django-girls vise une plus grande bienveillancet Carte de la +convivialité, chaleureux, et facile d'accès pour les débutants. Tout est livré +clé en main, et l'évènement est facile à prendre en main. Le 28 oct à bordeau, +recherche de coachs / sponsors pour l'évènement. +<a class="reference external" href="http://djangogirls.com/bordeaux">http://djangogirls.com/bordeaux</a></p> +<p><strong>Laurence</strong> — Aspect macho présent dans la communication de l’école (pas +forcément explicite). « On a toujours dessiné des symboles de métiers +identifiés par des garçons »</p> +<p><strong>Laurenceu</strong> — Il y a une partie d'inconscient dans l'ensemble de +l'enseignement qui est donné. Il y a peu de candidates qui essayent. Pas +question de discrimination positive puisque cela a des effets indésirables +(communautarisme). La question est tout de meme posée, mais il est impensable +d'accepter des gens grace / a cause de leur genre. L'ambiance change lorsqu'il +y a de la mixité. À la recherche d’idées pour faire venir plus de candidates.</p> +<p><strong>Viviane</strong> — En tant que femme, on reçoit en permanence le message que ce +métier n’est pas fait pour nous. Ces messages ont un impact, le résultat est +que les filles ne vont pas dans les écoles d’informatiques. Il faut aller +convaincre les jeunes filles que c’est aussi fait pour elles. Ça passe par +changer les plaquettes. Il faut réussir à changer l'image existante des confs / +communautés. Un développeur peut aussi etre une développeuse. Dans l'assemblée, +on se rend compte que certaines femmes sont en dehors du parcours. Il faut +qu'en tant que communauté on soit capables d'accueillir les nouvelles / +nouveaux. C’est en ayant une diversité qu’on parviendra à changer l’image du +métier. Les rencontres pyladies permettent aussi de rencontrer d'autres femmes +qui ont les mêmes problématiques. Accompagner les nouvelles entrantes pour +trouver du boulot, découvrir l'AFPY et les initatives existantes. Les +initiatives existantes django girls / pyladies est très important.</p> +<p><strong>Amandine</strong> — C’est pourquoi ce genre d’évènements non-mixtes permet de faire +des séances de rattrapage pour permettre d’intégrer la communauté dans son +ensemble. C’est le point clé pour faire accepter ce genre d’initiatives.</p> +<p><strong>Laurenne</strong> — DjangoGirls et Django Carrots ne sont pas des évènements +excluants. Ils sont simplement orientés en priorité aux femmes. Sur la question +de « comment amener des jeunes filles vers ces études-là », ça se joue bien +avant, dans l’enfance, bien avant l’école. cf les jeux genrés. Il faut +travailler à ce niveau-là.</p> +<p><strong>Anna</strong> — Pour illustrer ce que dit Laurenne, l'importance des clichés +existants. Avant le mi-80s, il y avait autant de femmes que dans d'autres +domaines. Si on regarde les stats, dans tousles autres domaines, le pourcentage +de femmes augmente. Et en IT, en 84 il y a un pic qui inverse la tendance. Ce +sont des stats américaines. A priori cela s'applique aussi en Europe. En IT, la +culture qui à été créé autour des hackers qui ont des super pouvoirs, mangent +des pizzas, etc. Ces clichés ont influencé le monde. Nous ne sommes pas +complètement autonomes, et nous sommes influencés par la culture autour de +nous. Les dommages qui ont été fait dans le domaine de l'IT sont graves, et il +est important de renverser la tendance. La question de l'image est centrale. +Les personnes ont besoin de place pour faire leurs évènements. Il est important +de comprendre et respecter que les autres veuillent faire de la discrimination +positive. Ce sont des actions qui sont supportées par la France. Ce sont des +valeurs qui sont beaucoup lus fortes en France qu'ailleurs (Anna souligne +qu'elle est Polonaise). On devrait respecter ce droit.</p> +<p><strong>Vivianne</strong> — Certaines evènements sont non-mixtes (pour les personnes qui +s'identifient comme des femmes). Ce ne doit pas etre les seules initiatives. +Elle est pour la mixté. PyLadies est assez spécifique : ce n’est pas de la +formation, mais principalement des évènements tournés autour du réseau. Il est +important d'avoir un endroit ou les jeunes femmes seront moins imprésionnées. +Les situations exposées dans la BD sont réelles. De se retrouver dans un +environnement où elles sont sûres qu’elles ne subiront pas de micro-agressions.</p> +<p><strong>Laurence</strong> — Témoignage d'une mère qui dit à sa fille, en passant devant un +panneau de l'école, mentionnant maths et informatique, et qui dit à sa fille « +oh non, c'est pas pour toi ça » . On dit « attention les garçons, vous devez +être sympas avec les filles ». Les garçons ont envie que ça se passe bien avec +les filles.</p> +<p><strong>JP</strong> — Sans revenir sur les décisions qui ont été prises, nous n'avons pas +dit que nous étions contre ces évènements (à l'AFPY). A plusieurs reprises, +j'ai du faire des blagues sexistes. Évidemment qu'on est mieux ensemble. Pour +revenir sur la discussion de la mailing-list, je me suis rendu compte que +j'avais un regard biaisé. Si on en est la, c'est quil y a énormement de +travail. Que faire, du coup ? En tant qu'hommes ? Qu'association ? Si il est +necessaire de créer une zone de confort / sécurité, c'est qu'il y a une zone +d'inconfort / insécurité qui est forte. Les couleurs, les jolis goodies, sont +le sommet de l’iceberg. Rappel de l'éxistence du Code of Conduct : il y a déjà +eu des incidents par le passé. On passe la parole à Florent, qui est à +l’origine du CoC. Remerciement envers les intervenantes.</p> +<p><strong>Florent (vice secrétaire de l'AFPY)</strong> — Comme le dit JP, un code of conduct +est affiché devant toutes les portes et à l'entrée. Tout le monde n’aimait pas +forcément l’idée d’en avoir, on a fini par trancher. Le but est d’avoir des +endroits safes. Avant d’avoir un CoC, on ne peut pas dire qu’on soit safes, +envers l'ensemble des minorités. On a écrit le CoC en conséquence des +agressions. Aujourd’hui, pas de tolérance pour des comportements qui n’ont pas +lieu d’être (qu’on a définis comme tels). Ça fonctionne sur la dénonciation +lorsque l’on est témoin de ça. On n’a pas vraiment de mal à rencontrer des +femmes, mais plus de mal à faire comprendre qu’elles sont bienvenues. Impact +important de blagues sexistes, qu’on défend comme « c’est pour rire ». Merci de +lire le Code of Conduct. Les blagues sexistes etc. ne sont pas les bienvenues. +Merci de réagir lors de ces cas.</p> +</div> +<div class="section" id="questions"> +<h2>Questions.</h2> +<p><strong>Questiond de Gawel</strong>: Question pour Amandine. Est-ce que tu te sens bien à l'AFPY ? Si non, que faire pour que tu te sente mieux ?</p> +<p>Amandine — Oui je me sens bien, est-ce qu’il y a eu des évènements ? oui, sans +doute mais j’y suis aguerrie, donc je me rends peu compte. Qu’est-ce qu’on peut +faire ? L’idée du CoC est d’aller à l’encontre des comportements négatifs, mais +l’idée derrière est une ouverture à la différence dans son ensemble, promouvoir +l’ouverture à l’autre et à la différence. L’enjeu culturel est d’arriver à +changer d’état d’esprit et d’identifier ces biais cognitifs. Il faudrait pas +qu’on se dise « ho là là, il y a une fille, faut rien dire sinon je vais me +faire taper » Il faut cultiver la différence. et être curieux/se.</p> +<p><strong>Question</strong> : « c’est pas fait pour moi », mais plutôt « je suis mauvais, donc +je dois travailler », on en revient à l’importance de l’éducation. Il faut +continuer de pointer du doigt les problèmes. Je suis aussi membre d’un LUG, +nous sommes entre hommes diplomés blancs de 30 à 40 ans. La réflexion sur les +plaquettes pas accueillantes est pertinente : le site de l’asso est très +masculin.</p> +<p><strong>Question de Bruno</strong>. Pour l’école: quand j’étais étudiant, 20% de filles. +(Aujourd’hui on est partis de 7/8% pour arriver à 15%). Est-ce que les filles +réussissent plus ?</p> +<p>Laurence — on n’a pas de stats, mais elles posent moins de problèmes. Les +filles sont favorisées par les employeurs.</p> +<p>Vivianne — la motivation des filles à la sortie est identique aux garçons, mais +tout n’est pas rose. En entretien par exemple, ils sont faits par des hommes, +mais au niveau des stats, le nombre de femmes qui quittent le milieu est +important. Effort à faire au niveau de la communauté, des entreprises. Schémas +masculins, mais sur le long terme, on subit des agressions. Difficile de rester +dans le métier et faire une carrière intéressante, à compétences/motivation +identiques aux hommes. Il faut en avoir conscience</p> +<p><strong>Question de Benoit</strong>: il y a peut-être une façon de créer des +lieux/évènements protégés, en utilisant ceux qui existent déjà. Est-ce qu’on +peut aller organiser des évènements dans des écoles/lycées, des endroits où les +gens se sentent déjà à l’aise, où les populations sont plus représentées ?</p> +<p>Vivianne — ça se fait. En tant qu’enseignante, dès que j’ai une occasion, que +ce soit pour aller chercher des JF ou des étudiants maths/infos, même si c’est +ouvert à tous, je le fais. Si c’est que des hommes, les femmes n’ont pas envie +d’y aller.</p> +<p>Laurenne — c’est quelque chose qui se fait beaucoup. On met en avant des femmes +chercheuses dès qu’on le peut.</p> +<p><strong>Question d'Alexis</strong> : je suis très content qu’il y ait cette discussion qui +se fasse. Question par rapport aux discriminations positives, qu’on a pu voir +par le passé (notamment lors de conférences). Difficile de dire « on va +préférer des femmes ». Question irrésolue, parce que pour faire évoluer, on a +besoin d'initier quelque chose, d’essayer. Mais ça a un côté dérangeant.</p> +<p>Vivianne — à la PyCon (US), j’ai été impressionnée du nombre de femmes qui +parlaient. On va pas mettre un quota, ça serait stupide, on va forcer personne. +Mais il faut en avoir conscience. Cette année, on est 4 oratrices, y’a du +travail à faire. En tant qu’hommes, il faut aussi se mettre en retrait et +inviter des femmes à en parler à notre place. Faire le pas d'aller faire un +exposé dans une communauté où on ne se sent pas à sa place (même si on lutte +contre) est difficile. Inviter des gens, sans forcément passer par un énorme +processus. Ça passe par des events comme PyLadies.</p> +<p>Anna — pour les personnes par encore convaincues, juste apres le droit de vote +des femmes en 46, à l'assemblée nationale il y avait très peu de femmes. Puis +en 93, 6.1% apres que des mesures aient été prises. Ensuite de femmes puis vers +20% Les choses ne vont pas se changer toutes seules. Il est necessaire d'avoir +du temps pour faire évoluer les choses. Il est important de noter que PyconFR +fait déjà des choses. Et lors de django carrots, je me suis sentie très +accueillie. J'ai eu beaucoup de très bonnes expériences avec des personnes qui +étaient prêtes à aider.</p> +<p>JP — Remerciement pour Rémy qui abat un travail de ouf. C'est grace à Rémy si +il y a django carrots demain. Il faut faire des choses. :-) Merci !</p> +</div> +Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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't actually +trust the software authors but are rather trusting the software distributors +and certificate authorities (CAs).</p> +<p>I'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 come!</p> +<div class="section" id="the-problem-attack-vectors"> +<h2>The problem (Attack vectors)</h2> +<p>Let's try to describe a few potential 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 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 CDN +which delivers the files,</p> +<p>Trusted <em>Certificate Authorities</em> (&quot;governments&quot; or &quot;hacking team&quot;) can also +trick the User Agents (i.e. Firefox) into thinking they're talking to <em>Indie +Hoster</em> even though they're actually talking to a different 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 users.</p> +</div> +<div class="section" id="problem-mitigation"> +<h2>Problem Mitigation</h2> +<p>Part of the problem is solved by the recently introduced <a class="reference external" href="https://w3c.github.io/webappsec/specs/subresourceintegrity/">Sub Resource +Integrity</a> +(SRI). To quote them: &quot;[it] defines a mechanism by which user agents may verify +that a fetched resource has been delivered without unexpected manipulation.&quot;.</p> +<p>SRI is a good start, but isn't enough: it ensures the assets (JavaScript files, +mainly) loaded from a specific HTML page are the ones the author of the HTML +page intends. However, SRI doesn't allow the User Agent to ensure the HTML page +is the one he 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's not automated, but at least it's possible.</p> +<p>For web applications, we don't have such a mechanism, but it should be +possible. Consider the following:</p> +<ul class="simple"> +<li><em>App Authors</em> publish a new version of their software; They provide a hash of +each of their distributed files (including the HTML files);</li> +<li><em>Crypto Experts</em> audit these files and sign the hashes 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're signed by a trusted +party.</li> +</ul> +</div> +<div class="section" id="chosing-who-you-trust"> +<h2>Chosing who you trust</h2> +<p>In terms of user experience, handling certificates is hard, and that's where +the community matters. Distributions such as <a class="reference external" 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't verified.</p> +<p>But, as highligted earlier, CAs are hard to trust. A new instance of the same +CA system wouldn'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 of).</p> +<blockquote class="epigraph"> +<p>[...] 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 CA scandals. Both schemes can also be attacked if the +authority does not verify keys before vouching for them.</p> +<p class="attribution">&mdash;<a class="reference external" 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 reliable:</p> +<blockquote class="epigraph"> +<p>Melara et al proposed CONIKS, using a series of chained commitments to Merkle +prefix trees to build a key directory [...] for which individual users can +efficiently verify the consistency of their own entry in the directory +without relying on a third 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 self-auditing.</p> +<p class="attribution">&mdash;<a class="reference external" 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'm pretty sure +this design has many security problems attached to it.</p> +<p>However, that's a problem I would really like to see solved one day, so here +the start of the discussion, don't hesitate to <a class="reference external" href="/pages/about.html">get in touch</a>!</p> +</div> +<div class="section" id="addendum"> +<h2>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'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 this.</p> +<p>A bit like User-Agents do for SSL, but for the actual signature of the files +being viewed.</p> +</div> +Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-06-29:/roles.html<blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de …</p></blockquote><blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de +positions qu’adoptent ses protagonistes et les affects qui y sont liés, +imaginer ensuite des questions à résoudre ou des propositions à travailler +qui soient susceptibles d’enrichir la palette, les couleurs de la fonction +de chacun dans le groupe et les manières qui sont les siennes d’intervenir +et de faire évoluer l’histoire.</p> +<p class="attribution">&mdash;David Vercauteren, <a class="reference external" href="http://micropolitiques.collectifs.net/Role">Micropolitiques des groupes</a></p> +</blockquote> +<p>Réussir la transformation d'un espace compétitif vers un groupe soudé demande +de réaliser quels sont les points forts de chacun au sein d'un groupe.</p> +<p>Une solution évoquée par <a class="reference external" href="http://www.starhawk.org/about/">StarHawk</a>, reprise +par <em>David Vercauteren</em> repose sur l'existence de rôles informels au sein des +groupes et la nécessité de les faire tourner (ainsi que les responsabilités +attachées).</p> +<p>Parmi les rôles principaux, quelques autres citations:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">l'emphase est de mon fait, et je retravaillé très legèrement certains +passages afin d'avoir une lecture plus fluide. Je vous invite à suivre +les liens pour voir les &quot;questions que chaque rôle fait exister&quot;, et +poursuivre la lecture du livre, qui est entièrement disponible en +ligne.</p> +</div> +<div class="section" id="id1"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_0">Les corbeaux</a></h2> +<blockquote class="epigraph"> +<p>Les Corbeaux sont visionnaires […] Ils voient à long terme, et gardent en +ligne de mire les objectifs du groupe. Ils suggèrent de nouvelles directions, +dressent des plans, développent des stratégies et anticipent les problèmes et +les besoins.</p> +<p>Les Corbeaux ont souvent beaucoup d’influence sur le groupe. Si une ou deux +personnes pensent à des plans au long-terme, les autres acquiesceront, +simplement parce qu’ils n’ont pas amené d’autres propositions. <strong>Le groupe +aurait intérêt à considérer ensemble les questions du Corbeau</strong></p> +</blockquote> +</div> +<div class="section" id="id2"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_1">Les graces</a></h2> +<blockquote class="epigraph"> +<p>Les Grâces sont toujours attentives à l’énergie du groupe, prêtes à la +renforcer au moment où elle faiblit, à la diriger et à la canaliser quand +elle est forte.</p> +<p>Elles apportent au groupe […] enthousiasme, énergie, capacité +à s’agrandir. <strong>Elles font en sorte que les gens se sentent bien</strong>, génèrent de +l’enthousiasme pour le groupe, accueillent les nouveaux venus, amènent de +nouvelles personnes. Elles offrent au groupe l’inspiration et génèrent de +nouvelles idées.</p> +</blockquote> +</div> +<div class="section" id="id3"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_2">Les dragons</a></h2> +<blockquote class="epigraph"> +<p>Le dragon permet au groupe de rester connecté à […] l’aspect pratique et +réaliste des choses. […] Le dragon veille aux ressources du groupe, à ses +frontières et donne voix à ses limites.</p> +<p>Questions que fait exister le dragon:</p> +<ul class="simple"> +<li>Notre manière de travailler est-elle viable ?</li> +<li>Nos ressources sont-elles renouvelées ?</li> +<li>Les gens s’épuisent-ils ? Pourquoi ?</li> +<li>Pouvons-nous vraiment nous lancer dans ce projet et le mener à bien +convenablement ?</li> +<li>De quelles frontières avec l’extérieur avons-nous besoin et voulons-nous +?</li> +<li>Comment établissons-nous ces frontières ? Comment nous protégeons-nous +des intrusions ? Invasions ? Distractions ? De ce qui épuise nos énergies +?</li> +</ul> +<p><strong>Les Dragons établissent des frontières qui donnent au groupe un sentiment +de sécurité et des limites qui le rendent viable dans le temps</strong>. Ils peuvent +être perçus comme des rabat-joie, mais ils peuvent gagner l’estime de ceux +qui, dans le groupe, se sentent dépassés et ne peuvent partager l’énergie +des Corbeaux et des Grâces.</p> +<p>Nourrir les Dragons peut permettre au groupe de se maintenir dans le temps. +Mais une fois encore, si ce rôle ne tourne pas, même les Dragons risquent +de s’épuiser.</p> +</blockquote> +</div> +<div class="section" id="id4"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_3">Les araignées</a></h2> +<blockquote class="epigraph"> +<p>Le centre d’un groupe peut consister en un « cœur spirituel », <strong>un but ou une +vision commune</strong>, ou peut se manifester à travers une personne. Dans les modes +de pensée hiérarchique, le professeur ou le gourou occupe le centre du +réseau. […]</p> +<p>Dans les groupes non-hiérarchiques, certaines personnes peuvent être perçues +comme centrales : en disposant des informations dont les autres ont besoin, +en étant le point de contact pour les autres.</p> +<p>Une Araignée est toutefois plus efficace en ne monopolisant pas la +communication et les informations mais en posant les questions susceptibles +de créer et de renforcer un véritable réseau d’interactions complexes.</p> +</blockquote> +</div> +<div class="section" id="id5"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_4">Les serpents</a></h2> +<blockquote class="epigraph"> +<p>Les serpents cultivent une attention particulière à la manière dont les gens +se sentent. […]</p> +<p>Les serpents sont au courant de ce qui se murmure dans les couloirs, des +conflits naissants, et les mettent sur la place publique, là où ils +pourraient aider à une médiation, à une résolution du problème. […]</p> +<p>Les serpents transgressent les lois du Censeur, <strong>parlent des non-dits, mettent +en évidence ce que d’autres ne voient pas ou préfèrent garder caché</strong>. […]</p> +<p>Les serpents peuvent diminuer l’antipathie dont ils font l’objet s’ils +prennent la peine de poser des questions au groupe et non d’apporter des +analyses.</p> +</blockquote> +<p>Ainsi, il est possible de se rendre compte de la complexité et de l'importance +d'une position ou d'une autre, et de les faire évoluer ensemble, en prenant en +compte leur impact positif sur le groupe.</p> +<p>Il est par exemple possible, après avoir expérimenté des rôles, de questionner +leur pertinence et d'établir des pistes d'amélioration en enlevant une part +importante d'affect personnel qui parfois empêche des discussions +constructives.</p> +<p>Je n'ai pour l'instant pas pu expérimenter l'évolution des rôles au sein d'un +groupe donné, mais je peux d'ores et déjà me rendre compte que selon les +groupes et selon les moments je n'ai pas le même rôle (tour à tour dragon, +araignée et grace, parfois corbeau, rarement serpent)</p> +<p>Aussi, il semble que le groupe doive souhaiter l'établissement d'un +environnement <em>horizontal</em>, avec une considération partagée de la direction que +le groupe souhaite prendre pour qu'un tel dispositif ait du sens.</p> +</div> +Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois …</p><blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois passé l'euphorie du &quot;il faut utiliser PGP pour l'ensemble de nos +communications&quot;, j'ai réalisé lors de discussions que PGP avait plusieurs +problèmes, parmi ceux-ci:</p> +<ul class="simple"> +<li>Les <em>meta données</em> (y compris le champ &quot;sujet&quot; de la conversation) sont quand +même échangées en clair (il est possible de savoir qu'un message à été échangé +entre telle et telle personne, a telle date);</li> +<li>PGP 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 chiffrée;</li> +<li>Il est facile de connaître votre réseau social avec PGP, puisque tout le +principe est de signer les clés des personnes dont vous validez l'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 PGP 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 &quot;sécurisée&quot; (HTTPS). Tout le monde peut donc voir ces échanges et +savoir de qui vous cherchez la 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 clés).</li> +</ul> +<p>Je suis en train de creuser à propos les alternatives à PGP, par exemple <a class="reference external" href="https://pond.imperialviolet.org/">Pond</a>, qui lui ne construit pas par dessus un +standard déjà établi, et donc n'hérite pas de ses défauts (mais pas non plus de +son réseau déjà établi).</p> +<p>En attendant, quelques bonnes pratiques sur PGP ;)</p> +<div class="section" id="bonnes-pratiques"> +<h2>Bonnes pratiques</h2> +<p>Il est en fait assez facile d'utiliser PGP de travers. Riseup à fait <a class="reference external" href="https://help.riseup.net/en/security/message-security/openpgp/best-practices">un +excellent guide</a> +qui explique comment configurer son installation correctement.</p> +<ul class="simple"> +<li>J'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 oubliez.</li> +<li>Générez des clés RSA de 4096 bits, en utilisant sha512;</li> +<li>Il faut utiliser une date d'expiration de nos clés suffisamment proche (2 +ans). Il est possible de repousser cette date si nécessaire, par la suite.</li> +</ul> +<p>Parmi les choses les plus frappantes que j'ai rencontrées:</p> +<ul class="simple"> +<li>Utiliser le <em>flag</em> <cite>–hidden-recipient</cite> avec PGP pour ne pas dévoiler qui est +le destinataire du message;</li> +<li>Ne pas envoyer les messages de brouillons sur votre serveur, ils le seraient +en clair !;</li> +<li>Utilisez HPKS pour communiquer avec les serveurs de clés, sinon tout le +trafic est en clair.</li> +</ul> +<p>Le <a class="reference external" href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils de +chiffrement d'échanges de messages et de VPN simples à utiliser, encore quelque +chose à regarder.</p> +<p>Enfin bref, y'a du taf.</p> +</div> +Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui …</p><blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui n'étaient bien souvent que des +envies passagères.</p> +<p>Il est arrivé que quelqu'un m'ait demandé de le faire, et que j'y prenne du +plaisir, ou que je le fasse simplement pour moi et que d'autres y trouvent leur +compte, mais il s'agit nécessairement de projets non <em>commandités</em> par l'extérieur.</p> +<p>Encore un signal dans la direction du travailler moins, cette fois ci pour +être plus créatif.</p> +<img alt="Soupa'Soups." src="https://blog.notmyidea.org/images/soupasoups.jpg" /> +Simplifier les preuves d'identités2015-05-11T00:00:00+02:002015-05-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.html<p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la …</p><p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la clé publique que +j'utilise est réellement la mienne.</p> +<p>Traditionnellement, il est nécessaire de faire signer ma clé publique par +d'autres personnes, via une rencontre en personne ou des échanges hors du +réseau. C'est par exemple ce qui est réalisé lors des <a class="reference external" href="https://fr.wikipedia.org/wiki/Key_signing_party">Key Signing parties</a>.</p> +<p>Une manière simple d'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 personne.</p> +<p>PGP propose un mécanisme de signature des clés d'autrui, une fois celles ci +validées, ce qui permet de placer sa confiance dans les signataires de la clé.</p> +<p><a class="reference external" 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'il est possible +d'utiliser différents moyens afin de prouver l'identité des personnes. Par +exemple, leurs comptes Twitter, GitHub ou leurs noms de domaines. De la même +manière qu'il est possible de signer (valider) les clés de nos amis, il est +possible de les &quot;tracker&quot; selon le jargon de keybase.</p> +<p>Donc, en somme, <em>Keybase.io</em> est un annuaire, qui tente de rendre plus facile la +création de preuves. Bien.</p> +<div class="section" id="quelques-points-d-ombre"> +<h2>Quelques points d'ombre</h2> +<p>Il s'agit d'une <em>startup</em> américaine, domiciliée dans le Delaware, qui se trouve être +un des paradis fiscaux qui <a class="reference external" 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 class="reference external" href="https://github.com/keybase/keybase-issues/issues/1569">j'ai ouvert un ticket +sur GitHub pour en savoir plus</a> (après tout, le fait +d'être un paradis fiscal permet peut-être d'échapper à certaines lois sur la +requêtes de données). D'autant plus étonnant, la startup n'a pour l'instant <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/788">pas +de *business model*</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 là).</p> +<p>Le service (bien qu'en Alpha), n'est pas mis à disposition sous licence libre, +ce qui pour l'instant empêche quiconque de créer son propre serveur Keybase. +<a class="reference external" href="https://github.com/keybase/">Une partie des composants, cependant, le sont (open source)</a>.</p> +<p>J'ai du mal à croire en des initiatives qui veulent sauver le monde, mais dans +leur coin, je ne comprends pas pourquoi il n'y à pas de documentation sur +comment monter son propre serveur, ou comment les aider à travailler sur la +fédération. Mais bon, c'est pour l'instant une initiative encore fraîche, et je +lui laisse le bénéfice du doute.</p> +<p>Sur le long terme, une infrastructure comme <em>Keybase.io</em>, devra évidemment être +<a class="reference external" href="https://github.com/keybase/keybase-issues/issues/162">distribuée</a>.</p> +<blockquote class="epigraph"> +<p>We'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'd be so happy to get this +right.</p> +<p class="attribution">&mdash;<a class="reference external" href="http://chris.beams.io/posts/keybase/">Chris Coyne, co-founder of Keybase</a></p> +</blockquote> +<p>Afin de se &quot;passer&quot; de leur service centralisé, les preuves générées (qui sont +la force du système qu'ils mettent en place) pourraient être exportées sur des +serveurs de clés existants. C'est quelque chose <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/890">qu'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'on s'y attarde un brin.</p> +<p>Par ailleurs, <a class="reference external" href="https://leap.se/nicknym">d'autres projets qui visent des objectifs similaires</a> existent, via le projet LEAP, mais je n'ai pas +encore creusé.</p> +</div> +Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html<blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi …</p></blockquote><blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi est trop faible ou construit d'une +manière trop prédictible, cette attaque par la force pourrait se revéler +fructueuse en essayant toutes les possibilités.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://www.eff.org/wp/defending-privacy-us-border-guide-travelers-carrying-digital-devices">The Electronic Frontier Foundation</a> (traduction de mon fait)</p> +</blockquote> +<p>Comprendre les concepts et l'écosystème qui permettent d'avoir une vie +numérique chiffrée n'est pas quelque chose d'aisé. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Plusieurs</a> <a class="reference external" 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 existants.</p> +<blockquote class="epigraph"> +<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 système.</p> +<p class="attribution">&mdash;La page de manuel de GPG.</p> +</blockquote> +<p>Une phrase de passe devrait:</p> +<ul class="simple"> +<li>Être suffisamment longue pour être difficile à deviner;</li> +<li>Ne pas être une citation connue (littérature, livres sacrés etc);</li> +<li>Difficile à deviner même pour vos proches;</li> +<li>Facile à se souvenir et à taper;</li> +<li>être unique et non partagée entre différents sites / applications etc.</li> +</ul> +<p>Une des techniques consiste à utiliser des mots du dictionnaire, sélectionnés de +manière aléatoire, puis modifiés.</p> +<div class="figure"> +<img alt="XKCD sur la force des mots de passe." src="https://imgs.xkcd.com/comics/password_strength.png" /> +</div> +<p>Micah Lee <a class="reference external" 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 longues.</p> +<div class="figure"> +<img alt="Capture d'écran du logiciel de génération et de mémorisation des phrases de passe." src="{filename}/static/passphrases.png" /> +</div> +<p>Oui, ce n'est pas aussi simple que ce qu'il y parait. Pour ma part, j'ai une +copie en local de mes clés, dans un fichier chiffré avec une autre clé que j'ai +généré pour l'occasion et que je ne partagerait pas. J'ai par ailleurs +<a class="reference external" href="https://github.com/jamessan/vim-gnupg">configuré</a> mon éditeur de texte pour +pouvoir chiffrer les documents textes par défaut.</p> +<p>J'ai donc regénéré une nouvelle fois mes clés de travail et personnelles, en +utilisant des phrases de passe plus complexes.</p> +<p>Reste encore la question de la sauvegarde de ces clés privées de manière +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.</p> +Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-08:/chiffrement.html<blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise …</strong></li></ul></blockquote><blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise sous surveillance de pans entiers de la vie politique, syndicale, +militante</strong>, mais aussi économique, scientifique, etc. ;</li> +<li>Légalisation massive de pratiques illégales des services de +renseignement et <strong>introduction de techniques de surveillance de masse +des communications électroniques</strong> ;</li> +<li><strong>Absence de contrôle réel et indépendant</strong> a priori par la future +CNCTR, et recours des citoyens illusoires ;</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="https://www.laquadrature.net/fr/lassemblee-nationale-vote-la-surveillance-de-masse-des-citoyens-francais">La Quadrature du Net - L'Assemblée nationale vote la surveillance de +masse des citoyens français !</a></p> +</blockquote> +<p>Je m'étonne que <a class="reference external" href="https://fr.wikipedia.org/wiki/R%C3%A9v%C3%A9lations_d%27Edward_Snowden">les révélations d'Edward Snowden</a> — qui +ont démontré que la plupart des communications électroniques et téléphoniques +pouvaient être scrutés par la NSA, l'agence de sécurité Américaine) — ne +fassent pas plus de remous que ça.</p> +<p>À peine deux années après ces révélations, la France fait passer une loi qui +légitime cette surveillance de masse, à plus de 77% des voies. Pour moi c'est +un signal fort de la perte de valeurs de notre démocratie, et à fortiori de ma +perte de foi en notre forme de démocratie.</p> +<p>Notre liberté d'expression se voit bien évidemment amputée de par la +surveillance généralisée. Sans avoir nécessairement à cacher mes échanges, ce +qui est de la sphère privée devrait pouvoir le rester.</p> +<p>De toute manière, l'email comme on l'utilise traditionnellement est une +hérésie: toutes les parties qui traitent le message peuvent le lire, +(destinataire, auteur et corps du message entre autres). Il est grand temps de +rendre les outils de chiffrement plus simples et ergonomiques.</p> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, envers +mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins pour +rendre le déchiffrement des messages plus longue, &quot;noyer le poisson&quot;.</li> +</ul> +<p>Si vous êtes intéressé(e)s, faites moi signe, je me ferais un plaisir de vous +expliquer ce qui n'est pas si complexe et vise à laisser dans la sphère privée +ce qui devrait l'être à priori.</p> +<p>Une manière simple de se protéger est d'installer Thunderbird avec Enigmail et +de le configurer correctement. Ce n'est pas très compliqué et permet d'avoir +des échanges chiffrés. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à pas.</p> +<p>La clé publique pour me contacter est <a class="reference external" href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et +vous ?</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 autour (<a class="reference external" href="https://supporters.eff.org/donate">Electronic +Fronteer Fondation</a>, <a class="reference external" href="https://tails.boum.org/contribute/how/donate/index.fr.html">Tails</a>, <a class="reference external" href="https://support.laquadrature.net/">La quadrature +du net</a> en france ou d'autres…)</p> +<link href="http://vjs.zencdn.net/4.12/video-js.css" rel="stylesheet"> +<script src="http://vjs.zencdn.net/4.12/video.js"></script> +<video id="MY_VIDEO_1" class="video-js vjs-default-skin" controls + preload="auto" width="640" height="264" poster="MY_VIDEO_POSTER.jpg" + data-setup="{}"> + <source src="https://citizenfour.thecthulhu.com/citizenfour.mp4" type='video/mp4'> + <p class="vjs-no-js">To view this video please enable JavaScript, and + consider upgrading to a web browser that <a + href="http://videojs.com/html5-video-support/" target="_blank">supports + HTML5 video</a></p> +</video>Language2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-01:/language.html<blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux …</p></blockquote><blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux dont c'est la langue maternelle.</p> +<p>Aussi nous savons tous que les concepts qui paraissent similaires sont +souvent différents d'une civilisation à l'autre. Les mots expriment une +culture, une façon de penser et une vision du monde.</p> +<p class="attribution">&mdash;M. Boutros Boutros-Ghali, ancien secrétaire général des Nations Unies</p> +</blockquote> +<p>Je me surprends à préférer le français pour m'exprimer au lieu de l'anglais, +notamment au niveau des articles non techniques.</p> +<p>Il y a quelques années, alors que je terminais mes études en Angleterre et que +je commençais à travailler pour Mozilla, on me proposait de venir aux +États-Unis, ce que j'ai refusé parce qu'exprimer mes points de vue de manière +fine m'était trop difficile dans une langue qui n'était pas la mienne.</p> +<ul class="simple"> +<li>Cela me permet de pouvoir tenir des discours avec des positions et un +argumentaire &quot;fin&quot;, ce qui me serait beaucoup plus difficile dans une langue +que je maitrise moins;</li> +<li>Sans même parler d'argumentaire, les mots utilisés dans ma langue maternelle +me permettent de manœuvrer plus finement et de faire passer des idées de +manière plus efficace;</li> +<li>J'ai l'impression de pouvoir engager plus facilement avec les gens qui +m'entourent géographiquement, par exemple par rapport à la communauté +technophile / pythoniste francophone.</li> +<li>Même si mon niveau d'anglais à progressé, ce n'est pas nécessairement le cas +de mes interlocuteurs.</li> +</ul> +<p>Par contre, cela nuit clairement à engager avec d'autres personnes dont la +langue n'est pas la mienne, dans tels cas, traduire les contenus intéressants +vers l'anglais semble une solution (chronophage).</p> +Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html<p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village …</p><p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village de dire :</p> +<blockquote> +Mais quel mauvais père qui oblige ainsi son fils d'aller à pied !</blockquote> +<p>Le lendemain ils sortent de nouveau.</p> +<p>Le père ayant installé son fils sur l'âne et lui marchant à côté.</p> +<p>Les gens du village dirent alors :</p> +<blockquote> +Quel fils indigne, qui ne respecte pas son vieux père et le laisse aller à pied !</blockquote> +<p>Le jour suivant, ils s'installent tous les deux sur l'âne avant de quitter la maison. +Les villageois commentèrent en disant :</p> +<blockquote> +Ils ne respectent pas leur bête à la surcharger ainsi !</blockquote> +<p>Le jour suivant, ils partirent en portant eux-mêmes leurs affaires, l'âne trottinant derrière eux. +Cette fois les gens du village y trouvèrent encore à redire :</p> +<blockquote> +Voilà qu'ils portent eux-mêmes leurs bagages maintenant ! C'est le monde à l'envers !</blockquote> +<p>De retour à la maison, le père dit à son fils :</p> +<blockquote> +Tu me demandais l'autre jour le secret du bonheur. +Peu importe ce que tu fais, il y aura toujours quelqu'un pour y trouver à redire. +Fais ce qui te plaît et là tu seras vraiment heureux.</blockquote> +What's Hawk and how to use it?2014-07-31T00:00:00+02:002014-07-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.html<p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original …</p><p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original <a class="reference external" href="https://en.wikipedia.org/wiki/OAuth">OAuth</a> specification authors, that intends to +replace the 2-legged OAuth authentication scheme using a simpler approach.</p> +<p>It is an authentication scheme for HTTP, built around <a class="reference external" href="https://en.wikipedia.org/wiki/Hmac">HMAC digests</a> of requests and responses.</p> +<p>Every authenticated client request has an Authorization header containing a MAC +(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 +server.</p> +<div class="section" id="exchange-of-the-hawk-id-and-hawk-key"> +<h2>Exchange of the hawk id and hawk key</h2> +<p>To sign the requests, a client needs to retrieve a token id and a token key +from the 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 class="reference external" href="http://accounts.firefox.com">Firefox Accounts</a> put together a scheme to do that, which acts +like the following:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p>All this derivation crazyness might seem a bit complicated, but don't worry, +we put together some libraries that takes care of that for you automatically.</p> +<p class="last">If you are not interested into these details, you can directly jump to the +next section to see how to use the libraries.</p> +</div> +<p>When your server application needs to send you the credentials, it will return +it inside a specific <cite>Hawk-Session-Token</cite> 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 requests.</p> +<p>In order to get the hawk credentials, you'll need to:</p> +<p>First, do an <a class="reference external" href="http://en.wikipedia.org/wiki/HKDF">HKDF derivation</a> on the +given session token. You'll need to use the following parameters:</p> +<pre class="literal-block"> +key_material = HKDF(hawk_session, &quot;&quot;, 'identity.mozilla.com/picl/v1/sessionToken', 32*2) +</pre> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">The <tt class="docutils literal">identity.mozilla.com/picl/v1/sessionToken</tt> is a reference to this way of +deriving the credentials, not an actual URL.</p> +</div> +<p>Then, the key material you'll get out of the HKDF need to be separated into two +parts, the first 32 hex caracters are the hawk id, and the next 32 ones are the +hawk key.</p> +<p>Credentials:</p> +<div class="highlight"><pre><span></span><span class="nx">credentials</span> <span class="o">=</span> <span class="p">{</span> + <span class="s1">&#39;id&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">0</span><span class="o">:</span><span class="mi">32</span><span class="p">],</span> + <span class="s1">&#39;key&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">32</span><span class="o">:</span><span class="mi">64</span><span class="p">],</span> + <span class="s1">&#39;algorithm&#39;</span><span class="o">:</span> <span class="s1">&#39;sha256&#39;</span> +<span class="p">}</span> +</pre></div> +</div> +<div class="section" id="httpie"> +<h2>Httpie</h2> +<p>To showcase APIs in the documentation, I like to use <a class="reference external" href="https://github.com/jakubroztocil/httpie">httpie</a>, a curl-replacement with a nicer +API, built around <a class="reference external" 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 class="reference external" href="https://github.com/mozilla-services/requests-hawk">I wrote +a wrapper</a> around <a class="reference external" href="https://github.com/kumar303/mohawk">mohawk</a> to add hawk support to the requests lib.</p> +<p>Doing hawk requests in your terminal is now as simple as:</p> +<pre class="literal-block"> +$ pip install requests-hawk httpie +$ http GET localhost:5000/registration --auth-type=hawk --auth='id:key' +</pre> +<p>In addition, it will help you to craft requests using the requests library:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Alternatively, if you don'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 you:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +</div> +<div class="section" id="integrate-with-python-pyramid-apps"> +<h2>Integrate with python pyramid apps</h2> +<p>If you're writing pyramid applications, you'll be happy to learn that <a class="reference external" 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'm chocked how simple it +is to use it.</p> +<p>Here is a demo of how we implemented it for Daybed:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>The <cite>get_hawk_id</cite> function is a function that takes a request and +a tokenid and returns a tuple of <cite>(token_id, token_key)</cite>.</p> +<p>How you want to store the tokens and retrieve them is up to you. The default +implementation (e.g. if you don't pass a <cite>decode_hawk_id</cite> function) decodes the +key from the token itself, using a master secret on the server (so you don't +need to store anything).</p> +</div> +<div class="section" id="integrate-with-node-js-express-apps"> +<h2>Integrate with node.js Express 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 class="reference external" href="https://github.com/mozilla-services/express-hawkauth">express-hawkauth</a>.</p> +<p>In order to plug it in your application, you'll need to use it as +a middleware:</p> +<div class="highlight"><pre><span></span><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express&quot;</span><span class="p">);</span> +<span class="kd">var</span> <span class="nx">hawk</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express-hawkauth&quot;</span><span class="p">);</span> +<span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span> + +<span class="kd">var</span> <span class="nx">hawkMiddleware</span> <span class="o">=</span> <span class="nx">hawk</span><span class="p">.</span><span class="nx">getMiddleware</span><span class="p">({</span> + <span class="nx">hawkOptions</span><span class="o">:</span> <span class="p">{},</span> + <span class="nx">getSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which pass to the cb the key and algorithm for the</span> + <span class="c1">// given token id. First argument of the callback is a potential</span> + <span class="c1">// error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span><span class="nx">key</span><span class="o">:</span> <span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="nx">algorithm</span><span class="o">:</span> <span class="s2">&quot;sha256&quot;</span><span class="p">});</span> + <span class="p">},</span> + <span class="nx">createSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which stores a session for the given id and key.</span> + <span class="c1">// Argument returned is a potential error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span> + <span class="p">},</span> + <span class="nx">setUser</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function that uses req and res, the hawkId when they&#39;re known so</span> + <span class="c1">// that it can tweak it. For instance, you can store the tokenId as the</span> + <span class="c1">// user.</span> + <span class="nx">req</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="nx">tokenId</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">});</span> + +<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;/hawk-enabled-endpoint&quot;</span><span class="p">,</span> <span class="nx">hawkMiddleware</span><span class="p">);</span> +</pre></div> +<p>If you pass the <cite>createSession</cite> parameter, all non-authenticated requests will +create a new hawk session and return it with the response, in the +<cite>Hawk-Session-Token</cite> 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't have any <cite>createSession</cite> parameter +defined.</p> +</div> +<div class="section" id="some-reference-implementations"> +<h2>Some reference implementations</h2> +<p>As a reference, here is how we're using the libraries I'm talking about, in +case that helps you to integrate with your projects.</p> +<ul class="simple"> +<li>The Mozilla Loop server <a class="reference external" href="https://github.com/mozilla-services/loop-server/blob/master/loop/index.js#L70-L133">uses hawk as authentication once you're logged in with +a valid BrowserID assertion</a>; +request, to keep a session between client and server;</li> +<li><a class="reference external" href="https://github.com/spiral-project/daybed/commit/f178b4e43015fa077430798dcd3d0886c7611caf">I recently added hawk support on the Daybed project</a> +(that's a pyramid / cornice) app.</li> +<li>It's also interesting to note that Kumar put together <a class="reference external" href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for the +django rest framework</a></li> +</ul> +</div> +Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html<p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est …</p><p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est +écrivain il est important de se poser des questions sur les textes que l'on +produit, pour qui et dans quel but; il est important de se questionner sur +l'utilité du métier de développeur, et sur l'utilisation des contenus produits.</p> +<p>Je suis un développeur parce que je défends certaines valeurs. Les valeurs du +partage de connaissances, de la collaboration, et de l'émancipation.</p> +<p>Je suis aussi développeur parce qu'il me plait de créer des contenus à partir +de &quot;pas grand chose&quot;. La <em>magie</em> de la création logicielle m'anime, parce que j'ai +l'impression qu'il est possible de faire des choses géniales à partir de ce &quot;pas +grand chose&quot;. Donnez moi un ordinateur et je vous crée une application de +partage de semences paysannes. Un peu comme il est possible de donner une +feuille de papier à un dessinateur pour se retrouver avec un univers magnifique +couché sur papier.</p> +<p>Je me rends compte qu'au fur et à mesure des années, je me laisse ramollir, +absorber par le quotidien et me retrouve à ne plus me poser de questions +quant à l'utilité de mon métier. Pourquoi est-ce que je code ? À qui cela sert +il ? Quelle est ma motivation réelle ?</p> +<p>En travaillant pour Mozilla, on pourrait croire que ce problème est résolu de fait, +puisque après tout, Mozilla, c'est les &quot;protecteurs du web&quot;, des +gentils, et qu'on essaye nécessairement de faire les choses bien…</p> +<div class="section" id="l-omnipresence-technologique"> +<h2>L'omniprésence technologique</h2> +<p>Je ne suis pas convaincu qu'utiliser la technologie de la manière dont on le +fait actuellement est systématiquement une bonne chose:</p> +<p>Depuis 2 ans quasiment maintenant, Mozilla travaille sur un système +d'exploitation mobile, un remplaçant pour les iphones et androides, qui utilise +cette fois ci les technologies du web. Les avantages sont multiples, et le +principal intérêt est de faire un téléphone qui ne soit pas au service +des &quot;gros&quot; du Web mondial (Google et Apple).</p> +<p>Ces &quot;ordiphones&quot; à destination des pays dits &quot;émergents&quot; sont d'ailleurs +construits à faible coût — toujours de manière honteuse, pour la plupart en +chine, dans les mêmes chaines de production que les autres téléphones, mais +c'est un autre débat.</p> +<p>L'idée, assez intéressante d'un point de vue marché (les pays en question +n'ayant que peu de périphériques actuellement semblent un terrain propice à la +diffusion des &quot;ordiphones&quot;), est de donner accès à la technologie, au Web à ces +pays émergents.</p> +<p>L'accès à la technologie pour tous me semble relever de la chimère +productiviste: je conçois que la technologie puisse être un pas en avant assez +fou, notamment lorsque l'on connaît la richesse des contenus qu'on peut trouver +sur le web, mais cette richesse vient aussi avec un certain coût, que nous +avons actuellement du mal, en tant qu'utilisateurs, à contrôler et à mesurer. +Les gens sont beaucoup beaucoup trop connectés.</p> +<p>Je le suis par exemple bien plus souvent que ce que je voudrais l'admettre, que +ce soit pour regarder un film, lire mes emails, communiquer avec des amis, +faire de l'associatif, écrire du code, des billets sur ces carnets…</p> +<p>Cette technologie, omniprésente dans nos vies, je ne sais pas si c'est un +futur que je souhaite partager.</p> +<p>Pour prendre un autre exemple, les bienfaits de la technologie ne viennent pas +seuls. Les réseaux sociaux, qui constituent une bonne part de l'utilisation du +Web, relèvent du culte de la personnalité, de l'individualisme, et ce n'est pas +ce développement que je souhaite pour notre société.</p> +<p>L'idée de base du Web, le fait de faire une toile de connaissances ouverte et +partagée entre tous est en train, petit à petit, de glisser vers l'idée d'un +outil de relai de l'information, où tout va vite, où l'on ne prends guère +plus le temps de lire autre chose que les titres des quotidiens, ou des +&quot;tweets&quot; de cent vingt caractères…</p> +</div> +<div class="section" id="des-outils-utiles"> +<h2>Des outils utiles</h2> +<p>Bon an, mal an, je pense quand même que la technologie puisse être un vecteur +d'émancipation. Plus spécifiquement, je crois qu'il ne faut pas laisser +l'utilisation de la technologie aux &quot;gros&quot;, aux entreprises, aux états ou +&quot;spécialistes&quot;.</p> +<p>Il est important de ne pas laisser ceux que l'on combat s'emparer des &quot;outils +du pouvoir&quot;. La science, la technologie ou les médias sont autant de champs +qu'il est important de défendre, de conserver, de s'approprier.</p> +<p>Un des objectifs que je me fixe, pour les années à venir, ce que j'ai envie de +créer, c'est à la fois des outils utiles pour les organisations, mais aussi +éduquer à ces outils.</p> +<p>Parce que l'éducation populaire ne s'arrête pas aux frontières du numérique, +parce qu'il est important de se battre avec les mêmes outils que ce monde que +l'on cherche parfois à combattre.</p> +<p>Les outils sur lesquels j'ai envie d'être amené à travailler sont des outils +qui favorisent et questionnent la collaboration.</p> +<p>Des outils comme etherpad par exemple, révolutionnent la manière de prendre des +notes en commun, et il reste énormément à faire sur le web à ce propos.</p> +<p>Nombre d'associations me demandent de plus en plus souvent ce qu'il en est de +Daybed, et de quand est-ce qu'on va pouvoir utiliser un système de génération +de formulaires en ligne, qui ne soit pas centré sur les services de google…</p> +<p>Allez, au boulot !</p> +<p>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, <a class="reference external" href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler-fr.html">sur le sens du travail et +de l'informatique</a>, ça fait du bien :)</p> +</div> +Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud Services&quot;.</p> +<p>Depuis, énormément de choses ont évoluées, tant en ce qui concerne les +objectifs de Mozilla (avec l'arrivée de FirefoxOS) que le travail que +j'effectue au jour le jour. Pour autant, mes objectifs personnels restent +intacts.</p> +<p>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 <a class="reference external" href="ziade.org">Tarek</a> par exemple.</p> +<p>Ç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 !</p> +<div class="section" id="services"> +<h2>Services</h2> +<p>Le principal de mon travail a été de construire des outils. Je suis le +mainteneur de <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>, un +utilitaire qui vient se greffer par dessus <a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">le framework python pyramid</a> pour +vous simplifier la vie et créer des services web; J'ai travaillé un peu +sur un outil de gestion des processus nommé <a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a>, et également sur un outil de +montée en charge dénommé <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a></p> +<p>Au tout début, j'ai travaillé sur un concept de <a class="reference external" href="https://github.com/mozilla-services/tokenserver">serveur de +tokens</a>. L'idée était de +désolidariser l'authentification des services web des services eux mêmes.</p> +<p>L'idée est (je pense) bonne mais le service n'a pas été utilisé durant plus de +deux ans. La raison étant principalement que Sync, pour lequel le serveur de +tokens a été écrit, a subi des changements majeurs (qui sont rentrés en +production il y a quelques semaines)</p> +<p>Circus est né de besoins découverts via le token server, et il m'a +personnellement beaucoup appris. Le token server est finalement utilisé dans la +nouvelle version de Sync qui est rentrée en production il y a peu.</p> +</div> +<div class="section" id="marketplace-chouette-on-va-casser-du-serveur"> +<h2>Marketplace (&quot;chouette, on va casser du serveur&quot;)</h2> +<p>Après 6 mois à travailler à Services, Tarek et moi avons commencé à rejoindre +l'équipe du Marketplace pour faire un travail d'&quot;audit de performance&quot;.</p> +<p>L'idée était de prêter main forte à l'équipe du marketplace, mais les détails +étaient alors assez flous. Le code est assez indigeste au premier abord, ce qui +m'avait alors pas mal refroidi. La raison principale étant que le code est +utilisé à la fois par <cite>addons.mozilla.org</cite> et par <cite>marketplace.firefox.com</cite>, +rendant les choses souvent un peu plus compliquées qu'il ne faudrait.</p> +<p>Cet &quot;audit&quot; a été l'occasion de travailler sur des outils de montée en charge +assez sympa, qui ont donné naissance à un projet qu'on utilise assez souvent +maintenant, <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a>.</p> +<p>Énormément d'efforts sont fait pour aller dans la bonne direction et faire en +sorte que le code soit plus facile à maintenir et que le projet soit plus +facile à aborder. D'ailleurs, pas mal de copains djangonautes français +travaillent dessus (salut <a class="reference external" href="http://virgule.net">Mathieu</a>, Yohan, <a class="reference external" href="http://larlet.fr">David</a> et <a class="reference external" href="http://mathieu.agopian.info">Mathieu Agopian</a>!)</p> +<p>Une partie de notre plan a été de sortir certaines fonctionnalités du code +actuel, pour en faire quelque chose de plus facile à maintenir et de moins +imbriqué.</p> +</div> +<div class="section" id="la-communaute"> +<h2>La Communauté</h2> +<p><a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a> et <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a> sont +deux outils qui semblent utiles à la communauté. J'ai eu des retours très +positifs sur Cornice, et j'essaye de le faire évoluer dans la direction qui me +semble propice.</p> +<p>D'ailleurs, Cornice est utilisé (par <a class="reference external" href="http://blog.mathieu-leplatre.info/pages/about.html">Mathieu L.</a> +— encore un —, <a class="reference external" href="http://twitter.com/natim">Rémy</a> et moi) actuellement pour coder +<a class="reference external" href="https://github.com/spiral-project/daybed">Daybed</a> un service de validation +de formulaires, mais ça sera l'objet d'un futur billet.</p> +<p>Circus commence à recevoir des contributions de plus en plus intéressantes, et +à être utilisé en interne chez nous et chez d'autres, donc c'est une +extrêmement bonne nouvelle.</p> +</div> +<div class="section" id="talkilla-loop"> +<h2>Talkilla / Loop</h2> +<p>Après quelques temps, j'avais envie d'apprendre de nouveau. Python c'est génial +mais c'était devenu ma &quot;zone de confort&quot;. J'adore découvrir des choses, donc +c'était le moment de faire en sorte que ça continue!</p> +<p>C'était aussi l'occasion de travailler avec <a class="reference external" href="https://nicolas.perriault.net/">Nicolas</a> et <a class="reference external" href="http://monkeypatch.me/blog/">Romain</a>. +Je suivais le projet Talkilla de plus ou moins loin depuis quelques mois, +c'était donc l'occasion à ne pas manquer.</p> +<p>En rentrant dans cette équipe, je cherchais principalement à avoir un projet +visible pour les utilisateurs finaux. Refaire un peu de frontend, apprendre +à faire du JavaScript propre et découvrir de nouvelles personnes.</p> +<p>J'y ai aussi récupéré une équipe qui essaye de suivre les principes de +l'agilité et qui est sur mon fuseau horaire (pour la plupart). Le rêve.</p> +<p>L'idée derrière Talkilla est d'utiliser la technologie de communication pair +à pair dans les navigateurs (WebRTC) pour faire des appels audio / vidéo. En +d'autres termes, c'est un peu transformer votre firefox en téléphone, sauf que +personne ne peut espionner ce qui se passe entre vous et l'autre bout du fil.</p> +<p>A peine arrivé dans le projet (peut-être un mois et quelques après mon +débarquement) le choix a été fait de tout réécrire depuis zéro, dans un projet +qui se nomme actuellement &quot;Loop&quot;, qui veut proposer la même chose, mais inclus +directement dans Firefox.</p> +<p>C'est en bonne voie, on a quelque chose qui fonctionne dans nightly, et le code +du serveur fonctionne pas mal. Le code du serveur est ici: +<a class="reference external" href="https://github.com/mozilla-services/loop-server">https://github.com/mozilla-services/loop-server</a>.</p> +<p>Un client est en train d'être implémenté dans Firefox et un autre en tant +qu'application pour FirefoxOS. Le boulot ne s'arrête pas de pleuvoir, mais je +pense qu'on va dans une direction intéressante.</p> +<p>Pour être complètement terminé, il faudrait qu'on soit capable de se passer +complètement de notre provider, TokBox (que l'on utilise en tant que relai +média), pour que n'importe qui puisse choisir d'utiliser son propre serveur +STUN / TURN et installe son serveur loop chez lui.</p> +<div class="section" id="le-travail-a-distance"> +<h3>Le travail à distance</h3> +<p>Quand j'ai commencé à travailler à Mozilla, j'ai décidé de venir m'installer +à Paris. La plupart des personnes de mon entourage ont d'ailleurs fait des gros +yeux, parce qu'ils connaissaient mon avis sur la ville en question, mais casser +des préjugés n'est jamais une mauvaise chose.</p> +<p>Après deux ans passés à Paris, j'ai décidé de partir m'installer à Rennes, +puisque de toute manière, la plupart de mon travail s'effectue au jour le jour +à distance. En d'autres termes, la plupart de mon équipe n'est pas à coté de +moi quand je travaille, ce qui veut dire que je peux travailler depuis +n'importe où.</p> +<p>Ce qui fonctionne pour moi, c'est de ne quasiment jamais travailler depuis la +maison. J'utilise <a class="reference external" href="http://www.lacantine-rennes.net/">un espace de coworking</a> +qui est un moyen de garder ma vie perso séparée de ma vie privée et de +rencontrer des gens passionnés par ce qu'ils font.</p> +<p>Depuis que je suis arrivé à Rennes, Rémy a commencé à travailler avec moi, et +c'est un réel bonheur que de pouvoir partager des journées de travail. On +&quot;pair-prog&quot; énormément et j'ai l'impression d'avoir un boost dans ma +productivité quotidienne.</p> +</div> +<div class="section" id="enseignements"> +<h3>Enseignements</h3> +<p>Mozilla est ma première expérience professionnelle, et par conséquent, je +manque nécessairement de recul sur ce qui est acceptable et ce qui ne l'est +pas. D'une manière générale, avoir un environnement de travail basé sur la +confiance est réellement appréciable (La première réaction des gens quand je +dis que je peux travailler à distance, c'est de me demander comment ils font +pour être sur que je travaille. Et la réponse est… il n'y en a pas).</p> +<p>J'ai encore un peu de mal à savoir quels indicateurs utiliser pour savoir si je +suis &quot;productif&quot; ou non, mais j'ai globalement l'impression que je manque de +concentration et de discipline: beaucoup d'interruptions n'aident pas à se +concentrer.</p> +<p>La motivation fluctue aussi énormément: un jour on est super motivé, un autre +c'est juste impossible de la trouver. Après quelques expérimentations, le mieux +(pour moi) est d'avoir des horaires fixes, pour pouvoir séparer le travail du +reste, de ne pas hésiter à faire des pauses et d'écouter un peu ses envies et +son corps (si je suis crevé, ça ne sert à rien de se lever pour aller +travailler, il vaut mieux se reposer un peu pour être plus efficace ensuite, +par exemple).</p> +<p>J'ai essayé de tirer quelques enseignements de ces deux années:</p> +</div> +</div> +<div class="section" id="malheureusement-le-code-n-est-pas-propre"> +<h2>Malheureusement, le code n'est pas propre</h2> +<p>Je me rends compte que bien souvent je suis assez déçu de la qualité du code +que je regarde. Principalement parce que je ne suis pas capable de le +comprendre rapidement. Spécifiquement, ça m'est arrivé avec certaines parties +de <a class="reference external" href="https://github.com/mozilla/zamboni">Zamboni</a>, le code du <a class="reference external" href="http://marketplace.firefox.com">Marketplace</a> dont je parlais plus haut, avec certaines +parties de Talkilla ou alors le code de Firefox lui même.</p> +<p>C'était extrêmement frustrant pour moi de découvrir que le code écrit à Mozilla +n'était pas exemplaire. Tout le code qui est ajouté à l'heure actuelle est +revu, corrigé et validé par des pairs, mais un certain nombre de projets ont un +historique assez lourd qui rends leur structure complexe.</p> +<p>Je réalise donc que mon travail n'est pas uniquement de savoir écrire du code +propre, mais également de réussir à comprendre du code que je considère comme +&quot;sale&quot; (quitte à l'améliorer au passage !).</p> +<p>Et c'est pas du gâteau; je m'attendais à réussir à comprendre des projets +complexes facilement, mais aucun miracle de ce coté là. Il faut réussir +à rester concentré pendant suffisamment longtemps pour pouvoir tirer tous les +fils et commencer à démêler… Pas facile !</p> +</div> +<div class="section" id="apprendre-est-un-processus-actif"> +<h2>Apprendre est un processus actif</h2> +<p>Il est facile de passer à coté de l'apprentissage. Être entouré de gens +talentueux ne suffit pas pour continuer à apprendre.</p> +<p>Savoir reconnaitre un échec est nécessaire. Dire que l'on comprends pour éviter +de passer pour un idiot est un biais qui se prends assez rapidement, et qu'il +faut éviter à tout prix.</p> +<p>Surtout au début, c'était une erreur que je faisais énormément, une question +d'égo probablement.</p> +<p>Il y a une espèce de honte de ne pas savoir, alors que tout le monde autour +sait ou en tout cas semble savoir. Bien souvent, les gens autour ne savent pas +non plus, ce qui mène à des discussions de comptoir, sans trop savoir pourquoi.</p> +<p>Connaître ses limites techniques est un bon début pour pouvoir les surpasser. +Chercher à les rencontrer est un processus actif.</p> +<p>Le manque de temps m'empêche bien souvent de pouvoir prendre un livre technique +et de pouvoir l'apprécier. Je ne sais pas exactement pourquoi, peut être par +sur-dose, mais je n'ai ouvert que quelques rares livres techniques durant ces +deux années. Et j'aimerais bien que ça change !</p> +</div> +<div class="section" id="assez-bien-est-suffisant"> +<h2>&quot;Assez bien&quot; est suffisant</h2> +<p>La culture de l'excellence se mets parfois au milieu du chemin. On oublie +souvent que &quot;le mieux est l'ennemi du bien&quot;.</p> +<p>Rien ne sert de faire des commits parfaits tout le temps. Quand j'ai besoin de +&quot;hacker&quot; sur un projet, je ne voulais d'abord pas tout péter, par peur de ne +plus m'y retrouver.</p> +<p>Mon approche actuelle est bien différente: on mets les mains dans le cambouis +jusqu'à ce que ça marche, et ensuite on répare les dégâts. Enfin… dans une +certaine mesure hein !</p> +</div> +<div class="section" id="ecrire-des-boites-a-outils-et-non-pas-des-frameworks"> +<h2>Écrire des boites à outils et non pas des frameworks</h2> +<p>Écrire des frameworks force les utilisateurs à les utiliser, et à les connaitre +dans les moindres recoins. Heureusement, il existe déjà énormément de +frameworks qui pour la plupart font très bien leur travail. Ce qui nous manque +ce n'est pas plus de frameworks, mais bel et bien plus de boites à outils.</p> +<p>Une boite à outil prends un problème bien défini et propose une solution pour +ce problème. Une boite à outils est, en mon sens, ce qu'on appelle une +bibliothèque. Pas besoin de réécrire tout votre projet pour utiliser ma +nouvelle bibliothèque afin de profiter des fonctionnalités qu'elle apporte +(alors que c'est le cas avec un framework, justement).</p> +</div> +<div class="section" id="etre-le-moteur-de-son-propre-changement"> +<h2>Être le moteur de son propre changement</h2> +<p>Facile à dire, héhé ! D'une manière générale, je me rends compte qu'il est +facile de se plaindre sans pour autant être moteur du changement que l'on +souhaite voir arriver.</p> +<p>Ça vaut le coup de se donner la peine de faire changer les choses, surtout +à Mozilla, parce que le changement n'est pas seulement vu d'un mauvais œil.</p> +<p>Pour que les choses évoluent, il faut être force de proposition. Se plaindre +n'a jamais servi à rien si ce n'est pas suivi d'actes ;)</p> +<p>Je dis de temps en temps que Mozilla est une &quot;do-o-cratie&quot; (celui qui fait +à raison), et je le pense de plus en plus. Quand j'ai envie que quelque chose +soit fait, et bah… il faut le faire !</p> +</div> +<div class="section" id="ne-pas-chercher-a-avoir-raison"> +<h2>Ne pas chercher à avoir raison</h2> +<p>Peu importe qui a raison, l'important n'est pas de chercher à montrer que tu +sais, mais de trouver ce qui est juste. Ça parait peut être évident, mais bien +souvent on cherche à se mettre en avant, au détriment du projet… Allez, gardons +nos égos de coté ;)</p> +</div> +<div class="section" id="arreter-le-negativisme"> +<h2>Arrêter le négativisme</h2> +<p>Il est très facile de se laisser embarquer dans le négativisme. Il y a toujours +des choses qui ne vont pas, et probablement il y en aura toujours. Ce ne sont +pas des raisons suffisantes pour perdre le moral. Identifier les points faibles +est important est permet de savoir ce qu'il est nécessaire d'améliorer, mais +regarder les choses du coté positif (et il y en a nécessairement un !) est +indispensable !</p> +<p>À plusieurs reprises je me suis retrouvé dans des crises de négativisme, pour +un tas de raisons différentes. La meilleure manière de s'en sortir: en causer +et trouver des solutions, prendre le problème à bras le corps, et ne pas +considérer que c'est un problème sur lequel on a aucune prise possible.</p> +<div class="section" id="la-suite"> +<h3>La suite ?</h3> +<p>Je n'ai aucune idée d'à quoi va ressembler la suite, et c'est justement ce que +j'apprécie et qui m'effraie en même temps…</p> +<p>Je fais actuellement énormément de Javascript et je travaille sur des +projets qui semblent avoir plus de sens qu'avant (même si je vois déjà des +choses que je souhaiterais améliorer, mais chaque chose en son temps). Donc +techniquement j'apprends et dans ma quête de faire des produits qui touchent un +utilisateur.</p> +<p>Depuis quelques semaines, je peux travailler une journée par semaine sur un +projet qui me tiens vraiment à cœur: daybed (<a class="reference external" href="http://daybed.rtfd.org">http://daybed.rtfd.org</a>). +L'objectif est de faire en sorte que le projet avance et soit utilisé au sein +de mozilla.</p> +<p>Avant toute autre chose, il faudra faire des changements de &quot;pitch&quot; pour qu'il +soit plus simple d'expliquer ce que Daybed souhaite faire, mais… c'est une autre +histoire.</p> +</div> +</div> +Le revenu de base2013-10-03T00:00:00+02:002013-10-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-10-03:/le-revenu-de-base.html<iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra …</p><iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra pas suffire à toute la population. En refusant +l'idée du RDB, on est obligé de croire en la croissance économique.</p> +<p>Différence entre une approche qantitative du travail VS une approche sociale.</p> +<p>La croissance éco ≠ croissance de l'emploi.</p> +<p>Parallelle entre le RDB et la déclaration des droits de l'homme. &quot;Et qui voudra +faire le sale boulot ?&quot;</p> +<p>Utopie veut dire le &quot;non lieu&quot;, le lieu qu'on à pas encore trouvé ici sur +terre, à part dans notre imaginaire.</p> +<p>Agriculture: Il y à 100 ans, qqn qui travaillait dans l'agriculture produisait assez pour +3 autres personnes. ajd un agriculteur produit assez pour 120 personnes, via +des machines énormes et à la rationalisation.</p> +<p>Rationalisation: moins d'emploi.</p> +<p>La condition de pouvoir refuser un travail est très importante.</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Le financmenet est acquis, la dificulté c'est la liberté</p> +<p class="attribution">&mdash;NA</p> +</blockquote> +<blockquote> +<p>Il faut en finir avec cette idée fausse, selon laquelle seul le travail +rémunéré constitue une contribution méritoire à la société, en réalité, c'est +souvent exactement l'inverse.</p> +<p class="attribution">&mdash;Katja Kipping, membre du parlement allemand.</p> +</blockquote> +<blockquote> +<p>Si les gens on déjà une sécurité matérielle, ils sont plus difficiles +à corrompre.</p> +<p class="attribution">&mdash;Katja Kipping</p> +</blockquote> +<blockquote> +<p>Soutenir les populations sans poser de condition. c'est un principe qui à la +longe, devra s'imposer. Mais il lui faudra d'abord affronter les droits et +privilèges dont on bénéficie aujourd'hui.</p> +<p class="attribution">&mdash;Anonyme.</p> +</blockquote> +<blockquote> +Si les revenus étaient uniquement lié au travail, il faudrait donner les plus +hauts revenus aux machines.</blockquote> +<p>Le sens de l'économie, c'est de libérer l'homme du travail Beaucoup de gens qui +ont une &quot;place de travail&quot;, n'ont en réalité qu'une &quot;place de revenu&quot;.</p> +</div> +<div class="section" id="chiffres"> +<h2>Chiffres</h2> +<p>Un sondage à été effectué. La question est: &quot;Si vous aviez un revenu de base, +est-ce que vous iriez encore travailler ?&quot;</p> +<ul class="simple"> +<li>~60% disent oui</li> +<li>30% répondent oui, mais plus à plein temps.</li> +<li>10% pour faire autre chose.</li> +</ul> +<p>Avec une question différente:</p> +<p>&quot;Si on instaurait un revenu de base, est-ce que vous pensez que les autres +iraient travailler ?&quot;</p> +<ul class="simple"> +<li>~80% répondent non.</li> +</ul> +<p>C'est un changement aussi dans les modes d'éducation, on nous enseigne à être +&quot;employable&quot;, et non pas à apprendre quelque chose qui nous interesse. Les gens +ont peur de ne pas trouver du travail.</p> +</div> +<div class="section" id="ressources"> +<h2>Ressources</h2> +<ul class="simple"> +<li>Le sens commun, Thomas Payne.</li> +<li>Peter Ulrich</li> +</ul> +</div> +<div class="section" id="comment-financer-le-rdb"> +<h2>Comment financer le RDB</h2> +<p>Si l’on se fie à son produit intérieur brut (PIB), la France est aujourd’hui le +cinquième pays le plus riche du monde. En 2010, le revenu disponible (après +versement des pres- tations sociales et prélèvement des impôts directs) s’y +élevait à 1 276 euros par mois et par personne, adultes et enfants confondus. +Nous disposons donc de ressources suffisantes pour garantir à chaque individu 1 +276 euros si l’on décidait d’opérer un partage strictement égalitaire. C’est +nettement plus que le seuil de pauvreté actuel, fixé en France à 60 % du revenu +médian (1), soit 960 euros par adulte. Qui peut le plus pouvant le moins, la +France a donc sans nul doute les moyens d’assurer à tous ses résidents un +revenu au moins égal au seuil de pauvreté.</p> +</div> +<div class="section" id="a-reculons-par-andre-gorz"> +<h2>À Reculons, par André Gorz.</h2> +<p>(Paru dans le monde diplomatique de Juin 1990)</p> +<p><em>Proche de Jean-Paul Sartre, cofondateur, en 1964, du Nouvel Observateur, le +philosophe André Gorz (1923-2007) s’est converti progressivement à un +écosocialisme dont il est devenu l’un des principaux théoriciens. En 1990, dans +nos colonnes, sous le titre « Pourquoi la société salariale a besoin de +nouveaux valets », il formulait une critique de l’idéologie du travail qui +devait l’amener quelques années plus tard à se prononcer en faveur d’un revenu +d’existence.</em></p> +<p>Dans l’ensemble des pays capitalistes d’Europe, on produit trois à quatre fois +plus de richesses qu’il y a trente-cinq ans ; cette production n’exige pas +trois fois plus d’heures de travail, mais une quantité de travail beaucoup plus +faible. (...)</p> +<p>Nous sortons de la civilisation du travail, mais nous en sortons à reculons, et +nous entrons à reculons dans une civilisation du temps libéré, incapables de la +voir et de la vouloir, incapables donc de civiliser le temps libéré qui nous +échoit, et de fonder une culture du temps disponible et une culture des +activités choisies pour relayer et compléter les cultures techniciennes et +profes- sionnelles qui dominent la scène. (...)</p> +<p>Pour près de la moitié de la population active, l’idéologie du travail est +devenue une mauvaise farce ; l’identification au travail est désormais +impossible, car le système économique n’a pas besoin ou n’a pas un besoin +régulier de leur capacité de travail. La réalité que nous masque l’exaltation +de la « ressource humaine », c’est que l’emploi stable, à plein temps, durant +toute l’année et toute la vie active, devient le privilège d’une minorité. +Pour [les autres], le travail cesse d’être un métier qui intègre dans une +communauté productive et définit une place dans la société. Ce que le patronat +appelle « flexibilité » se traduit pour les salariés par la précarité. (...)</p> +<p>Que doit être une société dans laquelle le travail à plein temps de tous les +citoyens n’est plus nécessaire, ni économiquement utile ? Quelles priorités +autres qu’économiques doit-elle se donner ? Comment doit-elle s’y prendre pour +que les gains de productivité, les économies de temps de travail profitent à +tout le monde ? Comment peut-elle redistribuer au mieux tout le travail +socialement utile de manière à ce que tout le monde puisse travailler, mais +travailler moins et mieux, tout en recevant sa part des richesses socialement +produites ?</p> +<p>La tendance dominante est d’écarter ce genre de questions et de poser le +problème à l’envers : comment faire pour que, malgré les gains de productivité, +l’économie consomme autant de travail que par le passé ? Comment faire pour que +de nouvelles activités rémunérées viennent occuper ce temps que, à l’échelle de +la société, les gains de productivité libèrent ? A quels nouveaux domaines +d’activité peut-on étendre les échanges marchands pour remplacer tant bien que +mal les emplois supprimés par ailleurs dans l’industrie et les services +industrialisés ?</p> +<p>On connaît la réponse, pour laquelle les Etats-Unis et le Japon ont montré la +voie : le seul domaine dans lequel il est possible, en économie libérale, de +créer à l’avenir un grand nombre d’emplois, c’est celui des services aux +personnes. Le développement de l’emploi pourrait être illimité si l’on +parvenait à transformer en prestations de services rétribuées les activités que +les gens ont, jusqu’à présent, assumées chacun pour soi. Les économistes +parlent à ce sujet de « nouvelle croissance plus riche en emplois », de « +tertiarisation » de l’économie, de « société de services » prenant le relais de +la « société industrielle » (1). (...)</p> +<p>Le problème de fond auquel nous sommes confrontés est celui d’un au-delà de +l’économie et, ce qui revient au même, d’un au- delà du travail rémunéré. La +rationalisation économique libère du temps, elle continuera d’en libérer, et il +n’est plus possible, par conséquent, de faire dépendre le revenu des citoyens +de la quantité de travail dont l’économie a besoin. Il n’est plus possible, non +plus, de continuer à faire du travail rémunéré la source principale de +l’identité et du sens de la vie pour chacun.</p> +<p>La tâche d’une gauche, si gauche il doit y avoir, consiste à transformer cette +libération du temps en une liberté nouvelle et en des droits nouveaux : le +droit de chacun et de chacune de gagner sa vie en travaillant, mais en +travaillant de moins en moins, de mieux en mieux, tout en recevant sa pleine +part de la richesse socialement produite. Le droit, d’autre part, de travailler +de façon discontinue, intermittente, sans perdre durant les intermittences de +l’emploi le plein revenu – de manière à ouvrir de nouveaux espaces aux +activités sans but économique 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.</p> +</div> +Des carnets d'esquisse2013-08-16T00:00:00+02:002013-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-08-16:/des-carnets-desquisse-fr.html<p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir …</p><p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir un &quot;carnet&quot; et d'y jeter juste quelques +notes. Pas grand chose: mes quelques pensées ou alors des liens 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.</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'accueil, mais vous pouvez les +trouver dans <a class="reference external" href="https://blog.notmyidea.org/category/notes.html">la section notes</a>.</p> +<p>Je ne sais pas encore si il s'agit du meilleur endroit pour ça, mais peu importe, +essayons. A bas la pudeur rédactionelle.</p> +<p>J'ai du au passage chambouler un peu vos agrégateurs, pardonnez moi :)</p> +<div class="section" id="le-retour-des-commentaires"> +<h2>Le retour des commentaires</h2> +<p>Au passage, je ne me rappelle plus quand exactement, mais j'avais décidé de +supprimer les commentaires de cet espace. Paf, apu. Comme ça, sans prévenir.</p> +<p>Les raisons en étaient à la fois techniques (je ne souhaitait pas avoir recours +à disqus qui est un silo propriétaire de plus) et parce que je considérais que +les commentaires n'avaient que peu d'intérêt. Ceci dit, le manque d'échange me +manque; j'aimerais bien savoir ce que vous pensez de ce que j'écris des fois, +et avoir des débats si nos opinions divergent.</p> +<p>Et puis bon, partager dans un seul sens, c'est un peu dommage !</p> +<p>Il est maintenant possible, avec <a class="reference external" href="http://talka.tv">talka.tv</a> d'héberger soi +même ses commentaires. J'ai dans l'idée d'héberger une instance de ce service +sur <cite>discus.notmyidea.org</cite>, 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 !)</p> +</div> +Notes: Économie libidinale et économie politique2013-07-06T00:00:00+02:002013-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-06:/notes-economie-libidinale-et-economie-politique.html<p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un …</p><p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un autre comportement s'est développé: le modèle &quot;collaboratif et contributif&quot;. +Ce modèle ne se repose pas sur la consommation mais sur l'implication et la +collaboration. Ce modèle est induit par internet, qui ne repose plus sur +l'opposition production / consommation.</p> +<p>Sur internet nous ne sommes pas des simples consommateurs, puisque vous êtes un +expéditeur / distributeur.</p> +<p>Le changement prduit par internet est le fait que les gens ne sont plus +simplement des consommateurs,mais sont également producteurs de contenus +/ viennent améliorer les contenus existants.</p> +<p>Note perso: quid du culte de la personalité qui en ressort ? Ce qu'il apelle +l'écologie relationelle ?</p> +<p>Quel est le manque que vient combler facebook par exemple ? Et quel est +l'impact que ces nouveaux réseaux ont sur les modèles relationels que l'ont +connait (famille, école, droit, etc.).</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Une révolution c'est le fait de faire une boucle est d'arriver au terme de +quelque chose. D'avoir clôt un cycle. La lune fait des révolutions aussi.</p> +<p>81% des Américains déclarent que le consumerisme est une plaie pour l'amérique +(d'après Juliet Score)</p> +</blockquote> +</div> +New year python meme, 20122013-07-01T00:00:00+02:002013-07-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-01:/new-year-python-meme-2012.html<p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this …</p><p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this year and +quite enjoyed it. I like the way they bring back some nice concepts on the +table, and how they compete with other frameworks. That's nicely decomposed and +everything fits together really well. I learned a bit about its internal +routing mechanism when working on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, and +it's really well done.</p> +<p><strong>2. What new programming technique did you learn in 2012 ?</strong></p> +<p>I learned about asynchronous programming, something I wasn't really aware of. +(Yes, that's a shame). This was really helpful to understand some bits of +<a class="reference external" href="http://circus.io">Circus</a>. I also started to learn about some related +concepts present in <a class="reference external" href="http://golang.org">go</a> or in <a class="reference external" href="http://erlang.org">erlang</a> with <a class="reference external" href="http://en.wikipedia.org/wiki/Actor_model">the actor model</a></p> +<p><strong>3. Which open source project did you contribute to the most in 2012 ? What did +you do ?</strong></p> +<p>I worked a bunch on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a> and <a class="reference external" href="http://circus.io">Circus</a>, not as much as I would like, but that was two really +interesting projects. For Cornice, I completely <a class="reference external" href="http://blog.notmyidea.org/refactoring-cornice.html">refactored the internals</a> back in May, and since +that, I added support for <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a> +and am currently working on porting it to Python 3 and adding support for <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>. For Circus, I worked on the web interface and +on other bits of the projects related to stats.</p> +<p>I didn't contributed that much to <a class="reference external" href="http://getpelican.com">Pelican</a>, mainly +because I'm less excited about it than I was previously: the project is +working and needs to focus more on code quality than features. We started in +this direction, hopefully it will pay-off; but I committed a lot less code than +previously.</p> +<p><strong>4. Which Python blog or website did you read the most in 2012 ?</strong></p> +<p>I really don't know. I found some interesting python-related news on <a class="reference external" href="http://news.ycombinator.com/">hacker +news</a> and on the printed version as well, +<a class="reference external" href="http://hackermonthly.com/">hacker monthly</a>. Twitter and IRC got me some +interesting articles as well.</p> +<p><strong>5. What are the three top things you want to learn in 2013 ?</strong></p> +<p>On the computer science side, I want to learn more about other paradigms, maybe +in other languages. I like python, but I want to learn about other concepts, +maybe some of them don't really fit with python.</p> +<p>For instance, I don't know that much about pattern matching or about the actor +model. Well I know what it is, but I would like to make good use of them in +order to have something nice and useful.</p> +<p>Also, I want to learn how to make a product. From scratch. Which means +designing, implementing and maintaining something. Maybe this will be the case +with <a class="reference external" href="https://github.com/spiral-project/daybed">daybed</a> ? Who knows.</p> +<p>I want to get better at building communities. Working with others is something +that can be complex and quite hard sometimes. I want to learn how to handle +this better.</p> +<p>On the other side, I want to learn about tons of other non-tech things: taking +pictures, finding a good balance between life and work, working with children, +teaching and animating workshops, writing articles, be better at reading (being +critic when I'm thinking!).</p> +<p><strong>6. What is the top software, application or library you wish someone would +write in 2013 ?</strong></p> +<p>The one missing thing, IMO, is a <strong>good</strong> webmail reader, in python. One we +could contribute to, one we could write features for, and one that could come +and compete with gmail, in term of features of UI.</p> +<p>However, most of the time, I'm just impressed by the new ideas that come from +others. I would like to have a library to handle the actor model in a nice way +in Python, I would like to see packaging fixed in python :-)</p> +<p>Want to do your own list? Here's how:</p> +<ul class="simple"> +<li>copy-paste the questions and answer to them in your blog</li> +<li>tweet it with the #2012pythonmeme hashtag</li> +</ul> +François Elie : Quelle école pour la société de l’information ?2013-06-14T00:00:00+02:002013-06-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-06-14:/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html<p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens …</p></blockquote><p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens font ça entre eux et on n’est pas non plus +dans une école de l’apprentissage où l’école a pour but de donner un métier, un +bagage utilisable. L’école ne sert évidemment pas à ça. D’ailleurs heureusement +parce que sinon on n’enseignerait pas la philosophie qui ne sert à rien à part +fabriquer des profs de philosophie !</p> +<p>On n’a pas besoin de tableau numérique pour enseigner l’informatique elle-même +pour enseigner la science. De la même façon on n’a pas besoin de machine à +calculer pour enseigner les mathématiques. Évidemment ! On n’a pas besoin d’une +machine à calculer pour savoir faire une division. Au contraire, surtout pas !</p> +<p>Il faut cesser d’opposer l’enseignement de la programmation d’une part et +l’enseignement des usages, c’est important mais ça c’est l’école des maîtres et +des esclaves. Ce qu’il faut enseigner, vite et à tous, c’est la science, pas la +technologie ou l’usage. C’est en amont de la programmation, l’algorithmique. +C’est, en amont de telle instanciation, du codage, du chiffrement, la théorie, +quelque chose qui comme les maths n’ont besoin que d’une craie et d’un tableau +noir.</p> +<p>Ce n'est pas un hasard si le mot &quot;numérique&quot; à remplaçé le mot &quot;informatique&quot;, +c'est qu'on voudrait nous faire croire qu'il n'y a pas besoin de l'apprendre.</p> +</blockquote> +Des profils de confiance partout et pour tout ?2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/confiance-fr.html<p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site …</p><p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site et de les appeler soi même, chose maintenant automatisée.</p> +<p>Dès que cette décision à été prise, il y a eu des émules. Le site <a class="reference external" href="http://covoiturage-libre.fr">Covoiturage +Libre</a> à été d'ailleurs créé pour faire en sorte +de garder &quot;l'esprit&quot; du covoiturage. Bref ça jasait dans les chaumières.</p> +<p>Il y à peu, j'ai reçu un <em>couriel</em> contenant un lien vers une vidéo d'<a class="reference external" href="http://www.covoiturage.fr/blog/2013-confiance">une +conférence animée par le fondateur de covoiturage.fr</a>.</p> +<p>Ils semblent vouloir parler de confiance, alors ça m'intrigue, d'autant que la +présentation en question est donnée lors d'un évènement TEDx, auquel j'accorde +un certain crédit.</p> +<div class="section" id="un-capital-de-confiance"> +<h2>Un &quot;capital de confiance&quot;</h2> +<p>Cette vidéo parle entre autres du <em>capital de confiance</em> que nous pouvons +nous accorder les uns aux autres; et notamment du fait que ce capital de +confiance n'est malheureusement pas partagé au dela d'un cercle de +connaissances assez limité. Il reste dans notre cercle de connaissances proche, les +amis des amis.</p> +<p>C'est donc une chose regrettable, parce que ça nous fait perdre du temps (et +donc, <em>ohmygod</em> de l'argent) à tous pour construire cette confiance. Temps qui +pourrait être mieux employé.</p> +<p>La solution proposée, attention les yeux, est de faire appel un maximum aux +profils en ligne, une manière de &quot;prouver au monde&quot; que nous sommes des +personnes de confiance. Selon les termes de la présentation, nous pourrions +alors tous devenir des &quot;super héros du trust&quot;, des &quot;trustman&quot;.</p> +<p>Grâce à des profils en ligne ou monsieur et madame tout le monde pourraient +aller voter et donner leur avis sur les personnes qu'ils ont rencontré.</p> +</div> +<div class="section" id="l-avenement-du-paiement-en-ligne"> +<h2>L'avènement du paiement en ligne</h2> +<p>On nous dit maintenant que le paiement en ligne est une révolution, un moyen de +tracer le fait qu'il y à effectivement eu une transaction entre deux personnes; +et que donc il en deviendrait un outil pour vérifier que la confiance est bien +légitime, et non pas créée de toute pièce sur le profil de la personne en +question.</p> +<p>Plu</p> +<p>Plus exactement, ce qui est dit est que le paiement en ligne permet de +justifier qu'il y a bien eu transaction entre deux personnes, et que donc les +commentaires et &quot;notations&quot; effectuées sont donc légitimes.</p> +</div> +<div class="section" id="ce-n-est-pas-un-probleme-de-confiance"> +<h2>Ce n'est pas un problème de confiance !</h2> +<p>Bien que j'arrive à suivre le raisonnement, il soulève certaines questions :</p> +<p>Si j'accorde de la confiance à quelqu'un dans mon cercle de connaissances, +c'est justement parce qu'il fait partie de ce cercle de connaissances. Pas +parce qu'une personne que je ne connait pas me dit qu'il s'agit d'une personne +de confiance. En d'autres termes, <strong>pourquoi ne garderions nous pas ces +relations privilégiées de personne à personne ?</strong></p> +<p>Dans le cadre du covoiturage, j'arrive à comprendre le raisonnement du paiement +<em>à l'avance</em>, pour avoir souvent entendu parler de désistements à la dernière +minute de la part des voyageurs. Le paiement à l'avance permet d'éviter ce +genre de désagréments.</p> +<p>Mais cela n'as rien à voir avec la confiance, il s'agit d'engagement de la part +des deux parties.</p> +<p>Et c'est bien ce qui semble poser problème: lorsqu'on s'attend à partager le +prix d'un trajet avec quelqu'un, c'est bien d'avoir quelque chose qui nous +y engage. J'aime beaucoup l'idée de payer une fois dans la voiture, de garder +cette transaction manuelle; et de laisser peu de place au paiements en ligne +dans cette histoire, mais je n'ai pas d'autre solution miracle.</p> +<p>En tout cas, la question n'est pas la question de savoir avec qui on embarque, +mais bel et bien la question de l'engagement des deux parties.</p> +<p>Nous sommes malheureusement dans une société qui est dirigée par la peur. On +à peur de se faire agresser par le gars qui tends le pouce sur le bord de la +route, peur de se faire envoyer un produit qui ne fonctionne pas via Amazon, +etc.</p> +<p>En poussant l'idée dans ses retranchements, j'aurais bientôt peur de mes +voisins alors je ne leur parlerais plus, parce qu'ils n'ont pas leur profil +disponible en ligne ou parce que quelqu'un à eu une mauvaise expérience avec +eux ?</p> +<p>Exposer des choses qui relèvent de ma vie privée en ligne de la sorte me +pose des problèmes éthiques: d'abord parce que je ne veux pas juger les gens +a priori, ensuite parce que l'expérience d'une personne n'est peut-être pas +représentative, tout simplement.</p> +<p>Donc non, ce n'est pas un problème de confiance, il s'agit d'un problème +d'engagement, dans le cadre du covoiturage, et les profils en ligne n'ont rien +à faire la dedans. Le principe du paiement à l'avance me semble intéressant, +mais il n'est à mon avis pas lié au profils en ligne.</p> +<p>La vidéo termine sur un &quot;libérez la valeur de la confiance&quot;. Oui, mais la +libérer pour qui ? Quels sont les problèmes liés à cette confiance rendue +nécessaire partout et pour tout ? Cela ne nous ferait-il pas évoluer uniquement +dans des cercles fermés ? Quelle place laisser à l'inconnu, à la surprise ?</p> +<p>Cette volonté de &quot;confiance partout&quot; semble découler tout droit des délires +sécuritaires que l'on nous sert à toutes les sauces. Et maintenant cela +serait rendu accessible à tous grâce à &quot;l'intelligence collective&quot;; gommant au +passage les différences de valeur; Préférant éviter de rencontrer les inconnus +aux profils &quot;légers&quot;.</p> +<p>Je sais pas vous, mais elle me fait peur cette idée.</p> +</div> +Implementing CORS in Cornice2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/cross-origin-in-cornice.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In other +words, if you have a page served from the domain <cite>lolnet.org</cite>, it will not be +possible for it to get data from <cite>notmyidea.org</cite>.</p> +<p>Well, it's possible, using tricks and techniques like <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a>, but that doesn't work all the time (see +<a class="reference external" 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's API.</p> +<p>Thankfully, there is a nicer way to do this, namely, &quot;Cross Origin +Resource-Sharing&quot;, or <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>.</p> +<div class="section" id="you-want-an-icecream-go-ask-your-dad-first"> +<h2>You want an icecream? Go ask your dad first.</h2> +<p>If you want to use CORS, you need the API you're querying to support it; on the +server side.</p> +<p>The HTTP server need to answer to the <cite>OPTIONS</cite> verb, and with the appropriate +response headers.</p> +<p><cite>OPTIONS</cite> is sent as what the authors of the spec call a &quot;preflight request&quot;; +just before doing a request to the API, the <em>User-Agent</em> (the browser most of +the time) asks the permission to the resource, with an <cite>OPTIONS</cite> call.</p> +<p>The server answers, and tell what is available and what isn't:</p> +<img alt="The CORS flow (from the HTML5 CORS tutorial)" src="images/cors_flow.png" /> +<ul class="simple"> +<li>1a. The User-Agent, rather than doing the call directly, asks the server, the +API, the permission to do the request. It does so with the following headers:<ul> +<li><strong>Access-Control-Request-Headers</strong>, contains the headers the User-Agent +want to access.</li> +<li><strong>Access-Control-Request-Method</strong> contains the method the User-Agent want +to access.</li> +</ul> +</li> +<li>1b. The API answers what is authorized:<ul> +<li><strong>Access-Control-Allow-Origin</strong> the origin that's accepted. Can be <cite>*</cite> or +the domain 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 methods.</li> +<li><strong>Access-Allow-Headers</strong> a list of allowed headers, for all of the +methods, since this can be cached as well.</li> +</ul> +</li> +<li><ol class="first arabic" start="2"> +<li>The User-Agent can do the &quot;normal&quot; request.</li> +</ol> +</li> +</ul> +<p>So, if you want to access the <cite>/icecream</cite> resource, and do a PUT there, you'll +have the following flow:</p> +<pre class="literal-block"> +&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 +</pre> +<p>You can see that we have an <cite>Origin</cite> Header in the request, as well as +a <cite>Access-Control-Request-Methods</cite>. We're here asking if we have the right, as +<cite>notmyidea.org</cite>, to do a <cite>PUT</cite> request on <cite>/icecream</cite>.</p> +<p>And the server tells us that we can do that, as well as <cite>GET</cite> and <cite>DELETE</cite>.</p> +<p>I'll not cover all the details of the CORS specification here, but bear in mind +than with CORS, you can control what are the authorized methods, headers, +origins, and if the client is allowed to send authentication information or +not.</p> +</div> +<div class="section" id="a-word-about-security"> +<h2>A word about security</h2> +<p>CORS 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 CORS, so you'll need to +write a proxy yourself, to provide this.</p> +<p>Secondly, if misunderstood, CORS 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're authorizing.</p> +<p>An incorrectly secured CORS 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 VPN 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 want.</p> +</div> +<div class="section" id="how-this-is-different-from-jsonp"> +<h2>How this is different from JSONP?</h2> +<p>You may know the <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> protocol. JSONP +allows cross origin, but for a particular use case, and does have some +drawbacks (for instance, it's not possible to do DELETEs or PUTs with JSONP).</p> +<p>JSONP exploits the fact that it is possible to get information from another domain +when you are asking for javascript code, using the <cite>&lt;script&gt;</cite> element.</p> +<blockquote> +Exploiting the open policy for &lt;script&gt; elements, some pages use them to +retrieve JavaScript code that operates on dynamically generated +JSON-formatted data from other origins. This usage pattern is known as +JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. +They are evaluated by the JavaScript interpreter, not parsed by a JSON +parser.</blockquote> +</div> +<div class="section" id="using-cors-in-cornice"> +<h2>Using CORS in Cornice</h2> +<p>Okay, things are hopefully clearer about CORS, let's see how we +implemented it on the 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 CORS support as +well.</p> +<p>In Cornice, you define a service like this:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>To add CORS support to this resource, you can go this way, with the +<cite>cors_origins</cite> parameter:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> +</pre></div> +<p>Ta-da! You have enabled CORS for your service. <strong>Be aware that you're +authorizing anyone to query your server, that may not be what you want.</strong></p> +<p>Of course, you can specify a list of origins you trust, and you don't need +to stick with <cite>*</cite>, which means &quot;authorize everyone&quot;.</p> +<div class="section" id="headers"> +<h3>Headers</h3> +<p>You can define the headers you want to expose for the service:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> + +<span class="nd">@foobar.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> +</pre></div> +<p>I've done some testing and it wasn't working on Chrome because I wasn't +handling the headers the right way (The missing one was <cite>Content-Type</cite>, 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 developing.</p> +<p>So I introduced an <cite>expose_all_headers</cite> flag, which is set to <cite>True</cite> by +default, if the service supports CORS.</p> +</div> +<div class="section" id="cookies-credentials"> +<h3>Cookies / Credentials</h3> +<p>By default, the requests you do to your API endpoint don't include the +credential information for security reasons. If you really want to do that, +you need to enable it using the <cite>cors_credentials</cite> parameter. You can activate +this one on a per-service basis or on a per-method basis.</p> +</div> +<div class="section" id="caching"> +<h3>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's not redone before each actual call.</p> +<p>The caching period is defined by the server, using the <cite>Access-Control-Max-Age</cite> +header. You can configure this timing using the <cite>cors_max_age</cite> parameter.</p> +</div> +<div class="section" id="simplifying-the-api"> +<h3>Simplifying the API</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 CORS-policy for your services, that +can be a bit tedious to pass these to your services all the time.</p> +<p>I introduced another way to pass the CORS policy, so you can do something like +that:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">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> +</pre></div> +</div> +</div> +<div class="section" id="comparison-with-other-implementations"> +<h2>Comparison with other implementations</h2> +<p>I was curious to have a look at other implementations of CORS, in +django for instance, and I found <a class="reference external" href="https://gist.github.com/426829.js">a gist about it</a>.</p> +<p>Basically, this adds a middleware that adds the &quot;rights&quot; headers to the answer, +depending on the request.</p> +<p>While this approach works, it's not implementing the specification completely. +You need to add support for all the resources at once.</p> +<p>We can think about a nice way to implement this specifying a definition of what's +supposed to be exposed via CORS and what shouldn't directly in your settings. +In my opinion, CORS support should be handled at the service definition level, +except for the list of authorized hosts. +Otherwise, you don't know exactly what's going on when you look at the definition of the service.</p> +</div> +<div class="section" id="resources"> +<h2>Resources</h2> +<p>There are a number of good resources that can be useful to you if you want to +either understand how CORS works, or if you want to implement it yourself.</p> +<ul class="simple"> +<li><a class="reference external" href="http://enable-cors.org/">http://enable-cors.org/</a> is useful to get started when you don't know anything +about CORS.</li> +<li>There is a W3C wiki page containing information that may be useful about +clients, common pitfalls etc: <a class="reference external" href="http://www.w3.org/wiki/CORS_Enabled">http://www.w3.org/wiki/CORS_Enabled</a></li> +<li><em>HTML5 rocks</em> has a tutorial explaining how to implement CORS, with <a class="reference external" 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 class="reference external" href="http://caniuse.com/#search=cors">clients support-matrix for this feature</a>.</li> +<li>About security, <a class="reference external" href="https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity">check out this page</a></li> +<li>If you want to have a look at the implementation code, check <a class="reference external" href="https://github.com/mozilla-services/cornice/pull/98/files">on github</a></li> +</ul> +<p>Of course, the W3C specification is the best resource to rely on. This +specification isn't hard to read, so you may want to go through it. Especially +the <a class="reference external" href="http://www.w3.org/TR/cors/#resource-processing-model">&quot;resource processing model&quot; section</a></p> +</div> +Status board2012-12-29T00:00:00+01:002012-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-29:/status-board-fr.html<p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org …</cite></p><p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org</cite>, mon serveur.</p> +<p>Jusqu'à très récemment, rien de tout ça n'était sauvegardé, et non plus monitoré. +Après quelques recherches, je suis tombé sur <a class="reference external" href="http://www.stashboard.org/">stashboard</a>, un &quot;status board&quot; qu'il est bien fait. Le seul +problème, c'est écrit pour se lancer sur GAE, <em>Google App Engine</em>. +Heureusement, c'est open-source, et ça a été forké pour donner naissance +à <a class="reference external" href="https://github.com/bfirsh/whiskerboard">whiskerboard</a> (la planche +moustachue, pour les non anglophones).</p> +<img alt="Capture d'écran du site." src="images/status_board.png" /> +<div class="section" id="verifier-le-statut-des-services"> +<h2>Vérifier le statut des services</h2> +<p>Donc, c'est chouette, c'est facile à installer, tout ça, mais… mais ça ne fait +en fait pas ce que je veux: ça ne fait que m'afficher le statut des services, +mais ça ne vérifie pas que tout est bien &quot;up&quot;.</p> +<p>Bon, un peu embêtant pour moi, parce que c'est vraiment ça que je voulais. Pas +grave, je sais un peu coder, autant que ça serve. J'ai ajouté quelques +fonctionnalités au soft, qui sont disponibles sur mon fork, sur +github:: <a class="reference external" href="https://github.com/ametaireau/whiskerboard">https://github.com/ametaireau/whiskerboard</a> .</p> +<p>Entres autres, il est désormais possible de lancer <a class="reference external" 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 spécifique.</p> +<p>C'é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 dépote).</p> +<p>Les modifications sont assez simples, vous pouvez aller jeter un œil aux +changements ici: +<a class="reference external" href="https://github.com/ametaireau/whiskerboard/compare/b539337416...master">https://github.com/ametaireau/whiskerboard/compare/b539337416...master</a></p> +<p>En gros:</p> +<ul class="simple"> +<li>ajout d'une <cite>connection_string</cite> aux services (de la forme +protocol://host:port)</li> +<li>ajout d'une commande <cite>check_status</cite> qui s'occupe d'itérer sur les services et +de lancer des taches celery qui vont bien, en fonction du protocole</li> +<li>ajout des taches en question</li> +</ul> +</div> +<div class="section" id="deploiement"> +<h2>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, forcément.</p> +<p>Après un essai (plutôt rapide en fait) sur <a class="reference external" href="http://heroku.com">heroku</a>, je me +suis rendu compte qu'il me fallait payer pas loin de 35$ par mois pour avoir un +process <cite>celeryd</cite> qui tourne, donc j'ai un peu cherché ailleurs, pour +finalement déployer la chose chez <a class="reference external" href="https://www.alwaysdata.com/">alwaysdata</a></p> +<p>Après quelques péripéties, j'ai réussi à faire tourner le tout, ça à été un peu +la bataille au départ pour installer virtualenv (j'ai du faire des changements +dans mon <cite>PATH</cite> pour que ça puisse marcher), voici mon <cite>.bash_profile</cite>:</p> +<pre class="literal-block"> +export PYTHONPATH=~/modules/ +export PATH=$HOME/modules/bin:$HOME/modules/:$PATH +</pre> +<p>Et après y'a plus qu'à installer avec <cite>easy_install</cite>:</p> +<pre class="literal-block"> +easy_install --install-dir ~/modules -U pip +easy_install --install-dir ~/modules -U virtualenv +</pre> +<p>Et à créer le virtualenv:</p> +<pre class="literal-block"> +virtualenv venv +venv/bin/pip install -r requirements.txt +</pre> +<p>Dernière étape, la création d'un fichier <cite>application.wsgi</cite> qui s'occupe de +rendre l'application disponible, avec le bon venv:</p> +<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span> +<span class="kn">import</span> <span class="nn">sys</span> + +<span class="n">activate_this</span> <span class="o">=</span> <span class="s1">&#39;/home/lolnet/venv/bin/activate_this.</span> +<span class="nb">execfile</span><span class="p">(</span><span class="n">activate_this</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="vm">__file__</span><span class="o">=</span><span class="n">activate_this</span><span class="p">))</span> + +<span class="n">paths</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;/home/lolnet/public&#39;</span><span class="p">,]</span> + +<span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">paths</span><span class="p">:</span> + <span class="k">if</span> <span class="n">path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="p">:</span> + <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> + + <span class="kn">import</span> <span class="nn">django.core.handlers.wsgi</span> + <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;DJANGO_SETTINGS_MODULE&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;settings&#39;</span> + <span class="n">application</span> <span class="o">=</span> <span class="n">django</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIHandler</span><span class="p">()</span> +</pre></div> +</div> +<div class="section" id="ssl-et-requests"> +<h2>SSL et Requests</h2> +<p>Quelques tours de manivelle plus loin, j'ai un celeryd qui tourne et qui +consomme les taches qui lui sont envoyées (pour des questions de simplicité, +j'ai utilisé le backend <cite>django</cite> de celery, donc pas besoin d'AMQP, par +exemple).</p> +<p>Problème, les ressources que je vérifie en SSL (HTTPS) me jettent. Je sais pas +exactement pourquoi à l'heure qu'il est, mais il semble que lorsque je fais une +requête avec <a class="reference external" 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 <cite>CURL</cite> fonctionnent, donc j'ai fait <a class="reference external" href="https://github.com/ametaireau/whiskerboard/blob/master/board/tasks.py#L17">un fallback +vers CURL lorsque les autres méthodes échouent</a>. +Pas super propre, mais ça fonctionne.</p> +<p><strong>EDIT</strong> Finalement, il se trouve que mon serveur était mal configuré. +J'utilisais haproxy + stunnel, et la négiciation SSL se passait mal. Une fois +SSL et TLS activés, et SSLv2 désactivé, tout fonctionne mieux.</p> +</div> +<div class="section" id="et-voila"> +<h2>Et voilà</h2> +<p>Finalement, j'ai mon joli status-board qui tourne à merveille sur +<a class="reference external" href="http://status.lolnet.org">http://status.lolnet.org</a> :-)</p> +</div> +Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag: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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais …</p><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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais vous aussi ça vous +titille:</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.habicoop.fr/IMG/pdf/Memoire_hbtat_coop_Vaulx-2.pdf">L’Habitat Coopératif : Solution au problème de responsabilisation sociale des +copropriétaires sur la commune de Vaulx en Velin +?</a> - mémoire REPIQUET Anne +2005.</li> +<li>Un bouquin à lire avec plein d'infos: <a class="reference external" href="http://www.ecosociete.org/t101.php">Vivre autrement</a> de Diana Leafe Christian.</li> +<li>…</li> +</ul> +Languages2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/languages.html<p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe><p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe>Tricot2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/tricot.html<p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu …</p><p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu +près un rang d'endroit et j'arrive pas à enchainer sur l'envers pour réussir +à faire un point jersey (jersey c'est un rang endroit puis un rang envers).</p> +<p>Enfin bref, si jamais ça vous botte vous aussi, voila quelques ressources que +j'ai trouvé sur internet (en plus des conseils avisés de maman chérie™):</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.youtube.com/watch?v=VcGiBG2BNxo&amp;list=UUskaiVNnKf7amRb5OI5op_w">Montage des mailles &quot;normales&quot;</a></li> +<li><a class="reference external" href="http://www.youtube.com/watch?v=aIQtNN89pqA&amp;list=UUskaiVNnKf7amRb5OI5op_w">Le point jersey</a></li> +</ul> +<p>La nana explique plutôt bien et assez lentement. En espérant que ça prenne.</p> +Astuces SSH2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/astuces-ssh.html<div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s …</pre></div><div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') +PATH=.:\$PATH nc -w1 $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /') +</pre> +<p>On peut donc spécifier des &quot;sauts&quot; ssh du style:</p> +<pre class="literal-block"> +ssh root&#64;91.25.25.25+192.168.1.1 +</pre> +<p>Ensuite on peut essayer de rajouter:</p> +<pre class="literal-block"> +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é +</pre> +</div> +Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag: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'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial …</a></li></ul><p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de +ubuntu, j'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial Menu</a> vire les +boutons et textes en rapport avec le web social. J'en avais pas besoin +puisque je suis connecté à mon instant messenger dans un terminal, en +utilisant weechat.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/97/coverflow-alt-tab/">Coverflow Alt-Tab</a> change le +switcher d'applications par defaut. Je le trouve bien plus pratique que celui +par defaut puisqu'il me permet de voir &quot;en grand&quot; quelle est la fenêtre que +je vais afficher.</li> +<li><a class="reference external" 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'intègre niquel avec +Spotify, et ça c'est chouette.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/149/search-firefox-bookmarks-provider/">Rechercher dans les bookmarks firefox</a> +permet de… à votre avis ?</li> +</ul> +<p>Un peu moins utile mais sait on jamais:</p> +<ul class="simple"> +<li>“<a class="reference external" href="https://extensions.gnome.org/extension/130/advanced-settings-in-usermenu/">Advanced Settings in UserMenu</a>” +permet d'avoir un raccourci vers les paramètres avancés dans le menu +utilisateur (en haut à droite)</li> +<li>Une <a class="reference external" href="https://extensions.gnome.org/extension/409/gtg-integration/">intégration à Getting things Gnome</a> (un truc de +GTD). Je suis en train d'expérimenter avec cet outil, donc je ne sais pas +encore si ça va rester, mais pourquoi pas.</li> +</ul> +<p>Vous pouvez aller faire un tour sur <a class="reference external" href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> +pour en trouver d'autres à votre gout.</p> +"Groovy"2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/groovy.html<p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>C'est pour ça que j'ai du …</p><p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>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 ;)</p> +Notre dame des landes2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/notre-dame-des-landes.html<p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre …</p><p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre +2012:</p> +<ul class="simple"> +<li>Article dans le monde qui explique la complexité de la lutte sur place: <a class="reference external" href="http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html">http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html</a></li> +<li>autour de relations à la presse: +<a class="reference external" href="http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html">http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html</a></li> +<li>Notre-Dame-des-Landes : un pilote annonce un fiasco pour le futur aéroport <a class="reference external" href="http://www.bastamag.net/article2866.html">http://www.bastamag.net/article2866.html</a></li> +</ul> +Semences paysannes2012-12-20T00:00:00+01:002012-12-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-20:/semences-paysannes.html<p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité …</p><p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité en 1960 au sein de l'UPOV pour faire des textes pour s'approprié les selections qu'ils ont fait. Les textes ont été votés par les députés depuis: bien prové au lieu de bien collectif.</p> +<p>Les semenciers n'existent que depuis 150 ans. Ils revendiquent maintenant le monopole de selection.</p> +<p>Un catalogue est prévu pour les semences dites &quot;de conservation&quot; (alors qu'elles évoluent, conservation n'est pas un terme adapté). C'est la voie qui est possible pour pouvoir échanger des semences entre agriculteurs.</p> +<p>→ Quelles sont les semences de conservation depuis 2002 ? → Quid des semences paysannes, qui évoluent et que l'on garde d'année en année, en selectionnant les meilleures especes. → Existe-il un autre catalogue ? → Au niveau européen, quelles sontles contraintes d'inscription ? Gratuité demandée, qu'en est il ?</p> +<p>→ Relocalistion sur les terroirs des échanges.</p> +<p>→ Biodiversité serait tué par l'utilisation d'espèces inscrites.</p> +<p>Série de vidéos sur la paysannerie: <a class="reference external" href="http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86">http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86</a></p> +Lifestyle2012-11-05T00:00:00+01:002012-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-11-05:/lifestyle-fr.html<p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre …</p><p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre une vie connectée et +une vie <em>réelle</em> (oui, celle avec des vrais gens qui ont d'autres +préoccupations que l'informatique !). Comment réussir à trouver un juste +milieu entre le geek inconditionnel et le bon vivant, qui à du temps à +consacrer à autre chose qu'à son travail ?</p> +<div class="section" id="voyages"> +<h2>Voyages</h2> +<p>Un des premiers trucs que j'ai trouvé surprennant en arrivant à Mozilla, c'est +la fréquence des voyages que l'on peut être amené à avoir. Ah, c'est pour la +bonne cause, c'est tellement plus sympa d'avoir les collègues à coté pour +bosser, plutôt qu'à l'autre bout du monde. Mais quand même, si je le voulais, +entre les semaines de travail et les conférences, je pourrais être tous les +deux mois aux États-Unis !</p> +<p>Une aubaine, penserons certains. Voyager, c'est <em>cool</em> ! Bon, si on mets de +coté le cout écologique d'un voyage (nécessairement en avion), la chose qui me +dérange le plus c'est cette impression de venir pour repartir. Voyager, c'est +sympa, mais avoir le temps de prendre un rythme de vie différent, de rencontrer +des gens, de construire quelque chose, ça me manque.</p> +<p>Donc je décline quand je n'en ai pas l'envie, tout simplement. Je loupe des +choses intéressantes (<a class="reference external" href="http://pycon.us">PyCon</a> à Santa Clara avait vraiment l'air +chouette !), mais ça me permet également d'avoir plus de temps pour vivre là ou +j'habite, pour construire quelque chose localement. Et puis des évènements, il +y en à tellement en France et en Europe auquel je n'assiste pas que ça me fait +mal au cœur d'aller à l'autre bout du monde pour faire la même chose !</p> +<p>Bien sur, je serais amené à voyager. Et autant que faire se peut je le +ferais avec plaisir et je tenterais de rester un peu plus avant et après sur +place (plus question de faire un aller/retour en une semaine !), question de me +faire à l'atmosphère ! <a class="reference external" href="http://ziade.org">Tarek</a> est par exemple resté un mois à San Francisco +en janvier pour son dernier séjour, alors pourquoi ne pas prendre exemple ? +Tout de suite ça me parles plus.</p> +</div> +<div class="section" id="et-quand-est-ce-qu-on-arrete"> +<h2>Et quand-est-ce qu'on arrête ?</h2> +<p>Une autre chose assez difficile à gérer, c'est le temps.</p> +<p>J'ai vraiment une chance monstrueuse, celle de faire un travail qui me plait, +éthiquement et techniquement. Je pourrais y passer mes journées et mes nuits +que je n'aimerais pas moins ça (même si il m'arrive bien sur de saturer !).</p> +<p>Mais j'ai aussi d'autres envies, qui signifient aussi passer du temps +hors-ligne, parce que bizarrement, c'est là que j'ai l'impression de réfléchir +le plus. Loin de ce surplus d'informations…</p> +<p>Facile à dire.</p> +<p>D'autant que quand il est possible de travailler depuis n'importe où, +la séparation physique entre le lieu de travail et le lieu de vie tends à +disparaitre assez facilement. Et sans séparation physique, il faut une sacré +motivation pour savoir quand commencer et quand s'arrêter.</p> +<p>J'essaye de me donner une règle simple: point trop n'en faut. Aucun intérêt à +rester travailler des heures durant sans s'arrêter, ou en tout cas pas +d'intérêt à le faire de manière trop régulière. Une journée qui commence tôt +(~9h) me permet de me concentrer le matin (les collègues californiens dorment) +et d'avoir un rythme assez &quot;normal&quot;. Et puis, avec ce soleil qui commence à +inonder les terrasses, autant faire autre chose que de rester enfermé à coder +en fin d'après midi !</p> +</div> +<div class="section" id="surplus"> +<h2>Surplus</h2> +<p>Tiens, je parlais de surplus, nous y sommes. Que ça soit le surplus +d'informations ou le surplus d'objets, ça m'encombre ! Une journée, pour ma +part est faite de communications diverses, de code et de lectures (se tenir au +courant de ce qui se passe dans le monde du logiciel n'est pas une tâche des +plus facile, et qui peut facilement prendre énormément de temps).</p> +<p>Je me demande si je ne devrais pas aspirer à la frugalité de ce coté là +également. Je reçois des mails toute la journée, et mon aggrégateur rss/atom se +remplit également très vite. Mais je n'ai aucunement besoin d'avoir toutes ces +informations dans l'heure, et de les vérifier de manière fréquente. De la même +manière, j'ai simplement arrêté de lire mes flux rss.</p> +<p>Quelques (longues) fois dans la semaine semblent suffire et me permettent de +réussir à rester concentrer.</p> +</div> +<div class="section" id="resolutions"> +<h2>Résolutions</h2> +<p>Soyons fous, tentons quelque chose de nouveau, c'est le printemps ! Pas de +communication dans la matinée, je n'en ai probablement pas besoin, sauf cas +extrêmes. Le matin, c'est pour se concentrer sur le travail à faire.</p> +<p>Une fois les mails du matin dépilés (à 9h30), pas la peine de garder un œil +sur ma boite mail, j'irais y faire un tour en début et en fin d'après midi.</p> +<p>Je pense même à débrancher internet, pour éviter les interactions et pour me +concentrer, mais j'ai comme l'impression que c'est un peu trop abrupt comme +approche.</p> +<p>Aussi, définir en début de journée la liste des choses prévues, et revenir +dessus jour après jour me permettra surement d'avoir un aperçu un peu plus +global du travail accompli.</p> +<p>L'avenir dira si tout ça fonctionne :-)</p> +</div> +Cheese & code - Wrap-up2012-10-22T00:00:00+02:002012-10-22T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.html<p>This week-end I hosted a <em>cheese &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 well.</p> +<p>Here is a summary of what we worked on:</p> +<div class="section" id="daybed"> +<h2>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 REST web service, in python, and open +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're using <strong>CouchDB</strong> as a backend.</p> +<img alt="Daybed is a big couch!" src="images/daybed.jpg" style="width: 400px;" /> +<p>We mainly hacked on daybed and are pretty close to the release of the first +version, meaning that we have something working.</p> +<p><a class="reference external" href="http://github.com/spiral-project/daybed">The code</a> is available on github, +and we also wrote <a class="reference external" href="http://daybed.rtfd.org">a small documentation</a> for 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'm pretty confidend that we now have really good basis for this project.</p> +<p>Also, we will have a nice todolist application, with the backend <strong>and</strong> the +frontend, in javascript / html / css, you'll know more when it'll be ready :-)</p> +<p>Once we have something good enough, we'll release the first version and I'll +host it somewhere so that people can play with it.</p> +</div> +<div class="section" id="cornice"> +<h2>Cornice</h2> +<p>Daybed is built on top of <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, a framework to +ease the creation of web-services.</p> +<p>At Pycon France, we had the opportunity to attend a good presentation about <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a>. SPORE is a way to describe your +REST web services, as WSDL is for WS-* services. This allows to ease the +creation of generic SPORE clients, which are able to consume any REST API with +a SPORE endpoint.</p> +<p>Here is how you can let cornice describe your web service for you</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>And you'll get a definition of your service, in SPORE, available at <cite>/spore</cite>.</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, etc.</p> +<p>I released today <a class="reference external" href="http://crate.io/packages/cornice/">Cornice 0.11</a>, which adds +into other things the support for SPORE, plus some other fixes we found on our +way.</p> +</div> +<div class="section" id="respire"> +<h2>Respire</h2> +<p>Once you have the description of the service, you can do generic clients +consuming them!</p> +<p>We first wanted to contribute to <a class="reference external" href="https://github.com/bl0b/spyre">spyre</a> but +it was written in a way that wasn't supporting to <cite>POST</cite> data, and they +were using their own stack to handle HTTP. A lot of code that already exists in +other libraries.</p> +<p>While waiting the train with <a class="reference external" href="http://natim.ionyse.com/">Rémy</a>, we hacked +something together, named &quot;Respire&quot;, a thin layer on top of the awesome +<a class="reference external" href="http://python-requests.org">Requests</a> 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're still hacking on it so it may break +(for the better), but that had been working pretty well for us so far.</p> +<p>You can <a class="reference external" 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 daybed)</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Finally, we were out of cheese so everyone headed back to their respective +houses and cities.</p> +<p>Until next time?</p> +</div> +Cheese & Code party: October 20-212012-09-20T00:00:00+02:002012-09-20T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-20:/afpy-computer-camp-october-20-21.html<p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing …</p><p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing something related with the Afpy Computer +Camps at his house each year, I've been there twice and it really was a nice +experience.</p> +<p>At Djangocong 2012, in Montpellier (south of France), <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu Leplatre</a> and myself started to work on a model +validation and storage service, named <a class="reference external" href="https://github.com/spiral-project/daybed/">Daybed</a>.</p> +<p>I've talked about this project to some persons this week-end (I've even done <a class="reference external" href="http://alexis.notmyidea.org/lightning-daybed.html">a +lightning talk</a> about it) +and it gathered some interest from people in the python community, so we +thought about sprinting on this.</p> +<div class="section" id="and-21-october-a-computer-camp"> +<h2>20 and 21 October - A Computer Camp !</h2> +<p>Add to this a few beers, and the sprint turns magically into a camp. We'll be +sprinting at the end of October (the 20 and 21) near Angers, on daybed.</p> +<p>We plan to have great food and wine, so if you feel like it and if you want to +come and work on some python-related things, you're invited!</p> +<p>Although, I can host a limited number of persons, so you'll need to contact me +before :), that's <cite>alexis at notmyidea dot org</cite>.</p> +<p>I've setup a wiki page to organize a bit everything (knowing how many people will +come by will allow me to handle things better), please put information there:</p> +<p><a class="reference external" href="http://wiki.python.org/moin/ComputerCampAlexis">http://wiki.python.org/moin/ComputerCampAlexis</a></p> +</div> +Circus sprint at PyconFR2012-09-17T00:00:00+02:002012-09-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.html<p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're …</p><p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're using +at Mozilla for some of our 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 features.</p> +<p>Having people wanting to sprint on our projects is exciting because that's +when making things in the open unleashes its full potential. You can't imagine +how happy I was to have some friends come and work on this with us :)</p> +<p>Here is a wrap-up of the sprint:</p> +<div class="section" id="autocompletion-on-the-command-line"> +<h2>Autocompletion on the command-line</h2> +<p><a class="reference external" 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're using bash. It seems that not that much work is needed to +make it happen on zsh as well :)</p> +<p><a class="reference external" href="https://github.com/mozilla-services/circus/blob/master/extras/circusctl_bash_completion">Have a look at the feature</a></p> +<p>On the same topic, we now have a cool shell for Circus. If you start the +<cite>circusctl</cite> command without any option, you'll end-up with a cool shell. Thanks +<a class="reference external" href="https://github.com/jojax">Jonathan Dorival</a> for the work on this! You can +have a look at <a class="reference external" href="https://github.com/mozilla-services/circus/pull/268">the pull request</a>.</p> +</div> +<div class="section" id="future-changes-to-the-web-ui"> +<h2>Future changes to the web ui</h2> +<p><a class="reference external" 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'm glad of this. +Currently, it's done with bottle.py and we want to switch to 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 instance.</p> +</div> +<div class="section" id="bug-and-doc-fixing"> +<h2>Bug and doc fixing</h2> +<p>While reading the source code, we found some inconsistencies and fixed them, +with <a class="reference external" href="http://mathieu.agopian.info/">Mathieu Agopian</a>. We also tried to +improve the documentation at different levels.</p> +<p>Documentation still needs a lot of love, and I'm planning to spend some time on +this shortly. I've gathered a bunch of feedback on this</p> +</div> +<div class="section" id="circus-clustering-capabilities"> +<h2>Circus clustering 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 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 be.</p> +<p>Remy wrote <a class="reference external" href="http://tech.novapost.fr/circus-clustering-management-en.html">a good summary about our brainstorming</a> so I'll not do +it again here, but feel free to contact us if you have ideas on this, they're +very welcome!</p> +</div> +<div class="section" id="project-management"> +<h2>Project management</h2> +<p>We've had some inquiries telling us that's not as easy as it should to get +started with the Circus project. Some of the reasons are that we don't +have any release schedule, and that the documentation is hairy enough to lost +people, at some point :)</p> +<p>That's something we'll try to fix soon :)</p> +<p>PyconFR was a very enjoyable event. I'm looking forward to meet the community +again and discuss how Circus can evolve in ways that are interesting to +everyone.</p> +<p>Tarek and me are going to <a class="reference external" href="http://python.ie/pycon/2012/">Pycon ireland</a>, feel +free to reach us if you're going there, we'll be happy to meet and enjoy beers!</p> +</div> +Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla-fr.html<p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi …</p><p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi je me suis dit que ça pouvait avoir du sens de l'écrire +quelque part.</p> +<p>Ça parle bien sur de logiciel libre, de protection de la vie privée et de +contre-pouvoirs.</p> +<p>Je ne m'adresse pas ici aux afficionados du logiciel libre et du non contrôle +du web, mais aux potentiels intéressés, qui souhaitent comprendre ce qu'on fait +à Mozilla, pourquoi et comment, et plus particulièrement quel est le rôle que +je joue la dedans.</p> +<div class="section" id="logiciel-libre"> +<h2>Logiciel libre</h2> +<p>Une des premières choses qui vient à l'esprit des gens quand on parle de +Mozilla, et par extension de Firefox, c'est qu'il s'agit d'un logiciel gratuit. +D'un logiciel soit disant &quot;libre&quot;. Avouez que le concept est de prime abord +curieux. Un logiciel qui serait libéré, mais libéré de quoi ?</p> +<p>Je ne vais pas refaire la génèse du logiciel et du logiciel libre, mais pour +résumer et expliquer ça très grossièrement, le logiciel libre c'est pour moi +l'idée de la collaboration. &quot;Plutôt que de travailler chacun dans son coin, +construisons ensemble quelque chose qui nous sera utile à tous&quot;. Ça marche dans +le domaine de l'informatique parce qu'on est exposé à un bien commun non +matériel. Ce n'est pas parce que je te donne un logiciel que je ne l'ai plus. +La duplication est possible et elle rend la collaboration plus facile.</p> +<div class="section" id="euh-oui-mais"> +<h3>Euh, oui mais…</h3> +<p>Ok, ok. Et comment on coopère ? Derrière un logiciel, il faut écrire des lignes +de code, il faut décrire comment doit se comporter le logiciel dans l'ensemble +des cas qu'il peut rencontrer. Mais pas seulement. Beaucoup de personnes +travaillent pour faire en sorte que Firefox soit disponible dans près de 100 +langues et dialectes par exemple.</p> +<p>J'aime beaucoup penser que le logiciel libre réussit à réunir des personnes +avec des objectifs differents. Linux, qui est un logiciel libre, est par exemple +utilisé dans beaucoup de domaines très différents tels que la médecine, +l'automobile ou l'énergie.</p> +<p>Le logiciel libre est une valeur clé que nous défendons chez Mozilla.</p> +</div> +</div> +<div class="section" id="protection-de-la-vie-privee"> +<h2>Protection de la vie privée</h2> +<p>Mozilla en fait un peu sa devise. Nous ne sommes pas une entreprise, nous +n'avons aucun intérêt à enfermer les utilisateurs chez nous, et surtout nous +n'exploitons et n'exploiterons pas les données utilisateurs à des fins +commerciales. Jamais.</p> +<div class="section" id="stockage-des-donnees"> +<h3>Stockage des données</h3> +<p>Un exemple qui est frappant est celui de <a class="reference external" href="https://www.mozilla.org/en-US/mobile/sync/">Sync</a>, l'outil qui permet de +synchroniser les données de navigation entre plusieurs périphériques (Cela peut +être utile pour avoir votre historique de navigation partagé entre votre +ordinateur de bureau et un téléphone portable par exemple)</p> +<p>Les données qui sont stockées dans un service tel que sync sont cruciales: vos +mots de passe et votre historique de navigation par exemple. Imaginez ce que +des annonceurs publicitaires pourraient faire avec ces données. Il est assez +facile de connaître votre profil et donc d'ensuite faire de la publicité +ciblée à partir de ces informations. Voire pire. Donner ces données à qui fait +suffisemment pression sur vous pour les récupérer.</p> +<p>Heureusement, les données qui sont stockées sur les serveurs Sync sont +chifrées, et seul l'utilisateur a accès a la clé de chiffrement et de +déchiffrement. En d'autres termes, en ayant accès aux serveurs de Mozilla, même +de l'intérieur, je pourrais avoir accès à vos données mais je ne pourrais rien +en faire car celles-ci me sont impossibles à déchiffrer.</p> +<p>Mozilla essaye de mettre le doigt là où ça fait mal dans l'innovation web&nbsp;: la +publicité et le respect de la vie privée des utilisateurs. Facebook, Google, +Twitter sont autant d'entreprises qui gagnent de l'argent grâce à leurs +utilisateurs et à leurs données privées.</p> +<p>Cela n'est pas <em>nécessairement</em> un mal mais il me semble important d'informer +les utilisateurs d'Internet la dessus, et de leur proposer des méthodes qui +leur permettent de protéger leur vie privée.</p> +</div> +<div class="section" id="decentralisation"> +<h3>Décentralisation</h3> +<p>Un autre aspect important est le fait que vous n'avez pas besoin de dépendre des +serveurs de Mozilla si vous ne souhaitez pas en dépendre. Bien que nous +fassions tout ce qui est en notre pouvoir pour avoir des serveurs très réactifs +et capables de tenir la charge, nous ne sommes pas à l'abri de pannes. Auquel +cas il vous faudra simplement vous armer de patience.</p> +<p>Mais il est possible pour vous de maintenir votre propre serveur et de ne pas +dépendre de Mozilla pour stocker vos données privées. J'ai parlé de Sync mais +Mozilla (j'en parle un peu plus bas) travaille aussi sur un système +d'exploitation pour téléphone portable, nommé Firefox OS (anciennement Boot 2 +Gecko), et sur l'écosystème qui va avec.</p> +<p>Actuellement, si vous souhaitez synchroniser vos contacts par exemple, vous +dépendez quasiment toujours d'une autorité à qui vous ne faites peut être pas +confiance: Apple, Microsoft ou bien Google.</p> +<p>On ne vous propose pas simplement de nous faire confiance, on vous propose la +possibilité de ne faire confiance qu'à ceux à qui vous souhaitez accorder votre +confiance, et ça peut être vous si vous le souhaitez.</p> +<p>La décentralisation à ceci de bon qu'elle vous laisse le choix d'où vous +souhaitez stocker vos données.</p> +</div> +</div> +<div class="section" id="innovation-et-standardisation"> +<h2>Innovation et standardisation</h2> +<p>Mozilla, dès ses débuts, a été un laboratoire. Firefox (si je ne me trompe pas) +a été le premier navigateur à avoir des onglets. Le web, c'est cool parce que +ça bouge tout le temps ! (Edit: en fait, <a class="reference external" href="http://en.wikipedia.org/wiki/Tabbed_document_interface">ce n'était pas le premier</a>, mais l'idée est là)</p> +<p>La dernière innovation en date est Firefox OS: utilisons les technologies du +web pour créer un téléphone: utilisons le web comme plateforme, et profitons de +tout l'écosystème qui existe déjà autour de celui-ci.</p> +<p>C'est bien que ça bouge mais il faut qu'on se mette d'accord sur comment on +veut faire bouger les choses. La guerre des navigateurs a eu lieu. Ne pas +reproduire ça est parfois un challenge. La standardisation, tout le monde s'y +met.</p> +<p>On a gagné une guerre: aux utilisateurs de choisir les outils qu'ils souhaitent +et non pas aux développeurs d'imposer leurs choix.</p> +</div> +<div class="section" id="et-moi-qu-est-ce-que-je-fais-la-dedans"> +<h2>Et moi, qu'est-ce que je fais la dedans ?</h2> +<p>Je travaille dans l'équipe nommée Services. On travaille à la mise en +place de services web qui sont capables de tenir la charge, de fonctionner de +manière décentralisée.</p> +<p>Ce travail a plusieurs objectifs:</p> +<ul class="simple"> +<li>Mettre à disposition des outils pour les développeurs, leur permettant de +créer des services de bonne qualité rapidement;</li> +<li>Permettre aux utilisateurs d'héberger eux mêmes leurs propres serveurs s'ils +le souhaitent, réduisant leur dépendance a des services externes.</li> +<li>Écrire les services en question de telle manière que les utilisateurs (vous +!) puissent les utiliser sans avoir trop de tracas :)</li> +</ul> +<p>Ça semble peu, mais j'aime ce boulot. Éthiquement et techniquement. C'est ça, +pour moi, la mission de Mozilla. Si vous avez des suggestions sur ce qui +pourrait être amélioré dans les services de Mozilla en termes de protection de +la vie privée, de décentralisation et de haute disponibilité, vous savez vers +qui vous tourner !</p> +<p>La liste des projets sur lesquels je travaille ou j'ai travaillé à Mozilla pour +l'instant:</p> +<ul class="simple"> +<li><a class="reference external" href="https://github.com/mozilla-services/tokenserver">https://github.com/mozilla-services/tokenserver</a></li> +<li><a class="reference external" href="http://circus.io/">http://circus.io/</a></li> +<li><a class="reference external" href="http://powerhose.rtfd.org/">http://powerhose.rtfd.org/</a></li> +<li><a class="reference external" href="https://github.com/mozilla-services/server-aitc">https://github.com/mozilla-services/server-aitc</a></li> +<li><a class="reference external" href="http://cornice.readthedocs.org/en/latest/index.html">http://cornice.readthedocs.org/en/latest/index.html</a></li> +<li><a class="reference external" href="https://github.com/mozilla/PyBrowserID/">https://github.com/mozilla/PyBrowserID/</a></li> +<li><a class="reference external" href="http://chaussette.readthedocs.org/en/0.3/index.html">http://chaussette.readthedocs.org/en/0.3/index.html</a></li> +</ul> +</div> +Refactoring Cornice2012-05-14T00:00:00+02:002012-05-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-05-14:/refactoring-cornice.html<p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> routing system, +allowing to register services in …</p><p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" 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 HTTP headers <a class="reference external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">as defined by the HTTP specification</a> without the need +from the developer to deal with them nor to know them.</p> +<p>If you're not familiar with Cornice, here is how you define a simple service +with it:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>This external API is quite cool, as it allows to do a bunch of things quite +easily. For instance, we've written our <a class="reference external" href="https://github.com/mozilla-services/tokenserver">token-server</a> code on top of this in a +blast.</p> +<div class="section" id="the-burden"> +<h2>The 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 internally.</p> +<p>The API of the <cite>cornice.service.Service</cite> class was as following (simplified so +you can get the gist of it).</p> +<div class="highlight"><pre><span></span><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="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="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> +</pre></div> +<p>I encourage you to go read <a class="reference external" 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 done.</p> +<p>A bunch of things are wrong:</p> +<ul class="simple"> +<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 <cite>get_drink</cite>, you will instead get a decorator which +contains this view.</li> +<li>second, we are using decorators as APIs we expose. Even if decorators are +good as shortcuts, they shouldn't be the default way to deal with an API. A +good example of this is <a class="reference external" href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/resource.py#L56">how the resource module consumes this API</a>. +This is quite hard to follow.</li> +<li>Third, in the <cite>api</cite> 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 API.</li> +</ul> +</div> +<div class="section" id="how-do-we-improve-this"> +<h2>How do we improve this?</h2> +<p>Python is great because it allows you to refactor things in an easy way. What I +did isn'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 API that much.</p> +<p>Here is the gist of the new architecture:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">None</span><span class="p">):</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="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="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> +</pre></div> +<p>So, the service is now only storing the information that'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 +<cite>register_service_views</cite> and has the following signature:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>To sum up, here are the changes I made:</p> +<ol class="arabic simple"> +<li>Service description is now separated from the route registration.</li> +<li><cite>cornice.service.Service</cite> now provides a <cite>hook_view</cite> method, which is not a +decorator. decorators are still present but they are optional (you don't +need to use them if you don't want to).</li> +<li>Everything has been decoupled as much as possible, meaning that you really +can use the <cite>Service</cite> class as a container of information about the services +you are describing. This is especially useful when generating 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. <cite>cornice.services.Service</cite> 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 system.</p> +<p>However, no integration with other frameworks is done at the moment even if the +design allows it.</p> +<p>The same way, the sphinx description layer is now only a consumer of this +service description tool: it looks at what's described and build-up the +documentation from it.</p> +<p>The resulting branch is not merged yet. Still, you can <a class="reference external" 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 :-)</p> +</div> +Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-30:/bidouille-fr.html<p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de …</p><p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de comprendre comment les choses fonctionnent, +et depuis peu cette envie de mettre en pratique ces connaissances dépasse la +bidouille logicielle. J'ai passé une grosse partie de mon week-end à Main +d'Œuvre, où l'association <a class="reference external" href="http://www.underconstruction.fr">Under Construction</a> faisait se rencontrer le milieu de +l'éducation populaire et le milieu de la bidouille.</p> +<p>Forcement, ni une ni deux, je saute dans le bateau en marche et, n'étant ni un +très grand bidouilleur ni un très grand animateur, j'en ressort enrichi de +toutes ces rencontres, de tous ces préjugés qui tombent, et de quelques +découvertes bluffantes, des idées plein la tête.</p> +<p>J'avais entendu parler des &quot;<a class="reference external" href="http://www.reprap.org">rep-raps</a>&quot;, des +imprimantes en 3 dimensions capables de produire des pièces en plastique +mais je n'avais jamais eu l'occasion de voir le bousin en vrai. Et +c'est impressionnant. Vraiment. (&quot;Bienvenue dans le 21ème siècle !&quot;)</p> +<p>Ça laisse énormément à penser autour des questions d'émancipation +technologique, et de non dépendance envers les constructeurs, dans le milieu de +l'électro-ménager, par exemple. &quot;Ah tiens, cette pièce est cassée, je vais +aller utiliser la rep-rap du coin pour me la fabriquer&quot;. Et hop, on mets fin à +tout un cycle d'obsolescence programmée…</p> +<p>Mais au delà du défi technique et technologique, j'ai pu refaire un petit peu +d'électronique, et découvrir que j'y prends vraiment gout rapidement. Il y a +bien évidemment un coté très ludique (la led s'allume quand on la branche), +mais il y a surtout cette notion de DIY (Do It Yourself) sous jacente: une fois +que je sais comment ça fonctionne, je peux vraiment faire des choses utiles de +mes 10 doigts, réparer des petits objets, bidouiller ceux existants etc.</p> +<p>De la récupération de composants on essaye de voir ce qu'on peut faire, on a +terminé par faire un &quot;vibro-bot&quot;, un vibreur de téléphone portable monté sur +une tête de brosse à dents, faisant donc avancer cette dernière.</p> +<p>C'est pour s'amuser, c'est pas sérieux ! Pour autant, les concepts de +l'électricité sont appris et je me retrouve avec cette envie de comprendre un +peu plus ce monde de l'électronique qui, je m'en rends compte, m'échappe encore +complètement. De l'éducation à la bidouille !</p> +<p>Allez, demain c'est fer à souder, piles, leds, interrupteurs, potars et c'est +parti !</p> +Djangocong 20122012-04-16T00:00:00+02:002012-04-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-16:/djangocong-2012-fr.html<p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une …</p><p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une qualité d'é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 :)</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'ai eu l'occasion de discuter de projets tournant autour de +l'entraide, que ça soit pour mettre en lien des associations d'économie sociale +et solidaire (ESS) ou simplement pour que les populations <em>non tech</em> <a class="reference external" href="http://blog.notmyidea.org/quels-usages-pour-linformatique-fr.html">puissent +utiliser toute la puissance de l'outil qu'est le web</a>.</p> +<p>Au niveau du format des conférences, je ne savais pas trop à quoi m'attendre, +au vu des échos de l'an dernier, mais c'était adapté: des mini-confs de 12mn le +samedi matin + début d'aprem, en mode no-wifi pour récupérer une qualité +d'écoute. Et contrairement à mes attentes, ce n'est pas trop court. Pas mal de +retours d'expérience pour le coup, et une matinée pas vraiment techniques, mais +ça pose le décor et permet de savoir qui fait quoi.</p> +<p>Parmi l'ensemble des conférences du matin, je retiens principalement +celle de Mathieu Leplatre, &quot;des cartes d'un autre monde&quot;, qui m'a réellement +bluffée quand à la facilité de créer des cartes avec <a class="reference external" href="http://mapbox.com/tilemill/">TileMill</a>, et qui me pousse à reconsidérer le fait que &quot;la +carto, c'est compliqué&quot;. <a class="reference external" href="https://www.youtube.com/watch?v=7NPQo54NbJ8">La vidéo est (déja !) disponible en ligne</a>, je vous invite à la regarder +(c'est une 15aine de minutes) pour vous faire un avis ;)</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 &quot;notre&quot; projet <a class="reference external" href="http://blog.notmyidea.org/carto-forms-fr.html">&quot;carto +forms&quot;</a>, qui à finalement pu se +redéfinir un peu plus et donner naissance à un <a class="reference external" href="https://github.com/spiral-project/daybed/blob/master/README.rst">README</a>. On en +à profité pour lui choisir un nouveau nom: &quot;daybed&quot;, en référence à couchdb.</p> +<p>Ça devrait se transformer en code d'ici peu. La curiosité aidant, on a pu +discuter du projet avec d'autres personnes et affiner les attentes de chacun +pour finalement arriver à quelque chose d'assez sympathique.</p> +<p>J'ai aussi pu me rendre compte que pas mal de monde utilise <a class="reference external" href="http://pelican.notmyidea.org">pelican</a>, le bout de code que j'ai codé pour générer ce +blog, et avoir des retours utiles ! Probablement des réflexions à venir +sur comment éviter qu'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 contributeurs.</p> +<p>Bien évidemment, c'était aussi l'occaz de rencontrer des gens qu'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 chouette.</p> +<p>Entres autres faits notoires, JMad a perdu au baby-foot face à Exirel, même +en m'ayant à ses cotés pour le déconcentrer (et je suis un joueur d'un autre +monde - en d'autres termes, je suis nul), David`bgk ne s'est pas levé pour +aller courir le dimanche matin (il avait dit 5 heures!), Les suisses ont essayé +de me convertir à coup d'abricotine, j'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'ils mentent avec leur soit disant +soleil).</p> +<p>Et c'est sans parler de <a class="reference external" href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la brasucade</a> …</p> +<p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une présentation +!)</p> +Bière maison !2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/biere-maison-fr.html<p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si …</p><p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si pire comme on dit !</p> +<p>Cette fois-çi, on s'est penché sur la confection d'une IPA (Indian Pale Ale, une +bière un peu plus amère que celle qu'on à l'habitude de trouver en France).</p> +<p>Elle est plus amère car elle comporte plus de houblon que les autres, et +(dans notre cas en tout cas) parce qu'on fait la première fermentation en +présence de houblon.</p> +<div class="section" id="comment-qu-on-fait-de-la-biere"> +<h2>Comment qu'on fait de la bière ?</h2> +<p>Machine arrière; n'allons pas trop vite: comment est-ce qu'on fait de la bière, +d'abord ?</p> +<p>En fin de compte, les quelques étapes nécessaire à la confection de la bière ne +sont pas bien sorcières; concassage de l'orge maltée, cuisson (libération de +l'amidon dans l'eau), infusion du houblon, refroidissement, première +fermentation, embouteillage et seconde fermentation.</p> +<p>L'idée principale est transformer l'amidon d'orge maltée en sucre, pour le +&quot;donner à manger&quot; à des levures. Vous ajoutez un peu de houblon au milieu pour +donner un petit goût amer et le tour est joué. Enfin presque.</p> +</div> +<div class="section" id="etape-par-etape"> +<h2>Étape par étape</h2> +<p>Première étape: <strong>le concassage</strong>. On avait 6kg d'orge maltée à concasser (plus +exactement 6kg de malt pâle <em>7EDC</em> et 500g de malt cara <em>50EDC</em>).</p> +<img alt="Image de concassage." src="images/concassage.jpg" style="width: 400px;" /> +<p>Attention, pas trop fin dis donc ! On ne veut pas de la poudre, on veut +simplement permettre à l'amidon de se dissoudre dans l'eau. Si on concasse le +malt trop fin, on se retrouve avec un dépôt dégeulasse au fond de toutes les +bouteilles (c'est l'expérience qui parle, notre première bière avait plus goût +de céréale que de bière…)</p> +<p>Contrairement aux fois précédentes où nous avions utilisé la technique du +marteau et du torchon (oui, comme vous pouvez l'imaginer, c'est assez long et +fastidieux), On a utilisé… un moulin à malt ! Qui nous à permis de concasser les +6kg en 30 minutes (heureusement qu'on était trois pour se relayer sur le +moulin, parce que nos petits muscles fatiguaient assez vite; vous pouvez +envisager de faire ça tout seul si vous êtes un tennisman).</p> +<img alt="C'est dur !" src="images/concasse.jpg" style="width: 700px;" /> +<p>La seconde étape, <strong>l'empatage</strong>. Il s'agit de faire chauffer notre orge maltée +à différentes températures. Les fois précédentes, on avait utilisé plusieurs +paliers de température, mais il semble que ça ne soit pas si nécessaire que ça, +selon les informations de l'ami Fred. On à donc tenté de faire chauffer notre +malt directement à 50°C. Une petite erreur sur la route, on à eu peur de la +contamination bactérienne et on à décidé de faire bouillir nos 26L d'eau pour +être sur que les bactéries s'enfuient en courant. Je dis erreur parce que ça +nous à pris pas loin de 3h30, inertie quand tu nous tiens!</p> +<p>On se rends compte de la taille de la marmite un peu là:</p> +<img alt="Une grosse marmite" src="images/marmite.jpg" style="width: 400px;" /> +<p>Une fois l'eau à température (54°C), il faut ajouter le malt et le laisser +durant 30mn à cette température, puis augmenter jusqu'à 65°C durant 1h.</p> +<p>La troisième étape, c'est <strong>le rinçage</strong>, l'idée est de récupérer l'amidon qui +s'est dissout dans l'eau et de mettre de côté l'orge maltée (la partie solide). +Pour ça, il faut faire chauffer de l'eau de rinçage. On a utilisé 10L d'eau de +rinçage qu'on a fait chauffer à 78°C, en comptant sur le fait qu'elle perdra de sa +température (20°C à peu près) en étant utilisée. On a filtré deux fois pour +être sûr de ne rien perdre.</p> +<img alt="Filtrage filtrage..." src="images/filtrage.jpg" style="width: 700px;" /> +<p>L'étape d'après (la quatrième, vous suivez), c'est <strong>le houblonnage</strong>. +On va faire infuser notre &quot;solution aqueuse&quot; (wouah, on dirait de la chimie !) +avec du houblon. Il faut porter l'eau à ébullition et laisser faire durant 1h.</p> +<p>Dernière étape: <strong>le refroidissement</strong>. On dirait que c'est tranquilou comme +ça, mais en fait ça ne l'est pas tant que ça: il faut réussir à passer notre +liquide qui était en ébullition à 54°C en un temps acceptable. Pour ça, on +a utilisé un serpentin confectionné main.</p> +<img alt="Notre refroidisseur fait main par Fred." src="images/refroidisseur.jpg" style="width: 400px;" /> +<p>Ça nous a permis de passer de 100°C à 54°C en… 35 minutes quand même ! (Nous avions essayé les fois précédentes +de gérer ça à coup de baignoire et de glaçons, les temps n'étaient absolument +pas au rendez-vous).</p> +<img alt="Décidement pas." src="images/refroidissement.jpg" style="width: 700px;" /> +<p>Je disais dernière étape, mais il ne faut pas oublier de rajouter les +levures, qui elles vont faire tout le travail et transformer tout ça en… alcool +! Dans notre cas, on ajoute aussi dans la cuve de fermentation du houblon +question de donner l'amertume dont on a envie.</p> +<p>On à mesuré une densité de 1046, ce qui veut dire 6° d'alcool. La cuve est +maintenant en train de buller tranquillement (les levures produisent du gaz qui +est évacué), et ça doit durer 15 jours approximativement.</p> +</div> +<div class="section" id="mise-en-bouteille"> +<h2>Mise en bouteille</h2> +<p>Une fois ces deux semaines passées, il faut mettre en bouteille. Dans notre cas +nous avons récupéré des bouteilles à bouchon mécanique (vous savez, les +bouteilles de limonades) qu'on à bien rincé et nettoyé.</p> +<p>On s'équipe d'un siphon (pensez à prendre un tuyau avec un diamètre assez +important, le notre était petit et c'était assez long) et après avoir ajouté du +sucre dans le mélange (pour réactiver les levures), on remplit les bouteilles +! Il s'agit de la seconde fermentation, celle qui va faire les bulles (la +première fermentation se charge de l'alcool, la seconde des bulles).</p> +<p>Et voilà ! Il ne reste plus qu'à mettre les bouteilles de coté durant deux +semaines de plus et… à déguster le moment venu.</p> +<p>On a donc pu tester notre bière la semaine dernière et, ma foi, elle est pas +mal du tout. Elle ne mousse pas trop et à un goût un peu amer. Malheureusement +pas assez à mon goût, mais ça viendra. En comparaison à nos précédents essais, +c'est plutôt positif: la première était ratée puisque trop de pression et trop +de dépôt (et donc un fort goût de levures) alors que la seconde (on avait tenté +d'ajouter de la lavande) avait un goût de lavande amère, pour ne pas dire de +savon.</p> +<p>Cette dernière bière a un goût de… de bière ! Il nous reste encore à 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 !</p> +</div> +Motivation, bénévolat et participation2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/motivation-benevolat-et-participation-fr.html<p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux …</p><p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux luttes +contre l'oligarchie et les profits d'une minorité aux dépends du reste du monde, +et à encore bien d'autres choses.</p> +<p>Pendant un bout de temps, j'ai parlé d'entraide, de collaboration, j'ai essayé +de sensibiliser autour de la question environnementale et aux alternatives +sociales. C'est d'ailleurs de cette manière que je me suis moi-même le plus +sensibilisé à ces questions qui me préoccupaient.</p> +<p>J'ai tenté de le faire sans tomber dans la critique des choix des uns et des +autres. Je respecte profondément la diversité des points de vues <strong>mais</strong> je +souhaite également que ces choix soient faits en connaissance de cause.</p> +<p>Une des choses difficile à supporter (pour les autres) quand on fait de la +sensibilisation, c'est le syndrôme du jeune con, du donneur de leçons.</p> +<p>On dirait qu'on parle de sauver le monde. &quot;Nous qui avons tout compris, on peut +vous aider à aller dans la <em>bonne direction</em>&quot;, mais c'est en oubliant que +la bonne direction pour l'un ne l'est pas nécessairement pour les autres…</p> +<div class="section" id="just-do-it"> +<h2>Just do it !</h2> +<p>Se battre <em>contre quelque chose</em> permet de facilement trouver des personnes qui +partagent les même craintes alors que se battre <em>pour</em> permet d'engager des +discussions avec des personnes qui partagent une vision commune.</p> +<p>Proposer des choses, trouver des personnes qui partagent des points de vue est +un bon point de départ pour le changer ce monde, a notre échelle. Le récent +documentaire <a class="reference external" href="http://justdoitfilm.com/">&quot;Just do it&quot;</a> porte un message assez +clair: toute initiative compte, aussi petite et insignifiante qu'elle puisse +sembler.</p> +<p>Des initiatives locales, il y en a, plein. Et si ce que nous avons dans notre +quotidien nous pèse (aller au supermarché, subir la sur-médiatisation +télévisuelle, ne pas parler à nos voisins de quartier…), qu'est-ce qui nous +empêche d'y substituer des modèles alternatifs ?</p> +<p>Monter une <a class="reference external" href="https://fr.wikipedia.org/wiki/AMAP">AMAP</a> (Association Pour le Maintien d'une Agriculture Paysanne) +n'est pas aussi compliqué qu'il y parait. Pour avoir fait l'expérience par deux +fois, j'ai été très agréablement surpris par la facilité des choses, pour peu +qu'on ne cherche pas à s'encombrer de l'inutile (tiens encore une fois on +parle de frugalité !): il est facile de vouloir faire trop, de recréer les +processus complexes auxquels nous sommes souvent confrontés.</p> +<p>Vous souhaitez partager des connaissances (cuisine, musique, danse, bricolage, +écriture), il suffit de le faire. En fait, pour la plupart des choses, il +suffit de tenter l'expérience, c'est rarement décevant. Surtout quand on +s'embarque dans des choses saugrenues ou personnellement inédites.</p> +<p>Pour moi, la frugalité, la simplicité volontaire, la sobriété heureuse, appelez-ça +comme vous le voulez, représente ce qui me convient et me permet d'être en +ligne avec les idées que je défends.</p> +</div> +<div class="section" id="faciliter-la-participation"> +<h2>Faciliter la participation</h2> +<p>Beaucoup de personnes sont à même de participer à des projets locaux, pour peu +qu'ils soient au courant mais pour autant peu franchissent le pas, et encore +moins persévèrent, pourquoi ?</p> +<p>Et pourquoi pas laisser les présents, les motivés, s'investir par eux-mêmes ? +Avoir des responsabilités est souvent pour ma part un frein à la réalisation +d'un projet lorsque je suis bénévole.</p> +<p>Décider à l'avance des choses qui semblent utiles et/ou importantes est parfois +indispensable, mais ne pas trop en faire permet de laisser libre court +à l'imagination (souvent débordante) des participants.</p> +<p>J'aime beaucoup l'idée de faire des camps de quelques jours, où rien n'est +réellement décidé à l'avance, mise à part un thème et quelques temps de +plénière ou il est possible à chacun de s'exprimer sur les projets qui +pourraient êtres réalisés.</p> +<p>Pas besoin de tant de formalisation: mettez une équipe de bidouilleurs ensemble +durant une semaine sans objectif commun à priori et sans distractions, vous +verrez bien ce qui en ressortira !</p> +</div> +Thoughts about a form generation service, GIS enabled2012-02-04T00:00:00+01:002012-02-04T00:00:00+01:00Alexis Métaireau, Mathieu Leplatretag:blog.notmyidea.org,2012-02-04:/carto-forms.html<p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of it.</p> +<p>This idea has been stuck …</p><p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of 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've named it +<em>carto-forms</em> for now, but that's only the &quot;codename&quot;.</p> +<p>To put it shortly: what if we had a way to build forms, ala Google forms, but +with geographic information in them?</p> +<p>If you don't know Google forms, it means having an user-friendly way to build +forms and to use them to gather information from different users.</p> +<p>In my opinion, Google forms is missing two important things: first, it's not +open-source, so it's not possible to hack it or even to run it on your own +server. Second, it doesn't really know how to deal with geographic data, and +there is no way to filter the information more than in a spreadsheet.</p> +<p>I knew that <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu</a> and some folks at <a class="reference external" href="http://makina-corpus.com">Makina Corpus</a> would be interested +in this, so I started a discussion with him on IRC and we refined the details +of the project and its objectives.</p> +<p>Imagine the following:</p> +<ol class="arabic simple"> +<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) ;</li> +<li>In situ, users fill the form fields with what they see. Geo fields can be +pre-populated using device geolocation ;</li> +<li>At the end of the day, we can see a map with all user contributions seized +through this particular form ;</li> +<li>If relevant, a script could eventually import the resulting dataset and +publish/merge with OpenStreetMap.</li> +</ol> +<div class="section" id="some-use-cases"> +<h2>Some use cases</h2> +<p>I can see some use cases for this. The first one is a collaborative map, with +facet filtering. Let's draw a potential user flow:</p> +<ul> +<li><p class="first">An &quot;administrator&quot; goes to the website and creates a form to list all the +alternative-related events. He creates the following fields:</p> +<ul class="simple"> +<li>Name: a plain text field containing the name of the event.</li> +<li>Category: the category of the event. Can be a finite list.</li> +<li>Location: The location of the event. It could be provided by selecting a +point on a map or by typing an address.</li> +<li>Date: the date of the event (a datepicker could do the 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 etc)</p> +</li> +<li><p class="first">Once finished, the form is generated and the user gets an url (say +<a class="reference external" href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>) for it.</p> +</li> +<li><p class="first">REST APIs allow third parties to get the form description and to +push/edit/get information from there.</p> +</li> +<li><p class="first">He can communicate the address in any way he wants to his community so they +can go to the page and add information to it.</p> +</li> +<li><p class="first">Then, it is possible to filter the results per location / date or category. +This can be done via API calls (useful for third parties) or via a nice +interface in the browser.</p> +</li> +</ul> +<p>So, as you may have noticed, this would allow us to create interactive maps really +easily. It's almost just a matter of some clicks to the users. If we also come +up with a nice Web API for this, we could do server-side validation and build +even phone applications 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 clients.</p> +<p>As mentioned before, the idea of a simple tool to support collaborative mapping +fullfils a recurring necessity !</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'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 class="reference external" href="http://fixmystreet.ca">http://fixmystreet.ca</a>), +geocaching, trajectories (e.g hiking, runners, cyclists)...</p> +<p>Here are some other examples of where <em>carto-forms</em> could be useful:</p> +<div class="section" id="simple-gis-storage-backend"> +<h3>Simple GIS storage backend</h3> +<p>Let's say you are a mobile developer, you don't want to bother with PostGIS +nor write a custom and insecure code to insert and retrieve your GIS data! You +need carto-forms! A simple API helps you design your models/forms and the +same API allows you to CRUD and query your data. Thus, you only need to focus +on your application, not on how GIS data will be handled.</p> +<p>We make a distinction between storage and widgets.</p> +<p>Besides, if you are a django / drupal / plomino... maintainer : you +can develop a module to &quot;plug&quot; your models (content types) and UI to carto-forms! +Carto forms are then exposed to your backoffice users (ex: drupal admin UI, django +adminsite), and likewise you can write your own HTML widgets that consume datasets +in frontend views (facets in JSON/XML, and map data in GeoJSON).</p> +</div> +<div class="section" id="visualization-tool"> +<h3>Visualization tool</h3> +<p>Since data submission can be done programmatically using the API, you could use Carto-forms +results page as a visualization 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're in +front of a decision support system!</p> +<p>Of course, filtered raw data can be downloaded (GeoJSON, XML) and a permalink allows to +share the page with the state of the filters and the zoom/location of the map.</p> +</div> +<div class="section" id="generic-forms-service"> +<h3>Generic forms service</h3> +<p>If you want to generate a configuration file (or whatever, email messages, ...), +you will need a form and a template to inlay user submitted values and get the result.</p> +<p>A form service would be really useful to create forms programmatically and retrieve +cleaned and validated input 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 result).</p> +<p>Note that for this use-case, there is no specific need of GIS data nor storage of records +for further retrieval.</p> +</div> +</div> +<div class="section" id="what-s-out-in-the-wild-already"> +<h2>What's out in the wild already?</h2> +<p>Of course, there is Google forms, which allows you to do these kind of things, +but it's closed and not exactly what we are describing here.</p> +<p>We've discovered the interesting <a class="reference external" 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't handle APIs and +geolocation information.</p> +<p>The idea of <a class="reference external" href="http://thoth.io">http://thoth.io</a> is very attractive : an extremely simple web API to store +and retrieve data. In addition, <em>carto-forms</em> would do datatype validation and have +basic GIS fields (point, line, polygon).</p> +<p><a class="reference external" href="http://mapbox.com">http://mapbox.com</a> also did an awesome work on cartography, but didn't take into +account the form aspect we're leveraging here.</p> +</div> +<div class="section" id="so-let-s-get-it-real"> +<h2>So… Let's get it real!</h2> +<p>As you may have understood, this isn't a really complicated problem. We have +been sometimes chatting about that with Mathieu about what we would need and +how we could achieve this.</p> +<p>We can probably come with an elegant solution without too much pain. Mathieu is +used to work with GIS systems (which is really cool because I'm not at all) and +knows his subject, so that's an opportunity to learn ;-)</p> +<p>We will be at <a class="reference external" 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 join!</p> +<p>We don'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 welcome!</p> +<p>Here is the etherpad document we worked on so far: +<a class="reference external" href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don't hesitate to add your thoughts and edit +it, that's what it's made for!</p> +<p>Thanks to <a class="reference external" href="http://sneakernet.fr/">Arnaud</a> and <a class="reference external" href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo fixing.</p> +</div> +Génération de formulaires, geolocalisés ?2012-02-04T00:00:00+01:002012-02-04T00:00:00+01:00Alexis Métaireau, Mathieu Leplatretag:blog.notmyidea.org,2012-02-04:/carto-forms-fr.html<p>On a un plan. Un &quot;truc de ouf&quot;.</p> +<p>À plusieurs reprises, des amis m'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 l'information.</p> +<p>L'idée fait …</p><p>On a un plan. Un &quot;truc de ouf&quot;.</p> +<p>À plusieurs reprises, des amis m'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 l'information.</p> +<p>L'idée fait son bout de chemin, et je commence à penser qu'on peut même avoir +quelque chose de vraiment flexible et utile. J'ai nommé le projet <em>carto-forms</em> +pour l'instant (mais c'est uniquement un nom de 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 plus?</p> +<p>Si vous ne connaissez pas Google forms, il s'agit d'une interface simple +d'utilisation pour générer des formulaires et récupérer des informations depuis +ces derniers.</p> +<p>Google forms est un super outil mais à mon avis manque deux choses importantes: +premièrement, il s'agit d'un outil propriétaire (oui, on peut aussi dire +privateur) et il n'est donc pas possible de le hacker un peu pour le faire +devenir ce qu'on souhaite, ni l'installer sur notre propre serveur. +Deuxièmement, il ne sait pas vraiment fonctionner avec des informations +géographiques, et il n'y à pas d'autre moyen de filtrer les informations que +l'utilisation de leur système de feuilles de calcul.</p> +<p>Après avoir réfléchi un petit peu à ça, j'ai contacté <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu</a> et les anciens +collègues de chez <a class="reference external" href="http://makina-corpus.com">Makina Corpus</a>, puisque les projets libres à base de carto +sont à même de les intéresser.</p> +<p>Imaginez le cas suivant:</p> +<ol class="arabic simple"> +<li>Dans une &quot;mapping party&quot;, on choisit un sujet particulier à cartographier et +on design un formulaire (liste des champs (tags) a remplir + description + +le type d'information) ;</li> +<li>Sur place, les utilisateurs remplissent les champs du formulaire avec ce +qu'ils voient. Les champs géolocalisés peuvent être remplis automatiquement +avec la géolocalisation du téléphone ;</li> +<li>À la fin de la journée, il est possible de voir une carte des contributions, +avec le formulaire choisi ;</li> +<li>Un script peut importer les résultats et les publier vers OpenStreetMap.</li> +</ol> +<div class="section" id="quelques-cas-d-utilisation"> +<h2>Quelques cas d'utilisation</h2> +<p>J'arrive à imaginer différents cas d'utilisation pour cet outil. Le premier est +celui que j'ai approximativement décrit plus haut: la génération de cartes de +manière collaborative, avec des filtres à facettes. Voici un flux d'utilisation +général:</p> +<ul> +<li><p class="first">Un &quot;administrateur&quot; se rend sur le site web et crée un nouveau formulaire +pour l'ensemble des évènements alternatifs. Il crée les champs suivants:</p> +<ul class="simple"> +<li>Nom: le champ qui contient le nom de l'évènement.</li> +<li>Catégorie: la catégorie de l'évènement (marche, concert, manifestation…). +Il peut s'agir d'un champ à multiples occurrences.</li> +<li>Le lieu de l'évènement. Celui-ci peut être donné soit par une adresse soit +en sélectionnant un point sur une carte.</li> +<li>Date: la date de l'évènement (un &quot;date picker&quot; peut permettre cela +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, +etc.)</p> +</li> +<li><p class="first">Une fois terminé, le formulaire est généré et une URL permet d'y accéder. +(par exemple <a class="reference external" href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>).</p> +</li> +<li><p class="first">Une API REST permet à d'autres applications d'accéder aux informations et d'en +ajouter / modifier de nouvelles.</p> +</li> +<li><p class="first">Il est maintenant possible de donner l'URL à qui voudra en faire bon usage. +N'importe qui peut ajouter des informations. On peut également imaginer une +manière de modérer les modifications si besoin est.</p> +</li> +<li><p class="first">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 +API REST, soit via une jolie carte et quelques contrôles bien placés, dans le +navigateur.</p> +</li> +</ul> +<p>Vous avez dû remarquer que le processus de création d'un formulaire est +volontairement très simple. L'idée est que n'importe qui puisse créer des +cartes facilement, en quelques clics. Si une API bien pensée suit, on peut +imaginer faire de la validation coté serveur et même faire des applications +pour téléphone assez 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 +génériques.</p> +<p>On imagine pas mal d'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'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'affichage publicitaires, participation citoyenne +(graffitis, nids de poule, voir <a class="reference external" href="http://fixmystreet.ca">http://fixmystreet.ca</a>), geocaching, +trajectoires (randonnées, coureurs, cyclistes)…</p> +<p>Voici quelques exemples où ce projet pourrait être utile (la liste n'est pas +exhaustive):</p> +<div class="section" id="un-backend-sig-simple-a-utiliser"> +<h3>Un backend SIG simple à 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 SIG! +Vous avez besoin de <em>Carto-Forms</em>! Une API simple vous aide à penser vos +modèles et vos formulaires, et cette même API vous permet d'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 gérées.</p> +<p>En d'autres termes, vous faites une distinction entre le stockage des +informations et leur affichage.</p> +<p>Si vous êtes un développeur django, plomino, drupal etc. vous pouvez développer +un module pour &quot;plugger&quot; vos modèles et votre interface utilisateur avec celle +de <em>Carto-Forms</em>. De cette manière, il est possible d'exposer les formulaires +aux utilisateurs de vos backoffices. De la même manière, il est possible +d'écrire des widgets qui consomment des données et les affichent (en utilisant +par exemple une bibliothèque javascript de webmapping).</p> +</div> +<div class="section" id="un-outil-de-visualisation"> +<h3>Un outil de visualisation</h3> +<p>Puisque les données peuvent être proposées de manière automatisée en utilisant +l'API, vous pouvez utiliser la page de résultat de Carto-forms comme un outil +de visualisation.</p> +<p>Il est possible d'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'impressoin d'être en face +d'un système d'aide à la décision !</p> +<p>Évidemment, il est possible de télécharger les données brutes (geojson, xml). +Idéalement, le mieux serait d'obtenir ces données filtrées directement depuis +une API Web, et un lien permet de partager la page avec l'état des filtres et +le niveau de zoom / la localisation de la carte.</p> +</div> +<div class="section" id="un-service-generique-pour-gerer-les-formulaires"> +<h3>Un service générique pour gérer les formulaires</h3> +<p>Si vous souhaitez générer un fichier de configuration (ou ce que vous voulez, +messages emails, …) vous aurez besoin d'un formulaire et d'un template pour +injecter les données proposées par les utilisateurs et récupérer un 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 &quot;nettoyées&quot; et +&quot;validées&quot;.</p> +<p>On peut imaginer par exemple l'utilisation d'un système de templates externe +reposant sur <em>carto-forms</em>. Celui-ci &quot;parserait&quot; le contenu des templates et +pourrait le lier aux informations ajoutées par les utilisateurs via un formulaire.</p> +<p>Pour ce cas particulier, il n'y a pas besoin d'informations géographiques +(SIG). Il s'agit quasiment du service proposé actuellement par Google forms.</p> +</div> +</div> +<div class="section" id="ca-n-existe-pas-deja-tout-ca"> +<h2>Ça n'existe pas déjà tout ça ?</h2> +<p>Bien sur, il y a Google forms, qui vous permet de faire ce genre de choses, +mais comme je l'ai précisé plus haut, il ne s'agit pas exactement de la même +chose.</p> +<p>Nous avons découvert <a class="reference external" href="https://webform.com">https://webform.com</a> qui permet de créer des formulaires +avec un système de drag'n'drop. J'adorerais reproduire quelque chose de +similaire pour l'interface utilisateur. Par contre ce projet ne gère pas les +appels via API et les informations de géolocalisation …</p> +<p>L'idée de <a class="reference external" 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 +SIG (point, ligne, polygone).</p> +<p><a class="reference external" 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 formulaires…</p> +</div> +<div class="section" id="on-est-parti"> +<h2>On est parti ?!</h2> +<p>Comme vous avez pu vous en rendre compte, il ne s'agit pas d'un problème +outrageusement complexe. On a pas mal discuté avec Mathieu, à propos de ce +qu'on souhaite faire et du comment. Il se trouve qu'on peut sûrement s'en +sortir avec une solution élégante sans trop de problèmes. Mathieu est habitué à +travailler autour des projets de SIG (ce qui est parfait parce que ce n'est pas +mon cas) et connaît son sujet. Une bonne opportunité d'apprendre!</p> +<p>On sera tous les deux à <a class="reference external" 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'hésitez pas!</p> +<p>On ne sait pas encore si on utilisera django ou quelque chose d'autre. On a +pensé un peu à CouchDB, son système de couchapps et geocouch, mais rien n'est +encore gravé dans le marbre ! N'hésitez pas à proposer vos solutions ou +suggestions.</p> +<p>Voici le document etherpad sur lequel on a travaillé jusqu'à maintenant: +<a class="reference external" href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. N'hésitez pas à l'éditer et à ajouter vos +commentaires, c'est son objectif!</p> +<p>Merci à <a class="reference external" href="http://sneakernet.fr/">Arnaud</a> pour la relecture et la correction de quelques typos dans le +texte :)</p> +</div> +Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique-fr.html<p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable …</p><p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable à lire que sa version papier, il reste quand même quelques problèmes, la plupart liés au format de distribution de l’œuvre.</p> +<p>J'avoue ne pas trop savoir quoi penser de tout ça. D'un coté le livre électronique permet de franchir les frontières plus facilement, et semble avoir un tas d'avantage (notamment le fait que se trimbaler avec l'ensemble de sa collection de bouquins est désormais possible).</p> +<p>A mon avis, ce qui pose vraiment problème, ce sont les formats sous lesquels ces livres sont mis à disposition, non pas les livres eux même. Encore une question de DRMs donc…</p> +<p>Encore une problématique liée au copyright et au fait que le copie privée pose des problèmes à l'industrie en place. Ça renvoie à des questions plus profondes, et principalement à la mise en perspective du producteur de contenu et du consomateur de ce même contenu. Exactement ce qu'on essaye de résoudre dans le milieu agricole par le biais des AMAPs.</p> +<p>Sauf qu'ici, on est face au simple problème de la dématérialisation. Est-ce qu'une responsabilisation des consommateurs ne pourrait pas résoudre ce problème de publication ?</p> +<p>Recemment, j'ai récupéré une version piratée d'un livre technique, simplement parce que je ne trouvais pas une version de ce livre en numérique qui me permette de faire une copie privée de celui ci. Un Epub, par exemple. J'ai fait en me disant que c'était un acte militant. Sauf que non, ce n'est pas une solution soutenable, et j'en viens maintenant presque à le regretter. On en discutait rapidement avec <a class="reference external" href="http://ziade.org">Tarek</a> il y à quelques jours et il pointait du doigt que ceux qui en patissent sont les auteurs des livres, non pas les éditeurs (qu'il ne faut pas non plus diaboliser selon moi, ils cherchent à trouver des manières de garder leur coeur de métier).</p> +<p>Or, avoir des auteurs, des personnes qui sont prêtes à partager leur savoir à de larges audiences me semble primordial pour que la répartition du savoir continue à se répendre. Certes, le blogging permet cela dans une faible mesure, mais de manière bien moins construite, et surtout, est fait de manière bénévole (à moins que certains bloggeurs aient trouvé des moyens de rémunération dont j'ignore l'existance ?), donc il est plus difficile pour les auteurs de se dégager du temps pour travailler sur de gros ouvrages (ceci est bien évidemment une généralisation).</p> +<p>Quelles sont nos solutions, donc ? Peut être se tourner vers des solution de publication alternatives, couplées à une résponsabilisation des lecteurs. Je ne pense pas necessairement aux plateformes alternatives comme <a class="reference external" href="http://framabook.org">framabook</a>, parce que je me demande toujours si cela est une solution viable pour les auteurs, du moins dans les premières années, mais au moins des éditeurs qui ne font pas le choix du grand verrou numérique.</p> +<p>On demande pas grand chose, pourtant… Peut être même que de telles initiatives existent déjà ?</p> +<p>Et vous, vous les achetez ou vos livres ?</p> +2012, first months2012-01-21T00:00:00+01:002012-01-21T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-21:/2012-first-months.html<p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services …</p><p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services able to scale out of +the box.</p> +<p>Our most visible and known project, so far, is Firefox Sync, which allows to synchronize +browsing data (tabs, passwords, history, etc.) among different instances of +Firefox. We are also building other things, such as a way to get metrics +easily, a web service based queue, etc. Our primary consumers are +people inside Mozilla, and we want to help them having a simple way to create, +deploy and scale their apps. The project is named &quot;sagrada&quot;, and you +can find some more information about it on <a class="reference external" href="https://wiki.mozilla.org/Services/Sagrada">our public wiki</a></p> +<p>All of what we do, we do it in the open. So you can have a look at <a class="reference external" href="http://github.com/mozilla-services">the +different pieces of code we wrote</a> +and use them / contribute if you want to.</p> +<p>I will not dig in to all the details of what I have been doing, but so far, this have been +a pretty amazing experience. Part of this is explainable by the fact that the +team is made of amazing folks, all with a strong experience in different +topics, so I'm learning things™.</p> +<p>I am currently practicing a bit my C++ to do crypto related things (I may or +may not talk about this later on this web-logs) and it's great (well, it +remembers me why I love python for so many things, but it makes me think closer +to the metal ;)). I love this job.</p> +<p>Second, I moved to Paris. Yes, Paris. Some of you who know me a bit may find +it unexpected, and that's the case. I'm usually not a big fan of big cities and +am a fairly strong defender of having and creating activities in the country side, +to face the rural exodus problem, into other thingS.</p> +<p>I didn't changed my opinion about that. However, I don't want to <em>start</em> by +working remote, especially when working with a remote team. Having offices kind +of help me to have a differentiation between my working place and home, which I +find to be important.</p> +<p>And, to be honest, I don't like Paris for unknown reasons: I +haven't been there, so it's a big over-generalisation to say that it's not +good for me. The reality is that I have no idea of what Paris is, and if I'll +like it or not.</p> +<p>I found a really nice house (yeah, a house!) in Paris and am sharing it with 3 +other persons. We have room, all like good food and… +they are not geeks, which is a big win for me: work is work and home is home.</p> +<p>So far, Paris had been really nice. A lot of things are going on in here, and I +kind of like the way it is possible to find alternative related things in here. +I found a <a class="reference external" href="http://en.wikipedia.org/wiki/Community-supported_agriculture">CSA</a>, +some people interested by agriculture related problems and I like where things +seems to be going.</p> +<p>So, new job, new house, new city, things are going forward and that's great.</p> +<p>Oh, and I will try to post some more technical articles soon, +I'm missing them :)</p> +Using JPype to bridge python and Java2011-11-06T00:00:00+01:002011-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-11-06:/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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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, 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 VM level. This means you need to start a VM +from your python script, but it does the job and stay fully compatible with +Cpython and its C extensions.</p> +<div class="section" id="first-steps-with-jpype"> +<h2>First steps with JPype</h2> +<p>Once JPype installed (you'll have to hack a bit some files to integrate +seamlessly with your system) you can access java classes by doing something +like that:</p> +<div class="highlight"><pre><span></span><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> +</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 them.</p> +</div> +<div class="section" id="interfacing-with-boilerpipe"> +<h2>Interfacing with Boilerpipe</h2> +<p>To install boilerpipe, you just have to run an ant script:</p> +<pre class="literal-block"> +$ cd boilerpipe +$ ant +</pre> +<p>Here is a simple example of how to use boilerpipe in Java, from their sources</p> +<div class="highlight"><pre><span></span><span class="kn">package</span> <span class="nn">de.l3s.boilerpipe.demo</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">java.net.URL</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">de.l3s.boilerpipe.extractors.ArticleExtractor</span><span class="o">;</span> + +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Oneliner</span> <span class="o">{</span> + <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="kd">final</span> <span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="kd">final</span> <span class="n">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="n">URL</span><span class="o">(</span><span class="s">&quot;http://notmyidea.org&quot;</span><span class="o">);</span> + <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ArticleExtractor</span><span class="o">.</span><span class="na">INSTANCE</span><span class="o">.</span><span class="na">getText</span><span class="o">(</span><span class="n">url</span><span class="o">));</span> + <span class="o">}</span> +<span class="o">}</span> +</pre></div> +<p>To run it:</p> +<div class="highlight"><pre><span></span>$ javac -cp dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar src/demo/de/l3s/boilerpipe/demo/Oneliner.java +$ java -cp src/demo:dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar de.l3s.boilerpipe.demo.Oneliner +</pre></div> +<p>Yes, this is kind of ugly, sorry for your eyes. +Let's try something similar, but from python</p> +<div class="highlight"><pre><span></span><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="k">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> +</pre></div> +<p>And you get what you want.</p> +<p>I must say I didn'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, nice!</p> +</div> +How are you handling your shared expenses?2011-10-15T00:00:00+02:002011-10-15T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.html<p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 …</p><p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 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 come.</p> +<p>I said yes and gave it some more thoughts: We probably aren'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, boooh!).</p> +<p>I then discussed with a friend of mine, who was excited about it and wanted to learn +python. Great! That'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 class="reference external" href="http://www.sneakernet.fr/">Arnaud</a> and Quentin!)</p> +<p>Since that, the project now support multiple languages and provides a REST API +(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's it (this was inspired by +doodle)!</p> +<img alt="Capture d'écran du site." src="images/ihatemoney.png" /> +<p>You can try the project at <a class="reference external" href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a> for now, and the +code lives at <a class="reference external" href="https://github.com/spiral-project/ihatemoney/">https://github.com/spiral-project/ihatemoney/</a>.</p> +<div class="section" id="features"> +<h2>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 once.</p> +<p>No, I don'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 way.</p> +<div class="section" id="no-user-registration"> +<h3>No user registration</h3> +<p>You don'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 you).</p> +</div> +<div class="section" id="keeping-things-simple"> +<h3>Keeping things simple</h3> +<p>&quot;Keep It Simple, Stupid&quot; 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're back from the +farmer's market on raw paper.</p> +</div> +<div class="section" id="no-categories"> +<h3>No categories</h3> +<p>Some people like to organise their stuff into different &quot;categories&quot;: +leisure, work, eating, etc. That's not something I want (at least to begin +with).</p> +<p>I want things to be simple. Got that? Great. Just add your bills!</p> +</div> +<div class="section" id="balance"> +<h3>Balance</h3> +<p>One of the most useful thing is to know what's your &quot;balance&quot; compared to +others. In other words, if you're negative, you owe money, if you'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 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 balance.</p> +</div> +<div class="section" id="api"> +<h3>API</h3> +<p>All of what's possible to do with the standard web interface is also available +through a REST API. I developed a simple REST toolkit for flask for this (and +I should release it!).</p> +</div> +</div> +<div class="section" id="interested"> +<h2>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't hesitate +a second! The project lives at <a class="reference external" href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p> +</div> +La simplicité volontaire contre le mythe de l'abondance2011-10-14T00:00:00+02:002011-10-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-14:/la-simplicite-volontaire-contre-le-mythe-de-labondance-fr.html<p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car …</blockquote><p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car il finira par nous poignarder, au moment ou nous pensions +justement pouvoir le vaincre… Entendons-nous bien, il ne s'agit pas +d'apprendre à &quot;positiver&quot; sous prétexte que l'on pourrait &quot;moraliser&quot; ou +repeindre en vert le capitalisme, il s'agit, bien au contraire, d'être aussi +intraitables lorsque nous créons cet autre monde, que lorsque nous étions +ces militants purs mais un peu durs à jouir, il s'agit d'être aussi +indomptables mais sans oublier que le capitalisme ne pourra être arrété que +par du non-capitaliste… c'est-à-dire en multipliant les expérimentations +sociales, en acceptant de faire au maximum sécession, en inventant +(réinventant?) une gauche buissonière et maquisarde, en faisant, au +quotidien, la part belle à la dérive, à des modes de comportement +expérimentaux. 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.</blockquote> +Using dbpedia to get languages influences2011-08-16T00:00:00+02:002011-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.html<p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 …</p><p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 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 technologies.</p> +<p>Well, you may have guessed it, the project in question in dbpedia, and exposes +information in the form of RDF triples, which are way more easy to work with +than simple HTML.</p> +<p>For instance, let's take the page about python: +<a class="reference external" 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 &quot;Influenced&quot; and &quot;InfluencedBy&quot;, 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 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 &quot;( +programming language)&quot;, which is the case for python.</p> +<p>So I've built <a class="reference external" 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 graphviz.</p> +<p>After a nice:</p> +<pre class="literal-block"> +$ python get_influences.py python dot | dot -Tpng &gt; influences.png +</pre> +<p>The result is the following graph (<a class="reference external" href="http://files.lolnet.org/alexis/influences.png">see it directly here</a>)</p> +<img alt="Graph des influances des langages les uns sur les autres." src="http://files.lolnet.org/alexis/influences.png" style="width: 800px;" /> +<p>While reading this diagram, keep in mind that it is a) not listing all the +languages and b) keeping a python 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 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 readable.</p> +<p>You can find the script <a class="reference external" href="https://github.com/ametaireau/experiments">on my github account</a>. Feel free to adapt it for +whatever you want if you feel hackish.</p> +Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html<p>Back in October, I released <a class="reference external" 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 class="reference external" 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 github.</p> +<p>And people started contributing. I wasn'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 requests.</p> +<p><strong>Which is clearly 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 fun.</p> +<p>Thank you, guys, you're why I like open source so much.</p> +Introducing Cornice2011-07-12T00:00:00+02:002011-07-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-12:/introducing-cornice.html<p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of …</p><p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of any kind.</p> +<p>The goal is to simplify your work, but we don't want to reinvent the wheel, so +it is easily pluggable with validations frameworks, such as <a class="reference external" href="http://docs.pylonsproject.org/projects/colander/en/latest/">Colander</a>.</p> +<div class="section" id="handling-errors-and-validation"> +<h2>Handling errors and validation</h2> +<p>Here is how it works:</p> +<div class="highlight"><pre><span></span><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.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> +</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 future)</p> +<p>As you might have seen, <cite>request.errors.add</cite> 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 &quot;body&quot;, +&quot;query&quot;, &quot;headers&quot; or &quot;path&quot;. <strong>name</strong> is the name of the variable causing +problem, if any, and <strong>description</strong> contains a more detailed message.</p> +<p>Let's run this simple service and send some queries to it:</p> +<pre class="literal-block"> +$ curl -v http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: */* +&gt; +* HTTP 1.0, assume close after body +&lt; HTTP/1.0 400 Bad Request +&lt; Content-Type: application/json; charset=UTF-8 +[{&quot;location&quot;: &quot;query&quot;, &quot;name&quot;: &quot;awesome&quot;, &quot;description&quot;: &quot;You lack awesomeness!&quot;} +</pre> +<p>I've removed the extra clutter from the curl's output, but you got the general idea.</p> +<p>The content returned is in JSON, and I know exactly what I have to do: add an +&quot;awesome&quot; parameter in my query. Let's do it again:</p> +<pre class="literal-block"> +$ curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;yay!&quot;} +</pre> +<p>Validators can also convert parts of the request and store the converted value +in <cite>request.validated</cite>. It is a standard dict automatically attached to the +requests.</p> +<p>For instance, in our validator, we can chose to validate the parameter passed +and use it in the body of the webservice:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>The output would look like this:</p> +<pre class="literal-block"> +curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;awesome yeah&quot;} +</pre> +</div> +<div class="section" id="dealing-with-accept-headers"> +<h2>Dealing with &quot;Accept&quot; headers</h2> +<p>The HTTP spec defines a <strong>Accept</strong> header the client can send so the response +is encoded the right way. A resource, available at an URL, can be available in +different formats. This is especially true for web services.</p> +<p>Cornice can help you dealing with this. The services you define can tell which +<cite>Content-Type</cite> values they can deal with and this will be checked against the +<strong>Accept</strong> headers sent by the client.</p> +<p>Let's refine a bit our previous example, by specifying which content-types are +supported, using the <cite>accept</cite> parameter:</p> +<div class="highlight"><pre><span></span><span class="nd">@service.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> +</pre></div> +<p>Now, if you specifically ask for XML, Cornice will throw a 406 with the list of +accepted <cite>Content-Type</cite> values:</p> +<pre class="literal-block"> +$ curl -vH &quot;Accept: application/xml&quot; http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: application/xml +&gt; +&lt; HTTP/1.0 406 Not Acceptable +&lt; Content-Type: application/json; charset=UTF-8 +&lt; Content-Length: 33 +&lt; +[&quot;application/json&quot;, &quot;text/json&quot;] +</pre> +</div> +<div class="section" id="building-your-documentation-automatically"> +<h2>Building your documentation 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 API in your docs.</p> +<div class="highlight"><pre><span></span><span class="p">..</span> <span class="ow">services</span><span class="p">::</span> + <span class="nc">:package:</span> <span class="nf">coolapp</span> + <span class="nc">:service:</span> <span class="nf">quote</span> +</pre></div> +<p>Here is an example of what a generated page looks like: <a class="reference external" href="http://packages.python.org/cornice/exampledoc.html">http://packages.python.org/cornice/exampledoc.html</a></p> +</div> +<div class="section" id="yay-how-can-i-get-it"> +<h2>Yay! How can I get it?</h2> +<p>We just cut a 0.4 release, so it's available at <a class="reference external" href="http://pypi.python.org/pypi/cornice">http://pypi.python.org/pypi/cornice</a> +You can install it easily using <cite>pip</cite>, for instance:</p> +<pre class="literal-block"> +$ pip install cornice +</pre> +<p>You can also have a look at the documentation at +<a class="reference external" href="http://packages.python.org/cornice/">http://packages.python.org/cornice/</a></p> +</div> +<div class="section" id="what-s-next"> +<h2>What's 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 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 class="reference external" href="https://github.com/mozilla-services/cornice">go grab them on github</a> +, commit and send us a pull request!</p> +</div> +Un coup de main pour mon mémoire!2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire-fr.html<p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de main.</p> +<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui connaissent +last.fm, je …</p><p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de 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'avis des personnes qui +ont des profils similaires au votre.</p> +<p>Le projet est loin d'ê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 &quot;tournée +générale&quot;).</p> +<p>J'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'enverra des +information sur les sites que vous visitez (si vous avez l'habitude d'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'un simple clic si vous souhaitez garder votre vie privée privée ;-)</p> +<p>Le site est par là: <a class="reference external" 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'est 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 correctement.</p> +<p>Merci pour votre aide !</p> +Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler-fr.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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un …</p><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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un brin!).</p> +<p>Bosser en extérieur est un réel plaisir et faire quelque chose de manuel +également. Je n'ai pas pour habitude de bricoler autre chose que du logiciel et +c'est vraiment quelque chose que j'apprécie.</p> +<p>J'avoue, je mens un peu quand je dis que j'étais complètement déconnecté: +j'ai vérifié mes mails assez régulièrement en utilisant mon téléphone +(merci Arnaud pour le prêt du gadget!) et j'ai limité ma présence web au strict +minimum. Je veux dire par là pas de twitter, pas d'IRC et autres mailing-lists.</p> +<p>Quand je dis hors-ligne, je ne dis pas que je n'ai pas travaillé sur mon +ordinateur. J'ai à fournir beaucoup plus de travail que ce que je ne pensait en +premier lieu pour la rédaction de mon mémoire et j'ai passé quelques heures par +ci par là à lire des articles et livres sur le sujet ainsi que rédigé une bonne +partie de mon mémoire durant ces 10 jours. Résultat ? Les heures que j'ai passées à travailler ont +été étonnement plus productives que celles que j'ai l'habitude de passer derrière +un écran. Je ne parles pas uniquement du fait de procrastiner; évidemment c'est +une des causes principales de ma perte de productivité, mais je pense également +au fait de laisser le cerveau reposer, au moins en ce qui concerne la partie +informatique. Bricoler demande de la concentration et de la réflexion mais +permet également de laisser son esprit vagabonder. J'ai pu donc avancer mes +sur certaines parties de mon mémoire alors que j'étais en train de poser le +bardage sur la garage par exemple.</p> +<p>Passer du temps sur autre chose (qui demandait également de la concentration +par ailleurs) m'a permis d'être réellement plus efficace lors de mes phases de +rédaction et de lecture.</p> +<p>Je me demande depuis quelques temps quel sera mon futur travail et quelle forme +il prendra. Éééh oui, la fin des études arrive pour la fin de l'année, c'est +pas une blague. Et je me pose sérieusement la question du travail aux 3/4 +temps. La raison principale étant que je ne souhaites pas passer la majeure +partie de mon temps à travailler derrière un écran et que la formation que j'ai +m'y rattache beaucoup. Ne me comprenez pas de travers: j'aime ce que je fais; +mais j'aime aussi ce que je fais à coté de l'informatique: associatif, projets +alternatifs, permaculture et autres.</p> +<p>Viens s'ajouter à ça le fait d'avoir une qualité de vie qui me semble pouvoir +passer par le fait de travailler moins (&quot;il est marant ce gamin, il à pas encore commencé +à travailler qu'il veut bosser moins, regarde moi cette feignasse!&quot;) et +travailler plus efficacement. Bien sur, on n'est jamais 100% productif et c'est +d'autant plus vrai pour moi, alors si gagner en productivité peut passer par +travailler moins, pourquoi pas s'y essayer !</p> +<p>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 ?</p> +Analyse users' browsing context to build up a web recommender2011-04-01T00:00:00+02:002011-04-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.html<p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full …</p><p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full time on my dissertation topic.</p> +<p>When I learned we'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's the good time to learn.</p> +<p>Since a long time, I'm being impressed by the <a class="reference external" href="http://last.fm">last.fm</a> +recommender system. They're <em>scrobbling</em> the music I listen to since something +like 5 years now and the recommendations they're doing are really nice and +accurate (I discovered <strong>a lot</strong> of great artists listening to the +&quot;neighbour radio&quot;.) (by the way, <a class="reference external" href="http://lastfm.com/user/akounet/">here is</a> +my lastfm account)</p> +<p>So I decided to work on recommender systems, to better understand what is it +about.</p> +<p>Recommender systems are usually used to increase the sales of products +(like Amazon.com does) which is not really what I'm looking for (The one who +know me a bit know I'm kind of sick about all this consumerism going on).</p> +<p>Actually, the most simple thing I thought of was the web: I'm browsing it quite +every day and each time new content appears. I've stopped to follow <a class="reference external" 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 class="reference external" href="http://twitter.com/ametaireau/">on +twitter</a>.</p> +<p>Too much information kills the 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're probably not interested by the same topics at different +times of the day, or depending on the computer you're using. We can also +probably make good use of the way you browse to create groups into the content +you're browsing (or even use the great firefox4 tab group feature).</p> +<p>There is a large part of concerns to have about user's privacy as well.</p> +<p>Here is my proposal (copy/pasted from the one I had to do for my master)</p> +<div class="section" id="introduction-and-rationale"> +<h2>Introduction and 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 articles.</p> +<p>A lot of people share the same interest to various topics, and the quantity of +information is such than it'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 perspective.</p> +<p>Machine learning is a branch of Artificial Intelligence (AI) 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 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'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 else.</p> +<p>Page contents are also interesting to analyse, because that'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 etc.)</p> +<p>The goal of this dissertation is to create a recommender system for web links, +including this context 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 system.</p> +</div> +<div class="section" id="background-review"> +<h2>Background 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 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's +browsers.</p> +<div class="section" id="data-preparation-and-extraction"> +<h3>Data preparation and 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 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, 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, 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 HTML pages so there is a need of tools to recognise 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 &quot;liked&quot; a resource, and +determine a mark for it, which can be used by information filtering a later +step (T. Segaran, 2007).</p> +<p>At this stage, structuring the data is required. Storing this kind of +information in RDBMS 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 querying.</p> +</div> +<div class="section" id="information-filtering"> +<h3>Information filtering</h3> +<p>To filter the information, three techniques can be used (Balabanovic et +Al, 1997):</p> +<ul class="simple"> +<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's about +establishing a profile for the user and compare new items against 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 to.</li> +<li>the hybrid approach, which appeared recently combine both of the previous +approaches, giving recommendations when items score high regarding user's +profile, or if a similar user already liked 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, 2007).</p> +<p>References:</p> +<ul class="simple"> +<li>Balabanović, M., &amp; Shoham, Y. (1997). Fab: content-based, collaborative +recommendation. Communications of the ACM, 40(3), 66–72. ACM. +Retrieved March 1, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp">http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp</a>;.</li> +<li>Berners-Lee, T., Hendler, J., &amp; Lassila, O. (2001). +The semantic web: Scientific american. Scientific American, 284(5), 34–43. +Retrieved November 21, 2010, from <a class="reference external" href="http://www.citeulike.org/group/222/article/1176986">http://www.citeulike.org/group/222/article/1176986</a>.</li> +<li>Castellano, G., Fanelli, A., &amp; Torsello, M. (2007). +LODAP: a LOg DAta Preprocessor for mining Web browsing patterns. Proceedings of the 6th Conference on 6th WSEAS Int. Conf. on Artificial Intelligence, Knowledge Engineering and Data Bases-Volume 6 (p. 12–17). World Scientific and Engineering Academy and Society (WSEAS). Retrieved March 8, 2011, from <a class="reference external" 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., &amp; Nejdl, W. (2010). Boilerplate detection using shallow text features. Proceedings of the third ACM international conference on Web search and data mining (p. 441–450). ACM. Retrieved March 8, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=1718542">http://portal.acm.org/citation.cfm?id=1718542</a>.</li> +<li>Myatt, G. J. (2007). Making Sense of Data: A Practical Guide to Exploratory +Data Analysis and Data Mining.</li> +<li>Segaran, T. (2007). Collective Intelligence.</li> +</ul> +</div> +</div> +<div class="section" id="privacy"> +<h2>Privacy</h2> +<p>The first thing that's come to people minds when it comes to process their +browsing data is privacy. People don't want to be stalked. That's perfectly +right, and I don't either.</p> +<p>But such a system don't have to deal with people identities. It's completely +possible to process completely anonymous data, and that's probably what I'm +gonna 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 !</p> +</div> +<div class="section" id="what-s-the-plan"> +<h2>What's the plan ?</h2> +<p>There is a lot of different things to explore, especially because I'm +a complete novice in that field.</p> +<ul class="simple"> +<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 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 db?</li> +<li>Process the data using well known recommendation algorithms. Compare the +results and criticize their value.</li> +</ul> +<p>There is plenty of stuff I want to try during this experimentation:</p> +<ul class="simple"> +<li>I want to try using Geshi to visualize the connexion between the links, +and the contexts</li> +<li>Try using graph databases such as Neo4j</li> +<li>Having a deeper look at tools such as scikit.learn (a machine learning +toolkit in python)</li> +<li>Analyse web pages in order to categorize them. Processing their +contents as well, to do some keyword based classification will be done.</li> +</ul> +<p>Lot of work on its way, yay !</p> +</div> +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:00Alexis Métaireautag: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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time …</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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time in a console while +developing, it's possible to work via ssh, from everywhere.</p> +<p>The only problem is the synchronisation of the source code, config files etc. +from my machine to the server.</p> +<p>Unison provides an interesting way to synchronise two folders, even over +a network. So let's do it !</p> +<div class="section" id="creating-the-jail"> +<h2>Creating the jail</h2> +<p>In case you don't use FreeBSD, you can skip this section.</p> +<div class="highlight"><pre><span></span><span class="c1"># I have a flavour jail named default</span> +$ ezjail-admin -f default workspace.notmyidea.org <span class="m">172</span>.19.1.6 +$ ezjail-admin start workspace.notmyidea.org +</pre></div> +<p>In my case, because the &quot;default&quot; flavour contains already a lot of interesting +things, my jail come already setup with ssh, bash and vim for instance, but +maybe you'll need it in your 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 <cite>/etc/pf.conf</cite>:</p> +<pre class="literal-block"> +workspace_jail=&quot;172.19.1.6&quot; +rdr on $ext_if proto tcp from any to $ext_ip port 20006 -&gt; $workspace_jail port 22 +</pre> +<p>Reload packet filter rules</p> +<div class="highlight"><pre><span></span>$ /etc/rc.d/pf reload +</pre></div> +</div> +<div class="section" id="working-with-unison"> +<h2>Working with unison</h2> +<p>Now that we'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 it</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> +$ make -C /usr/ports/net/unison-nox11 config-recursive +$ make -C /usr/ports/net/unison-nox11 package-recursive +</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 2.32.52.</p> +<p>Check that unison is installed and reachable via ssh from your machine</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> unison -version +unison version <span class="m">2</span>.27.157 +$ unison -version +unison version <span class="m">2</span>.27.57 +</pre></div> +</div> +<div class="section" id="let-sync-our-folders"> +<h2>Let sync our folders</h2> +<p>The first thing I want to sync is my vim configuration. Well, it's already <a class="reference external" href="http://github.com/ametaireau/dotfiles/">in +a git repository</a> but let's try to use +unison for it right now.</p> +<p>I have two machines then: <cite>workspace</cite>, the jail, and <cite>ecureuil</cite> my laptop.</p> +<div class="highlight"><pre><span></span>unison .vim ssh://notmyidea.org:20006/.vim +unison .vimrc ssh://notmyidea.org:20006/.vimrc +</pre></div> +<p>It is also possible to put all the informations in a config file, and then to +only run <cite>unison</cite>. (fire up <cite>vim ~/.unison/default.prf</cite>.</p> +<p>Here is my config:</p> +<pre class="literal-block"> +root = /home/alexis +root = ssh://notmyidea.org:20006 + +path = .vimrc +path = dotfiles +path = dev + +follow = Name * +</pre> +<p>My vimrc is in fact a symbolic link on my laptop, but I don't want to specify +each of the links to unison. That's why the <cite>follow = Name *</cite> is 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 2GB in 20mn ;)</p> +</div> +<div class="section" id="run-the-script-frequently"> +<h2>Run the script 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've wrote a tiny script to get some +feedback from the sync:</p> +<div class="highlight"><pre><span></span><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="bp">True</span> + <span class="n">error</span> <span class="o">=</span> <span class="bp">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; {0}&#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="bp">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 {0}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 {2} &quot;{0}&quot; &quot;{1}&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> +</pre></div> +<p>This is probably perfectible, but that does the job.</p> +<p>Last step is to tell you machine to run that frequently. That's what <cite>crontab</cite> +is made for, so let's <cite>crontab -e</cite>:</p> +<pre class="literal-block"> +$ * */3 * * * . ~/.Xdbus; /usr/bin/python /home/alexis/dev/python/unison-syncer/sync.py +</pre> +<p>The <cite>~/.Xdbus</cite> allows cron to communicate with your X11 session. Here is its +content.</p> +<div class="highlight"><pre><span></span><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 -u <span class="nv">$LOGNAME</span> -n 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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$nautilus_pid</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">exit</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="k">$(</span>tr <span class="s1">&#39;\0&#39;</span> <span class="s1">&#39;\n&#39;</span> &lt; /proc/<span class="nv">$nautilus_pid</span>/environ <span class="p">|</span> grep <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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$DBUS_SESSION_BUS_ADDRESS</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">echo</span> <span class="s2">&quot;Failed to find bus address&quot;</span> &gt;<span class="p">&amp;</span><span class="m">2</span> +<span class="nb">exit</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> DBUS_SESSION_BUS_ADDRESS +</pre></div> +<p>And it comes from <a class="reference external" 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 developments.</p> +</div> +Wrap up of the distutils2 paris' sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00Alexis Métaireautag: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've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what …</p><p>Finally, thanks to a bunch of people that helped me to pay my train and bus +tickets, I've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what we've been working on:</p> +<ul class="simple"> +<li>the <cite>datafiles</cite>, a way to specify and to handle the installation of files which +are not python-related (pictures, manpages and so on).</li> +<li><cite>mkgcfg</cite>, a tool to help you to create a setup.cfg in minutes (and with funny +examples)</li> +<li>converters from setup.py scripts. We do now have a piece of code which +reads your current <cite>setup.py</cite> file and fill in some fields in the <cite>setup.cfg</cite> +for you.</li> +<li>a compatibility layer for distutils1, so it can read the <cite>setup.cfg</cite> you will +wrote for distutils2 :-)</li> +<li>the uninstaller, so it's now possible to uninstall what have been installed +by distutils2 (see PEP 376)</li> +<li>the installer, and the setuptools compatibility layer, which will allow you +to rely on setuptools' based distributions (and there are plenty of them!)</li> +<li>The compilers, so they are more flexible than they were. Since that'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 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 use.</p> +<p>I'm really pleased to see how newcomers went trough the code, and started +hacking so fast. I must say it wasn't the case when we started to work on +distutils1 so that's a very good point: people now can hack the code quicker +than they could 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 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 +bears^Wbeers.</p> +<p>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 :-)</p> +PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00Alexis Métaireautag: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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +drawbacks.</p> +<p>Basically, if you want to use informations coming from the simple API, you will +have to parse web pages manually, to extract informations using some black +vodoo magic. Badly, magic have a price, and it's sometimes impossible to get +exactly the informations you want to get from this index. That's the technique +currently being used by distutils2, setuptools and pip.</p> +<p>On the other side, while XML/RPC is working fine, it'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's important to point out that, even if +PyPI have a mirroring infrastructure, it's only for the so-called <em>simple</em> API, +and not for the XML/RPC.</p> +<div class="section" id="couchdb"> +<h2>CouchDB</h2> +<p>Here comes CouchDB. CouchDB is a document oriented database, that +knows how to speak REST and JSON. It's easy to use, and provides out of the box +a replication mechanism.</p> +</div> +<div class="section" id="so-what"> +<h2>So, what ?</h2> +<p>Hmm, I'm sure you got it. I'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 HTTP request on the CouchDB server. You can also access the informations +from the index directly using a REST API, speaking json. Handy.</p> +<p>So PyPIonCouch is using the PyPI XML/RPC API to get data from PyPI, and +generate records in the CouchDB instance.</p> +<p>The final goal is to avoid to rely on this &quot;simple&quot; API, and rely on a REST +insterface instead. I have set up a couchdb server on my server, which is +available at <a class="reference external" 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've done the first import from PyPI yesterday and all +went fine: it's possible to access the metadata of all PyPI projects via a REST +interface. Next step is to write a client for this REST interface in +distutils2.</p> +</div> +<div class="section" id="example"> +<h2>Example</h2> +<p>For now, you can use pypioncouch via the command line, or via the python API.</p> +<div class="section" id="using-the-command-line"> +<h3>Using the command line</h3> +<p>You can do something like that for a full import. This <strong>will</strong> take long, +because it's fetching all the projects at pypi and importing their metadata:</p> +<pre class="literal-block"> +$ pypioncouch --fullimport http://your.couchdb.instance/ +</pre> +<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 http://couchdb.notmyidea.org/pypi/</strong>, to avoid +the duplication of nodes:</p> +<pre class="literal-block"> +$ pypioncouch --update http://your.couchdb.instance/ +</pre> +<p>The principal node is updated once a day by now, I'll try to see if it's +enough, and ajust with the time.</p> +</div> +<div class="section" id="using-the-python-api"> +<h3>Using the python API</h3> +<p>You can also use the python API to interact with pypioncouch:</p> +<pre class="literal-block"> +&gt;&gt;&gt; from pypioncouch import XmlRpcImporter, import_all, update +&gt;&gt;&gt; full_import() +&gt;&gt;&gt; update() +</pre> +</div> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I want to make a couchapp, in order to navigate PyPI easily. Here are some of +the features I want to propose:</p> +<ul class="simple"> +<li>List all the available projects</li> +<li>List all the projects, filtered by specifiers</li> +<li>List all the projects by author/maintainer</li> +<li>List all the projects by keywords</li> +<li>Page for each project.</li> +<li>Provide a PyPI &quot;Simple&quot; API 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 replication</li> +</ul> +<p>I also still need to polish the import mechanism, so I can directly store in +couchdb:</p> +<ul class="simple"> +<li>The OPML files for each project</li> +<li>The upload_time as couchdb friendly format (list of int)</li> +<li>The tags as lists (currently it's only a string separated by spaces</li> +</ul> +<p>The work I've done by now is available on +<a class="reference external" href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it's still +a work in progress, and everything can break at any time. However, any feedback +will be appreciated !</p> +</div> +Help me to go to the distutils2 paris' sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00Alexis Métaireautag: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 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 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 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 event.</p> +<p>You can find more informations about the sprint on the wiki page of the event +(<a class="reference external" 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'm unfortunately blocked in UK for money reasons. +The cheapest two ways I've found is about £80, which I can't afford. +Following some advices on #distutils, I'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 way.</p> +<p>I'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't make it to paris, I'll hang around on IRC to give some help +while needed.</p> +<p>If you want to contribute some money to help me go there, feel free to use this +chipin page: <a class="reference external" href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> +<p>Thanks for your support !</p> +Quels usages pour l'informatique ?2011-01-12T00:00:00+01:002011-01-12T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-01-12:/usages-informatique-fr.html<p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas …</p><p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas vous pourrir la vie. Oui, parce que de +l'informatique on en a partout, des &quot;geeks&quot; et des &quot;accros&quot; aussi, et que ça +vient s'immiscer dans nos vies même quand d'autres moyens ou médias sont plus +utiles ou pertinents.</p> +<p>Certes, l'informatique nous permet de communiquer et travailler plus efficacement, +Mais à quel prix ? Ce n'est pas parce qu'il est possible d'<a class="reference external" href="http://retourdactu.fr/2011/11/07/la-non-communication-nouveau-modele-de-societe/">industrialiser +l'éducation</a> +(ou l'agriculture !), que l'on doit le faire. Oui, ça me dérange d'être une des +nombreuses personnes à l'œuvre derrière cette soit disant &quot;révolution&quot;, qui +n'est pas toujours pour le meilleur. Attention, je ne remets pas l'informatique +et son intérêt en cause: je me pose des questions quand à la place que je veux +lui donner et la place que je souhaites occuper dans son évolution. Ce n'est +pas parce qu'on peut tuer avec un marteau (avec un peu de volonté) qu'il s'agit +d'un mauvais outil, mais si tout le monde se met à tuer avec des marteaux (y a +des malades partout, hein), alors se poser la question de son rôle, en tant que +fabricant de marteaux me semble nécessaire (oui, je vous l'accorde, on aura vu +des comparaisons plus perspicaces).</p> +<p>Donc: à partir de quel moment l'informatique cesse d'être un outil utile pour +transformer nos modes de vies d'une manière qui me dérange ? Peut être avec son +arrivée sur des périphériques mobiles ? Peut être quand elle se fait +l'instrument du consumérisme et de l'individualisme.</p> +<div class="section" id="et-alors-on-fait-quoi"> +<h2>Et alors, on fait quoi ?</h2> +<p>Mais si je continue à faire de l'informatique, il y a bien des raison. J'ai +d'ailleurs trouvé mon intérêt de par le coté collaboratif qui est permis et +développé par l'outil informatique, et notamment par le réseau des réseaux +(internet). Faisons ensemble, mes amis. Prouvons que la collaboration a de +meilleurs jours à vivre que la compétition. Le web, notamment, est une avancée +majeure en ce qui concerne la liberté d'expression et le partage de +connaissances (oui, kipédia). Je vous conseille d'ailleurs à ce propos +<a class="reference external" href="http://owni.fr/2011/11/30/vers-une-economie-de-la-contribution/">l'excellent discours tenu par Bernard Stiegler</a> paru +récemment sur <a class="reference external" href="http://www.owni.fr">owni</a>.</p> +<p>Et c'est cet avenir qu'il me plait de défendre: l'ouverture d'esprit, la +possibilité que chacun puisse contribuer et participer à une base de savoir +commune, en apprenant des autres. Mais par pitié, n'imposons pas la +technologie là où elle n'est pas nécessaire, et utilisons la avec tact quand +elle peut nous être profitable.</p> +<p>Il me plait de repenser l'informatique comme outil et non plus comme mode de +vie. Faisons le l'outil de la collaboration. À l'école, apprenons à nos enfants +à collaborer, à susciter le partage, pas uniquement avec l'outil informatique, +mais aussi avec celui ci, tout en leurs apprenant à avoir un regard critique +sur les informations qu'ils reçoivent.</p> +<p>En bref, questionner le rôle que l'on souhaite avoir dans notre société par le +biais de l'informatique est nécessaire. Comme d'autres, je suis arrivé +à l'informatique par le biais du premier ordinateur familial, il y a de ça une +bonne quinzaine d'années. Ça intrigue, on touche un peu à tout (on en fait des +conneries !) et on finit par apprendre/comprendre comment ça marche, petit +à petit. Cette curiosité n'est d'ailleurs pas le propre de l'informatique +puisqu'on la retrouve dans la cuisine, dans le bricolage et dans un tas de +domaines de notre vie quotidienne.</p> +<p>Finalement, c'est aimer bidouiller, et comprendre comment ça fonctionne, quitte +à sortir les compétences de leur domaine de prédilection (qui a dit que +l'informatique ne pouvait être artistique ?) Le mouvement hacker (bidouilleurs) +aime à sortir l'informatique de son carcan et l'appliquer ailleurs.</p> +<p>C'est de cette manière que j'ai envie de considérer mon métier, qui avant tout +est une passion. Je suis un bidouilleur, j'aime découvrir comment les choses +fonctionnent et avoir une panoplie d'outils qui me permettent de répondre à des +besoins réels.</p> +</div> +<div class="section" id="favoriser-la-collaboration"> +<h2>Favoriser la collaboration</h2> +<p>Et donc, en tant qu'individu, pourquoi faire de l'informatique ? Qu'est-ce qui +m'attire dans cet outil ?</p> +<p>Ce qu'on pourrait qualifier de &quot;recherche fondamentale&quot;, l'écriture de +bibliothèques logicielles, est important mais n'est pas tout. Ce qui importe ce +sont les usages qui en découlent. Je souhaite <strong>savoir écrire des outils qui +sont utiles</strong>, <strong>qui favorisent la collaboration et participent à l'ouverture +des esprits</strong>.</p> +<p>Je choisis de faire de l'informatique pour créer les outils qui répondent à des +problématiques réelles, pour trouver de meilleures manières de communiquer et +de travailler ensemble. Mais, comme me le disait David, d'<a class="reference external" href="http://outils-reseaux.org/PresentationProjet">Outils-Réseaux</a>, on ne crée pas de la +coopération: rien ne sert d'essayer de faire coopérer des gens qui ne veulent +pas. On peut, cependant, la faciliter, en utilisant les bons outils et en +formant les gens à leur utilisation, ainsi qu'aux pratiques collaboratives +(qui, je le répète, ne s'arrêtent pas du tout aux frontières informatique).</p> +<p>Le logiciel libre, avant d'être une force pour le marché logiciel, est une +application du partage. Une démonstration qu'il est possible de travailler +ensemble pour fabriquer quelque chose de fonctionnel et d'utile pour tous. Une +sorte d'antithèse de ce modèle capitaliste incarné par les brevets logiciel.</p> +<p>A plusieurs reprises, j'ai été bluffé par la réalité du logiciel libre. Oui, il +est facile de collaborer lorsqu'on crée un logiciel, pour peu qu'on explique +les tenants et les aboutissants aux participants. Les contributeurs sortent +d'on ne sait où, pour peu que le projet leur soit utile. Je ne parle pas +d'outils &quot;corpo compliant&quot; (bien que ça soit probablement aussi le cas), mais +d'outils que j'ai pu développer pour mon propre usage, et sur lesquels il a été +possible de collaborer avec d'autres.</p> +<p>Parce que l'informatique est utile dans bien des milieux, parce qu'elle peut +être (et elle l'est) un vecteur de participation et de collaboration, défendons +les valeurs qui nous sont chères (logiciels libres et ouverts!) et construisons +des ponts entre les initiatives qui nous parlent (fermes autogérées, +initiatives d'éducation populaire) et l'informatique.</p> +<p>Faisons en sorte de rendre l'informatique accessible et utile dans les milieux +ou elle peut apporter quelque chose !</p> +</div> +Fork you ! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html<p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to …</p><p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to share +our knowledge.</p> +<p>I say github, because it seems to be the more mainstream, but I think it's +something strongly related to the <a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_revision_control">DVCS</a> principles: the &quot;only&quot; thing github have +made is to turn that into a social network, and to reveal the awesomeness of the +DVCSes to the masses.</p> +<p>What is really interesting is to see how this platform is addictive: it's +automatically updating a webpages with the more accurate informations about the +projects you're involved in, and add a bit of magic to that using webhooks, +allowing you to update your website each time you push to you repository, for +instance.</p> +<p>Quite nothing, indeed, but, I don't know why, I find this fascinating.</p> +<p>I haven't had the privilege to see my projects forked from github by strangers, +but I've forked others repository to give an hand some times, when I wanted to, +and the main reason is &quot;because it's <strong>fun</strong>&quot; to do so.</p> +<p>Yeah, you're probably right, you have to be a nerd to find fun to fork others. +The good point is that geeks are a kind of nerds, and some geeks are coders :)</p> +<div class="section" id="new-ways-to-contribute"> +<h2>New ways to contribute</h2> +<p>In addition, it seems that he community, or the communities, are there, on those +new social networks for coders. It's really handy to drop an eye on interesting +projects, to report bugs, propose new features, and check what new projects this +or this person have made.</p> +<p>Well, &quot;it's not new&quot;, you may think. That's true, because it's been a while that +SVN was there and even CVS before that. But, it was a bit messy to &quot;fork&quot; a +project, isn't it ? And I'm not talking about all the hell SVN involved with it +(who have not had issues with those messy .svn folders raises an hand !).</p> +<p>It have not been so easy to share code and thoughts about code, to propose +changes on existing code, than now. You think it's better to implement this or +that in a different way ? Clone it (fork it), make your changes and publish +them, and then ask projects owners about it. For sure you'll have answers.</p> +<p>Even if they don't want it, you can easily keep your changes, and keep getting +their updates!</p> +<p>Also, lot of <em>fashionables</em> projects tend to move on DVCS. +Personally, if I know I can fork on a DVCS instead of from a &quot;simple&quot; VCS, +I'll probably be quicker to fork/clone, and to publish changes on my own copy, +than if I had to do so on the upstream repository (and I'll likely dont have +the rights to push to it), because I will not be afraid to break things.</p> +<p>DVCSes makes the contribution easier.</p> +</div> +<div class="section" id="release-early-release-often"> +<h2>Release early, release often</h2> +<p>Maybe have you read <a class="reference external" href="http://www.catb.org/~esr/writings/cathedral-bazaar/">The cathedral and the bazaar</a>, by Eric Steven Raymond ? +(If not, consider doing so, it's a really interesting reading)</p> +<p>Among a lot of others interesting things, one hint he gives is <em>release early, +release often</em>.</p> +<p>I understand it as: if you want to get contributors, release your code early, +even if it's not perfect, and don't be afraid to publish your changes each +time it's needed.</p> +<p>Without notifying it, that's basically what I was doing for my own projects. +I guess that's because Social coding platforms encourages those practices, +partially cause of the possible impact publishing each of your changes can have +on your final solution.</p> +<p>If you have considered publishing your projects, code snippets, or whatever +(code related) but did not done it, considering them not yet ready, maybe +should you think about it twice: you can get feedback and probably start some +interesting discussions about it, if you write code that's readable, of course!</p> +</div> +<div class="section" id="a-step-further-for-open-source-softwares"> +<h2>A step further for open source softwares</h2> +<p>Well, DVCSes are a honking great idea, and they're starting to be really +powerful when applied to free softwares. I mean: if you can't see a project, +it will be hard to contribute to it. And, I don't think anyone wants to +contribute to something closed/proprietary, <em>just for fun</em>. Or maybe am I +missing something.</p> +<p>Maybe it's a kind of revolution, about free and open source softwares (<a class="reference external" href="http://en.wikipedia.org/wiki/Free_and_open_source_software">FOSS</a>), +that is going on. I really like to know I have my word to say about the changes +in the tools I use, and to know that I can make them evolve.</p> +<p>Let's take an example. Imagine I'm using a web framework on daily basis, as a +part of my job as a web developer. I do like using an open source software +because I know how it's working, and because I know that I can interact with the +authors of the framework while they're doing the changes on it.</p> +<p>That's communication, nothing more, and of course I can do that with an internal +proprietary solution, but it will cost me <strong>a lot</strong> more time, for a dead-simple +reason: a company is not as big and powerful as a community can be: it will cost +time to work on this framework, resources to maintain it, fix bugs etc.</p> +<p>Well, I'm starting advocating here about Free and Open Source Softwares use on +companies, what is a bit beyond the scope of this article, so let's back to +our DVCSes and new social related tools.</p> +<p>If I find a bug in this framework, while working, I have the possibility to +go and talk with the creators of the framework, to open a ticket, and even to +make a fix for it, because I've access to the source code. If I want to create a +new feature, I just have to fork it, hack it, and then publish my code to have +feedback of the community.</p> +<p>My fix/work will benefit to all the people (and maybe others companies) working +with this framework, and it's a way to prove the community that my company is +enough skilled to make code-fixes to the framework, so that's all good !</p> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I hope those social coding platforms are only the begining of a new area. I hope +they will make people realize what the power of the community is, and how easily +they can becomes part of it.</p> +<p>If you're not using them right now, maybe you should do so: have a +look 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 !</p> +</div> +How to reboot your bebox using the CLI2010-10-21T00:00:00+02:002010-10-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.html<p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using …</p></div><p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using directly the +command line tools curl, grep and tail (but really harder to read).</p> +<div class="highlight"><pre><span></span>curl -X POST -u joel:joel 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 -d <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="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> +</pre></div> +</div> +<div class="section" id="the-python-version"> +<h2>The Python version</h2> +<p>Well, that's not the optimal solution, that's a bit &quot;gruik&quot;, but it works.</p> +<div class="highlight"><pre><span></span><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="bp">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> +</pre></div> +</div> +Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html<p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some …</p><p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some time ago, I've made a little python script to ease that, and you can now +use it too. It's named &quot;gnome-background-generator&quot;, and you can install it via +pip for instance.</p> +<div class="highlight"><pre><span></span>$ pip install gnome-background-generator +</pre></div> +<p>Then, you have just to use it this way:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator -p ~/Images/walls -s +/home/alexis/Images/walls/dynamic-wallpaper.xml generated +</pre></div> +<p>Here is a extract of the <cite>--help</cite>:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator --help +usage: gnome-background-generator <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-p PATH<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> + <span class="o">[</span>-t TRANSITION_TIME<span class="o">]</span> <span class="o">[</span>-d DISPLAY_TIME<span class="o">]</span> <span class="o">[</span>-s<span class="o">]</span> + <span class="o">[</span>-b<span class="o">]</span> + +A simple <span class="nb">command</span> line tool to generate an XML file to use <span class="k">for</span> gnome +wallpapers, to have dynamic walls + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -p PATH, --path PATH Path to look <span class="k">for</span> the pictures. If no output is + specified, will be used too <span class="k">for</span> outputing the dynamic- + wallpaper.xml file. Default value is the current + directory <span class="o">(</span>.<span class="o">)</span> + -o OUTPUT, --output OUTPUT + Output filename. If no filename is specified, a + dynamic-wallpaper.xml file will be generated in the + path containing the pictures. You can also use <span class="s2">&quot;-&quot;</span> to + display the xml in the stdout. + -t TRANSITION_TIME, --transition-time TRANSITION_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> transitions must last <span class="o">(</span>default value + is <span class="m">2</span> seconds<span class="o">)</span> + -d DISPLAY_TIME, --display-time DISPLAY_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> a picture must be displayed. Default + value is <span class="m">900</span> <span class="o">(</span>15mn<span class="o">)</span> + -s, --set-background <span class="s1">&#39;&#39;</span><span class="err">&#39;</span>try to <span class="nb">set</span> the background using gnome-appearance- + properties + -b, --debug +</pre></div> +How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html<p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr …</pre><p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr/ports/lang/php5-extensions +$ make package-recursive -C /usr/ports/lang/php5-extensions + +# install nginx +$ make config-recursive -C /usr/ports/www/nginx-devel +$ make package-recursive -C /usr/ports/www/nginx-devel +</pre> +<p>Now we have all the dependencies installed, we need to configure a bit the +server.</p> +<p>That's a simple thing in fact, but it could be good to have something that will +work without effort over time.</p> +<p>Here's a sample of my configuration:</p> +<pre class="literal-block"> +server { + server_name ndd; + set $path /path/to/your/files; + root $path; + + location / { + index index.php; + } + + location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { + access_log off; + expires 30d; + } + + location ~ .php$ { + fastcgi_param SCRIPT_FILENAME $path$fastcgi_script_name; + fastcgi_pass backend; + include fastcgi_params; + } +} + +upstream backend { + server 127.0.0.1:9000; +} +</pre> +<p>And that's it !</p> +Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html<p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple tool to generate your …</p><p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" 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's easy to extend, +and has a template support (via jinja2).</p> +<p>I'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's needs.</p> +<p>Need an example ? You're looking at it ! This weblog is using pelican to be +generated, also for the atom feeds.</p> +<p>I've released it under AGPL, since I want all the modifications to be profitable +to all the users.</p> +<p>You can find a repository to fork at <a class="reference external" href="https://github.com/getpelican/pelican/">https://github.com/getpelican/pelican/</a>. +feel free to hack it !</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 (<cite>pelican --help</cite>)</p> +<div class="highlight"><pre><span></span>$ pip install pelican +</pre></div> +<div class="section" id="usage"> +<h2>Usage</h2> +<p>Here's a sample usage of pelican</p> +<div class="highlight"><pre><span></span>$ pelican . +writing /home/alexis/projets/notmyidea.org/output/index.html +writing /home/alexis/projets/notmyidea.org/output/tags.html +writing /home/alexis/projets/notmyidea.org/output/categories.html +writing /home/alexis/projets/notmyidea.org/output/archives.html +writing /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 ! +</pre></div> +<p>You also can use the <cite>--help</cite> option for the command line to get more +informations</p> +<div class="highlight"><pre><span></span><span class="nv">$pelican</span> --help +usage: pelican <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-t TEMPLATES<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> <span class="o">[</span>-m MARKUP<span class="o">]</span> <span class="o">[</span>-s SETTINGS<span class="o">]</span> <span class="o">[</span>-b<span class="o">]</span> + path + +A tool to generate a static blog, with restructured text input files. + +positional arguments: + path Path where to find the content files <span class="o">(</span>default is + <span class="s2">&quot;content&quot;</span><span class="o">)</span>. + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -t TEMPLATES, --templates-path TEMPLATES + Path where to find the templates. If not specified, + will uses the ones included with pelican. + -o OUTPUT, --output OUTPUT + Where to output the generated files. If not specified, + a directory will be created, named <span class="s2">&quot;output&quot;</span> in the + current path. + -m MARKUP, --markup MARKUP + the markup language to use. Currently only + ReSTreucturedtext is available. + -s SETTINGS, --settings SETTINGS + the settings of the application. Default to None. + -b, --debug +</pre></div> +<p>Enjoy :)</p> +</div> +An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html<p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the …</p><p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the PyPI +testing infrastructure. You could find what each person have done +on +<a class="reference external" 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 shape.</p> +<p>Then, I'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've been introducing myself to +python in the late 2009.</p> +<p>I'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've traveled +since I wrote it.</p> +<p>This summer was awesome because I've learned about python good +practices, now having some strong +<a class="reference external" href="http://mercurial.selenic.com/">mercurial</a> knowledge, and I've +seen a little how the python community works.</p> +<p>Then, I would like to say a big thanks to all the mentors that have +hanged around while needed, on IRC or via mail, and especially my +mentor for this summer, <a class="reference external" 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 work!</p> +<div class="section" id="why"> +<h2>Why ?</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 way.</p> +<p>Now, we have PEPs that describes some format we agreed on (see PEP +345), and we wanted to have a tool on which users can base their +code on, that's <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>.</p> +</div> +<div class="section" id="my-job"> +<h2>My job</h2> +<p>I had to provide a way to crawl the PyPI indexes in a simple way, +and do some installation / uninstallation scripts.</p> +<p>All the work done is available in +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket repository</a>.</p> +<div class="section" id="crawling-the-pypi-indexes"> +<h3>Crawling the PyPI indexes</h3> +<p>There are two ways of requesting informations from the indexes: +using the &quot;simple&quot; index, that is a kind of REST index, and using +XML-RPC.</p> +<p>I've done the two implementations, and a high level API to query +those twos. Basically, this supports the mirroring infrastructure +defined in PEP 381. So far, the work I've done is gonna be used in +pip (they've basically copy/paste the code, but this will change as +soon as we get something completely stable for distutils2), and +that's a good news, as it was the main reason for what I've done +that.</p> +<p>I've tried to have an unified API for the clients, to switch from +one to another implementation easily. I'm already thinking of +adding others crawlers to this stuff, and it was made to be +extensible.</p> +<p>If you want to get more informations about the crawlers/PyPI +clients, please refer to the distutils2 documentation, especially +<a class="reference external" 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 class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> source code .</p> +</div> +<div class="section" id="installation-uninstallation-scripts"> +<h3>Installation / Uninstallation scripts</h3> +<p>Next step was to think about an installation script, and an +uninstaller. I've not done the uninstaller part, and it's a smart +part, as it's basically removing some files from the system, so +I'll probably do it in a near future.</p> +<p><a class="reference external" 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 +METADATA (1.2) (See, the PEP 345), but I'm working on a +compatibility layer for the old metadata, and for the informations +provided via PIP requires.txt, for instance.</p> +</div> +<div class="section" id="extra-work"> +<h3>Extra work</h3> +<p>Also, I've done some extra work. this includes:</p> +<ul class="simple"> +<li>working on the PEP 345, and having some discussion about it +(about the names of some fields).</li> +<li>writing a PyPI server mock, useful for tests. you can find more +information about it on the +<a class="reference external" href="http://distutils.notmyidea.org">documentation</a>.</li> +</ul> +</div> +</div> +<div class="section" id="futures-plans"> +<h2>Futures plans</h2> +<p>As I said, I've enjoyed working on distutils2, and the people I'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 usable.</p> +<p>I'm not plainly satisfied by the work I've done, so I'll probably +tweak it a bit: the installer part is not yet completely finished, +and I want to add support for a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +index in the future.</p> +<p>We'll talk again of this in the next months, probably, but we +definitely need a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +API for <a class="reference external" href="http://pypi.python.org">PyPI</a>, as the &quot;simple&quot; index +<em>is</em> an ugly hack, in my opinion. I'll work on a serious +proposition about this, maybe involving +<a class="reference external" href="http://couchdb.org">CouchDB</a>, as it seems to be a good option +for what we want here.</p> +</div> +<div class="section" id="issues"> +<h2>Issues</h2> +<p>I've encountered some issues during this summer. The main one is +that'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 emails.</p> +<p>I've finally managed to work in an office, so good point for +home/office separation.</p> +<p>I'd not planned there will be so a high number of emails to read, +in order to follow what'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 !).</p> +</div> +<div class="section" id="thanks"> +<h2>Thanks !</h2> +<p>A big thanks to <a class="reference external" href="http://www.graine-libre.fr/">Graine Libre</a> and +<a class="reference external" 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're a student, if you're +interested about FOSS, dont hesitate any second, it's a really good +opportunity to work on interesting projects!</p> +</div> +Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html<p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my …</p><p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my weekly +summaries in +<a class="reference external" href="http://wiki.notmyidea.org/distutils2_schedule">a dedicated wiki page</a>.</p> +<div class="section" id="general-feelings"> +<h2>General feelings</h2> +<p>First, and it's a really important point, the GSoC is going very +well, for me as for other students, at least from my perspective. +It's a pleasure to work with such enthusiast people, as this make +the global atmosphere very pleasant to live.</p> +<p>First of all, I've spent time to read the existing codebase, and to +understand what we're going to do, and what's the rationale to do +so.</p> +<p>It's really clear for me now: what we'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 PEP about packaging.</p> +<p>With distutils2, it will be simpler to make &quot;things&quot; 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 so.</p> +</div> +<div class="section" id="tasks"> +<h2>Tasks</h2> +<p>My main task while working on distutils2 is to provide an +installation and an un-installation command, as described in PEP +376. For this, I first need to get informations about the existing +distributions (what's their version, name, metadata, dependencies, +etc.)</p> +<p>The main index, you probably know and use, is PyPI. You can access +it at <a class="reference external" href="http://pypi.python.org">http://pypi.python.org</a>.</p> +</div> +<div class="section" id="pypi-index-crawling"> +<h2>PyPI index crawling</h2> +<p>There is two ways to get these informations from PyPI: using the +simple API, or via xml-rpc calls.</p> +<p>A goal was to use the version specifiers defined +in`PEP 345 &lt;<a class="reference external" href="http://www.python.org/dev/peps/pep-0345/">http://www.python.org/dev/peps/pep-0345/</a>&gt;`_ and to +provides a way to sort the grabbed distributions depending our +needs, to pick the version we want/need.</p> +<div class="section" id="using-the-simple-api"> +<h3>Using the simple API</h3> +<p>The simple API is composed of HTML pages you can access at +<a class="reference external" 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's why I've preferred to pick up +the good ideas, and some implementation details, plus re-thinking +the global architecture.</p> +<p>The rules are simple: each project have a dedicated page, which +allows us to get informations about:</p> +<ul class="simple"> +<li>the distribution download locations (for some versions)</li> +<li>homepage links</li> +<li>some other useful informations, as the bugtracker address, for +instance.</li> +</ul> +<p>If you want to find all the distributions of the &quot;EggsAndSpam&quot; +project, you could do the following (do not take so attention to +the names here, as the API will probably change a bit):</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>We also could use version specifiers:</p> +<div class="highlight"><pre><span></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 (&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> +</pre></div> +<p>Internally, what's done here is the following:</p> +<ul class="simple"> +<li>it process the +<a class="reference external" href="http://pypi.python.org/simple/FooBar/">http://pypi.python.org/simple/FooBar/</a> +page, searching for download URLs.</li> +<li>for each found distribution download URL, it creates an object, +containing informations about the project name, the version and the +URL where the archive 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 &quot;final&quot; distribution (rather +than beta, alpha etc. ones)</li> +</ul> +<p>So, nothing hard or difficult 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're curious, please browse the +<a class="reference external" href="http://distutils2.notmyidea.org/">distutils2 documentation</a>.</p> +</div> +<div class="section" id="using-xml-rpc"> +<h3>Using xml-rpc</h3> +<p>We also can make some xmlrpc calls to retreive informations from +PyPI. It's a really more reliable way to get informations from from +the index (as it's just the index that provides the informations), +but cost processes on the PyPI distant server.</p> +<p>For now, this way of querying the xmlrpc client is not available on +Distutils2, as I'm working on it. The main pieces are already +present (I'll reuse some work I've made from the SimpleIndex +querying, and +<a class="reference external" 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's on what I'm actually working on.</p> +</div> +</div> +<div class="section" id="processes"> +<h2>Processes</h2> +<p>For now, I'm trying to follow the &quot;documentation, then test, then +code&quot; path, and that seems to be really needed while working with a +community. Code is hard to read/understand, compared to +documentation, and it's easier to change.</p> +<p>While writing the simple index crawling work, I must have done this +to avoid some changes on the API, and some loss of time.</p> +<p>Also, I've set up +<a class="reference external" 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 +...)</p> +</div> +Sprinting on distutils2 in Tours2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/sprinting-on-distutils2-in-tours.html<p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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 …</p><p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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'd really enjoyed this +time, because Éric knows a lot of things about mercurial and python +good practices, and I'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 had.</p> +<div class="section" id="documentation"> +<h2>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'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 those:</p> +<ul class="simple"> +<li><strong>Packagers</strong> who want to distribute their softwares.</li> +<li><strong>End users</strong> who need to understand how to use end user +commands, like the installer/uninstaller</li> +<li><strong>packaging coders</strong> who <em>use</em> distutils2, as a base for +building a package 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 API +description ? etc. That's maybe seems to be not so important, but I +guess the readers would appreciate to have the same structure all +along distutils2 documentation.</p> +</div> +<div class="section" id="mercurial"> +<h2>Mercurial</h2> +<p>I'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'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've not used them so far, so consider this as +a personal note.</p> +<ul class="simple"> +<li>hg histedit, to edit the history</li> +<li>hg crecord, to select the changes to 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 class="reference external" 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 ... Great. I'm a powerful merger now !</p> +</div> +<div class="section" id="on-using-tools"> +<h2>On using 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've +discovered vimdiff and hgtk, which will completely change the way I +navigate into the mercurial history. We aren't &quot;power users&quot;, so we +have learned from each other about vim tips. You can find +<a class="reference external" href="http://github.com/ametaireau/dotfiles">my dotfiles on github</a>, +if it could help. They're not perfect, and not intended to be, +because changing all the time, as I learn. Don't hesitate to have a +look, and to propose enhancements if you have !</p> +</div> +<div class="section" id="on-being-pythonic"> +<h2>On being 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 class="reference external" 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 do.</p> +</div> +<div class="section" id="conclusion"> +<h2>Conclusion</h2> +<p>It was really great. Next time, we'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'll probably do +another sprint in a few weeks, stay tuned !</p> +</div> +Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html<p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 …</p><p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 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 class="reference external" href="http://docutils.sourceforge.net/rst.html">restructured text</a>, so +I've wrote a simple file containing our different bullet points. In +fact, there is quite nothing to do then, to have a working +presentation.</p> +<p>So far, I've used +<a class="reference external" href="http://code.google.com/p/rst2pdf/">the rst2pdf program</a>, and a +simple template, to generate output. It's probably simple to have +similar results using latex + beamer, I'll try this next time, but +as I'm not familiar with latex syntax, restructured text was a +great option.</p> +<p>Here are +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.pdf">the final PDF output</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.rst">Rhe ReST source</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/slides.style">the theme used</a>, +and the command line to generate the PDF:</p> +<pre class="literal-block"> +rst2pdf couchdb.rst -b1 -s ../slides.style +</pre> +first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html<p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I've not worked as much as I +wanted, and this will continues until the end of …</p><p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I'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 class="reference external" 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 class="reference external" href="http://pypi.python.org/">PyPI</a>), and there is at +least two ways to retreive informations from here: XML-RPC and the +&quot;simple&quot; API.</p> +<p>So, I've been working on porting some +<a class="reference external" href="http://bitbucket.org/tarek/distribute/">Distribute</a> related +stuff to <a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a>, cutting +off all non distutils' things, as we do not want to depend from +Distribute's internals. My main work has been about reading the +whole code, writing tests about this and making those tests +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've taken some time to improve the work +<a class="reference external" href="http://bitbucket.org/konrad">Konrad</a> makes about this mock.</p> +<div class="section" id="a-pypi-server-mock"> +<h2>A PyPI Server 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 class="reference external" href="http://wsgi.org">WSGI</a> and +<a class="reference external" 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 class="reference external" 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 +Distutils2).</p> +<p>So, we switched to +<a class="reference external" href="http://docs.python.org/library/basehttpserver.html">BaseHTTPServer</a> +and +<a class="reference external" href="http://docs.python.org/library/simplehttpserver.html">SimpleHTTPServer</a>, +and updated our tests accordingly. It's been an opportunity to +realize that <a class="reference external" href="http://wsgi.org">WSGI</a> has been a great step +forward for making HTTP servers, and expose a really simplest way +to discuss with HTTP !</p> +<p>You can find +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/changesets">the modifications I made</a>, +and the +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/src/tip/docs/source/test_framework.rst">related docs</a> +about this on +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket distutils2 clone</a>.</p> +</div> +<div class="section" id="the-pypi-simple-api"> +<h2>The PyPI Simple API</h2> +<p>So, back to the main problematic: make a python library to access +and request information stored on PyPI, via the simple API. As I +said, I've just grabbed the work made from +<a class="reference external" 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 tests.</p> +</div> +<div class="section" id="the-work-to-come"> +<h2>The work to come</h2> +<p>So, once all use cases covered with tests, I'll rewrite a bit the +grabbed code, and do some software design work (to not expose all +things as privates methods, have a clear API, and other things like +this), then update the tests accordingly and write a documentation +to make this clear.</p> +<p>Next step is to a little client, as I've +<a class="reference external" href="http://github.com/ametaireau/pypiclient">already started here</a> +I'll take you updated !</p> +</div> +A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html<p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python …</blockquote><p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python application (pip, setuptools, distribute, distutils, etc.) +so&nbsp;there is a huge effort to make in order to make all this +packaging stuff interoperable, as pointed out by +the&nbsp;<a class="reference external" href="http://www.python.org/dev/peps/pep-0376/">PEP 376</a>.</blockquote> +<p>In more details, I'm going to work on the Installer / Uninstaller +features of Distutils2, and on a PyPI XML-RPC client for distutils2. +Here are the already defined tasks:</p> +<ul class="simple"> +<li>Implement Distutils2 APIs described in PEP 376.</li> +<li>Add the uninstall command.</li> +<li>think about a basic installer / uninstaller script. (with deps) +-- similar to pip/easy_install</li> +<li>in a pypi subpackage;</li> +<li>Integrate a module similar to setuptools' package_index'</li> +<li>PyPI XML-RPC client for distutils 2: +<a class="reference external" href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> +</ul> +<p>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.</p> +Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y-fr.html<p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un …</p><p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un répis +d'une semaine, pour récupérer des folies organisatrices (c'est ça +qui fait du bien, ceci dit -- les folies, pas le repos), je me +retrouve de nouveau sur ces mêms réflexions, grâce aux journées +organisées par +<a class="reference external" href="http://www.fne.asso.fr/">France Nature Environnement</a>, qui +proposaient ce jeudi soir une projection de &quot;Le temps des grâces&quot;, +un documentaire sur l'agriculture.</p> +<p>Parce que depuis 60 ans, il est pratiqué le remembrement des +parcelles à gogo, parce que nos sols deviennent completement morts +à cause des tonnes d'intrants qu'on leur fait absorber, et parce +que les exploitations s'agrandissent sans en finir pour tenter de +réagir façe à un marché financier toujours plus insaisissable, mené +de très loin par la PAC, il fallait un film pour en parler. C'est +ce que fait &quot;le temps des grâçes&quot;, avec un bon sens et une facilité +à faire passer des messages, qu'on ne peut qu'applaudir.</p> +<p>Malheureusement il s'agissait de la dernière diffusion à +<a class="reference external" href="http://www.cinemas-utopia.org/toulouse/">L'Utopia de Toulouse</a>... +Si vous en avez l'occasion, sautez dessus et profitez le temps de +ces 2 heures, ou vous pourrez écouter à la fois des discours +d'agronomes, d'agriculteurs, de chercheurs et bien d'autres, qui +dressent un constat pas si brillant de notre agriculture. On n'est +pas sorti de l'auberge, enfin, c'est l'expression.</p> +<p>Je vous laisse avec le synopsis et une bande annonce.</p> +<blockquote> +Une enquête documentaire sur +le monde agricole français aujourd'hui à travers de nombreux récits +: agriculteurs, chercheurs, agronomes, écrivains... Un monde qui +parvient à résister aux bouleversements qui le frappent - +économiques, scientifiques, sociaux - et qui, bon gré mal gré, +continue d'entretenir les liens entre générations. Un monde au +centre d'interrogations majeures sur l'avenir.</blockquote> +<p>Ainsi qu'un commentaire que je ne peux m'empécher de relayer, +trouvé sur allocine.fr (oui, vous savez, ce site rempli de pubs).</p> +<blockquote> +Le temps des grâces c'est je pense le plus grand film traitant de +l'écologie en tant que documentaire ou en sujet principal, on y +apprend une multitude de choses, on en ressort en colère contre le +système, le film propose différents points de vues, ici on a pas de +voix off moralisatrice à deux balles avec des gros titres bien +surlignés pour que même les beaufs matant TF1 puissent comprendre, +ici même si ça reste accessible au citoyen lambda, le film ne fait +pas de compromis avec le monde agroalimentaire, il ose dénoncer les +filière d'agronomie qui apprennent pas les bonnes choses à leurs +étudiants, aux lobbys de cette agro-industrie qui n'en fait qu'à sa +tête pour amasser de l'argent, cette tendance à tout uniformiser et +détruire… Franchement j'ai trouvé ça génial de bout en bout, +captivant, on explore cette campagne française, on comprend les +dilemmes des paysants. Le film n'étant pas opposé à la modernité, +ni même réactionnaire, il propose juste un constat alarmant du +monde agricole français, tout en proposant des alternatives qui +pourraient être utilisée, si les pouvoirs publics lâchaient un peu +la main des lobbys. Passionnant, vraiment.</blockquote> +<p>Courrez-y, je vous dis.</p> +Semaine de l’environnement: La consommation étudiante2010-02-24T00:00:00+01:002010-02-24T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-02-24:/semaine-de-lenvironnement-la-consommation-etudiante-fr.html<p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres …</p><p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres), et a tout un tas d'autres associations que je ne peux pas citer ici exhaustivement... Ce sont eux qui sont porteurs de messages alternatifs, et qui sont les initiateurs de débats publics, qui permettent de faire avancer des thématiques aussi importantes que le logiciel libre ou la protection de l'environnement.</p> +<p>Dans cette optique, depuis près de 3 ans (déjà !), au sein du +<a class="reference external" href="http://www.reseaugrappe.org">réseau GRAPPE</a>, on <em>essaye</em> +d'aborder des thématiques qui touchent de près ou de loin à +l'environnement, parce que c'est un sujet qui nous importe et nous +passionne. L'année dernière, c'était l'alimentation étudiante, ce +qui à abouti à la publication de +<a class="reference external" href="http://public.reseaugrappe.org/alimentation.pdf">la revue &quot;les étudiants se mettent à table&quot;</a>. +Cette année c'est la consommation étudiante qui est au programme.</p> +<div class="section" id="la-consommation-etudiante"> +<h2>La consommation étudiante ?</h2> +<p>L'idée principale de cette étude est de tenter de faire une analyse +de la &quot;société de consommation&quot;, souvent questionnée par les +étudiants et par d'autres, et de jeter un œil sur le rapport des +étudiants à cette société: Quoi et comment consomment-ils ? Les +universités et les écoles ne poussent-elles pas d’une certaine +manière les étudiants à la consommation ? Quelles sont les +alternatives face aux dérives de surconsommation ?</p> +<blockquote> +Analyse des pratiques, réflexions et mobilisations des étudiants en +termes de consommation seront réalisés pour comprendre leur modes +de vie, mais aussi leurs attentes, leurs propositions sur cette +thématique</blockquote> +</div> +<div class="section" id="la-semaine-de-l-environnement"> +<h2>La semaine de l'environnement !</h2> +<p>A travers l'ensemble des villes du réseau, +des projections de films et des débats auront donc lieu sur ce +thème, lors de la semaine de l'environnement 2010, qui se déroulera +d'ailleurs durant le mois de Mars +<a class="reference external" href="http://www.reseaugrappe.org/la-semaine-de-lenvironnement-programme/">partout en france</a>, +et <strong>du 6 au 14 Mars sur Toulouse</strong>. +<a class="reference external" href="http://docs.notmyidea.org/sde/prog-toulouse.pdf">Jetez un oeil au programme</a> +! Avec pour objectif de sonder un peu le ressenti des étudiants en +terme de consommation, nous avons mis en place +<a class="reference external" href="http://spreadsheets.google.com/viewform?formkey=dHV2bVllS2lWbzhyV3NBN3NUbi1TM2c6MA">un questionnaire en ligne</a>, +que vous pouvez compléter en une petite 10aine de minutes, +n'hésitez pas ! +<a class="reference external" href="http://www.reseaugrappe.org/consommation/">La page sur la consommation étudiante sur le site du GRAPPE</a></p> +</div> +Python ? go !2009-12-17T00:00:00+01:002009-12-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-12-17:/python-go-fr.html<p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à …</p><p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à l'esprit à propos de Python, sont &quot;logique&quot; et +&quot;simple&quot;. Et pourtant puissant pour autant. Je ne manque d'ailleurs +pas une occasion pour faire un peu d'<em>évangélisation</em> auprès des +quelques personnes qui veulent bien m'écouter.</p> +<div class="section" id="the-zen-of-python"> +<h2>The Zen of Python</h2> +<p>Avant toute autre chose, je pense utile de citer Tim Peters, et +<a class="reference external" href="http://www.python.org/dev/peps/pep-0020/">le PEP20</a>, qui +constituent une très bonne introduction au langage, qui prends la +forme d'un <em>easter egg</em> présent dans python</p> +<div class="highlight"><pre><span></span>&gt;&gt;&gt; import this +The Zen of Python, by Tim Peters + +Beautiful is better than ugly. +Explicit is better than implicit. +Simple is better than complex. +Complex is better than complicated. +Flat is better than nested. +Sparse is better than dense. +Readability counts. +Special cases 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 Dutch. +Now is better than never. +Although never is often better than *right* now. +If the implementation is hard to explain, 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="k">do</span> more of those! +</pre></div> +<p>J'ai la vague impression que c'est ce que j'ai toujours cherché à +faire en PHP, et particulièrement dans +<a class="reference external" href="http://www.spiral-project.org">le framework Spiral</a>, mais en +ajoutant ces concepts dans une sur-couche au langage. Ici, c'est +directement de <em>l'esprit</em> de python qu'il s'agit, ce qui signifie +que la plupart des bibliothèques python suivent ces concepts. Elle +est pas belle la vie ?</p> +</div> +<div class="section" id="comment-commencer-et-par-ou"> +<h2>Comment commencer, et par ou ?</h2> +<p>Pour ma part, j'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'est bien évidemment pas exhaustive et vos +commentaires sont les bienvenus) :</p> +<ul class="simple"> +<li><a class="reference external" href="http://diveintopython.adrahon.org/">Dive into python</a></li> +<li><a class="reference external" href="http://www.swaroopch.com/notes/Python_fr:Table_des_Matières">A byte of python</a></li> +<li><a class="reference external" href="http://www.amazon.fr/Python-Petit-guide-lusage-développeur/dp/2100508830">Python: petit guide à l'usage du développeur agile</a> +de <a class="reference external" href="http://tarekziade.wordpress.com/">Tarek Ziadé</a></li> +<li><a class="reference external" href="http://docs.python.org/index.html">La documentation officielle python</a>, +bien sûr !</li> +<li><a class="reference external" 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 :)</li> +</ul> +<p>J'essaye par ailleurs de partager au maximum les ressources que je +trouve de temps à autres, que ce soit +<a class="reference external" href="http://www.twitter.com/ametaireau">via twitter</a> ou +<a class="reference external" href="http://delicious.com/ametaireau">via mon compte delicious</a>. +Allez jeter un œil +<a class="reference external" href="http://delicious.com/ametaireau/python">au tag python</a> sur mon +profil, peut être que vous trouverez des choses intéressantes, qui +sait!</p> +</div> +<div class="section" id="un-python-sexy"> +<h2>Un python sexy</h2> +<p>Quelques fonctionnalités qui devraient vous mettre l'eau à la +bouche:</p> +<ul class="simple"> +<li><a class="reference external" 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 condition)</li> +<li>Assignation de valeurs multiples (il est possible de faire a,b,c += 1,2,3 par exemple)</li> +<li><a class="reference external" href="http://docs.python.org/tutorial/datastructures.html">Les listes</a> +sont simples à manipuler !</li> +<li>Les <a class="reference external" 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 simple.</li> +<li>Les +<a class="reference external" 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 exemples.</li> +<li>Les +<a class="reference external" 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 construisent</li> +<li>Python est +<a class="reference external" 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'est ce qui m'agaçait avec PHP qui est un langage à typage faible +dynamique.</li> +</ul> +<p>Cous pouvez également aller regarder +<a class="reference external" href="http://video.pycon.fr/videos/free/53/">l'atelier donné par Victor Stinner durant le Pyconfr 09</a>. +Have fun !</p> +</div> +AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e-fr.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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à …</p><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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à expliquer que justement, l'AMAP c'est +avant tout, pour nous, une notion de solidarité envers les +agriculteurs, malgré le fait que le message soit plus profond que +simplement aller acheter du bio (ça, c'est possible aussi en +supermarché), malgré le fait qu'il s'agisse en fait d'une remise en +cause plus profonde de la société, les journalistes n'ont choisi de +prendre que les quelques secondes qui leurs convenaient, celles qui +ne faisaient pas tache, celle ou je dis que &quot;l'AMAP permet aux +étudiants de réapprendre à cuisiner, plutôt que de manger des +nouilles et de se faire des plats réchauffés&quot;. Bien sur, je l'ai +dit et je le pense d'ailleurs, là n'est pas le problème, mais mon +message n'était pas celui là.</p> +<p>Jamais, dans les quelques minutes du reportage, on ne dit ce que +AMAP signifie: Association de <strong>Maintien</strong> d'une Agriculture +<strong>Paysanne</strong>. On ne parles même pas des agriculteurs ! C'est +simplement plus facile pour les étudiants de venir récupérer leurs +paniers, puisque les points de distribution sont sur les facs, et +en plus ça ne coute que 5 euros ! ...</p> +<p>Alors je crois bon de rappeler que L'AMAP n'est pas seulement un +service, c'est un engagement. Sur 5 mois, un engagement solidaire, +c'est la donnée principale de l'équation, celle sans quoi ça ne +peut fonctionner. Par le biais de cette AMAP, on essaye de montrer +que d'autres agricultures sont possibles, que la solidarité c'est +bien réel, et qu'il est possible de sortir du +<em>tout, tout de suite</em>.</p> +<p>Mais bon, apparemment, ça passe pas bien à la télé.</p> + \ No newline at end of file diff --git a/feeds/beer.atom.xml b/feeds/beer.atom.xml new file mode 100644 index 0000000..6244d90 --- /dev/null +++ b/feeds/beer.atom.xml @@ -0,0 +1,174 @@ + +Carnets Web - beerhttps://blog.notmyidea.org/2017-12-29T00:00:00+01:00NEIPA #32017-12-29T00:00:00+01:002017-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-29:/neipa-3.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<p>Test autour d'une New England Pale Ale; Cette fois ci avec du Mosaic et du Citra, durant une collab' avec Heiko.</p> +<h1>Objectifs:</h1> +<ul> +<li>Brasser une nouvelle NEIPA en appliquant les trouvailles des deux premières versions;</li> +<li>Hop stand de 40mn;</li> +<li>Contrôle du pH à 5.2;</li> +<li>Refroidissement dans l'évier;</li> +<li>Ajouter plus d'avoine;</li> +<li>Faire un mash out;</li> +<li>Augmenter un peu la quantité de grain.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1055 (atteint) +pH: 5.2 (5.4 mesuré)</p> +<h2>Grains:</h2> +<ul> +<li>75% de Pale Ale</li> +<li>12.5% de blé</li> +<li>12.5% flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Mosaic (Hop Stand 40mn)</li> +<li>2g/L Citra (Hop Stand 40mn)</li> +<li>4g/L Citra à cru (en deux fois)</li> +<li>4g/L Mosaic à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li> +<h2>Gypse: 1g</h2> +<dl> +<dd>1.8g (=4.05ml)</dd> +</dl> +</li> +<li>Acide lactique: 0.4ml</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>68°C durant 40mn;</li> +<li>75°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>GigaYeast «Vermont Ale». Le nombre de cellules n'est pas indiqué sur le packaging, ni en ligne.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>12h50: empâtage à 68°C</li> +<li>pH = 5.5. Ajout de 0.2 d'acide.</li> +<li>Pas mal de mesures du pH:<ul> +<li>5.2@23°C (13h05)</li> +<li>5.4@18°C (13h05)</li> +<li>5.2@27°C (13h15)</li> +<li>5.3@19°C (13h20)</li> +<li>5.4@25°C (13h30)</li> +</ul> +</li> +<li>13h33: Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: OK</li> +<li>14h11: 1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>31/12/2017 - Fermentation à 20°C</li> +<li>01/01/2018 - Ajout de 12g de Citra et 12g de Mosaic après deux jours.</li> +<li>10/01/2018 - 1.040 SG = 1.008 corrigé</li> +<li>15/01/2018 - Ajout de 12g de Citra et 12g de Mosaic</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>En mettant 1.5ml d'acide, si on mesure le pH de l'eau, il est à 3.5. Ça nous à pas mal effrayé, puisque on a pas trop l'habitude de monitorer le pH. On refait: 0.4ml d'acide = pH de 4.1. Au final, cela ne semble pas utile de mesurer le pH de l'eau avant de mettre son grain.</li> +<li>Je le savais déjà, mais travailler à deux en discutant n'est pas vraiment une bonne idée: sur les opérations un peu technique, un manque de concentration se fait tout de suite ressentir.</li> +<li>BeerSmith semble proposer un outil pour calculer les modifications de pH, je devrais l'utiliser la prochaine fois.</li> +<li>Baisser le ration d'empâtage: On s'est retrouvé avec beaucoup trop d'eau de rincage, alors qu'on était sur une bière assez faible en densité.</li> +<li>Au final, ajouter l'acide au départ est problématique pour le pH de l'eau qui baisse énormement. Après quelques recherches, il semble qu'il faille faire confiance au logiciel, et prendre une seule mesure de pH à 10mn (cela devrait être stable). Le pHmetre est aussi peut-être en cause.</li> +<li>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 ?</li> +</ul>NEIPA #22017-12-18T00:00:00+01:002017-12-18T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-12-18:/neipa-2.html<p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le …</li></ul><p><em>Voici quelques prises durant un de mes brassins. L'idée est de pouvoir les relire et m'améliorer au fur et à mesure.</em></p> +<h1>Objectifs:</h1> +<ul> +<li>Corriger les erreurs du précédent brassin.</li> +<li>Éviter les soucis de filtration</li> +<li>Mieux corriger le pH</li> +<li>Faire un whirlpool digne de ce nom / avoir moins de trub dans le fermenteur</li> +<li>Ne pas se laisser avoir par la baisse de température durant l'empâtage.</li> +</ul> +<h1>Recette:</h1> +<p>DI: 1060 (1050 mesuré) +pH: 5.2 (atteint)</p> +<h2>Grains:</h2> +<ul> +<li>90% Pils</li> +<li>10% Flocons d'avoine</li> +</ul> +<h2>Houblons:</h2> +<ul> +<li>2g/L Wakatu (au Whirlpool)</li> +<li>2g/L Motueka (au Whirlpool)</li> +<li>4.5g/L Wakatu à cru (en deux fois)</li> +<li>2.5g/L Motueka à cru (en deux fois)</li> +</ul> +<h2>Eau:</h2> +<ul> +<li>Utilisation d'eau de source, pour pouvoir corriger les sulfates / chlorures.</li> +<li>200 Chlorures pour 100 Sulfates.</li> +<li>Gypse: 0.9g</li> +<li>CaCl2: 3.4g</li> +<li>Acide lactique: Au batch précédent, j'avais mesuré 5.6, donc: ajout de +2ml d'acide (=2.4g).</li> +<li>Utilisation d'Irish Moss (2g) pour coaguler les protéines.</li> +</ul> +<h2>Profil d'empatage:</h2> +<ul> +<li>65°C durant 90mn (68°C au départ, 65 visé)</li> +<li>78°C durant 10mn (mash-out)</li> +</ul> +<h2>Levure</h2> +<ul> +<li>London Ale III.</li> +</ul> +<h1>Déroulé</h1> +<ul> +<li>18h36 - empatage à 65°C</li> +<li>19h16- pH = 5.2</li> +<li>Densité 1er moût: 1070</li> +<li>Ébullition importante pour atteindre 6,2L avec la bonne densité.</li> +<li>Mash-out à 78°C durant 10mn</li> +<li>Test à l'iode: NOK</li> +<li>1er rincage. Densité premier mout: 1070</li> +<li>15h40: Hop Stand (15g Citra / 15g Mosaic)</li> +</ul> +<h1>Fermentation</h1> +<ul> +<li>18/12/2017 - Fermentation à 18°C</li> +<li>21/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Ajout de 13.5g de Wakatu et 7.5g de Motueka</li> +<li>30/12/2017 - Passage à 10°C.</li> +<li>15/01/2018 - Cold Crash</li> +<li>21/01/2018 - Mise en bouteille. Resucrage à 7g/L.</li> +</ul> +<h1>Observations:</h1> +<ul> +<li>Je change de technique, et mets l'acide lactique directement dans l'eau.</li> +<li>Je concasse moins fin mais reteste quand même l'avoine. Aucun souci de filtration (mais l'avoine n'est pas concassé).</li> +<li>1g de CaCl2 ~= 2.25ml en solution à 33%.</li> +<li>Les deux thermomètres n'affichent pas la même température. Super :(.</li> +<li>Au final, j’empâte dans une casserole pour pouvoir faire un mash-out.</li> +<li>Le pH oscille pas mal durant l'empâtage. J'ai mesuré des pH de 4.9 à certains moments, mais au final la dernière lecture est de 5.2, ce qui me semble bon.</li> +<li>Le système que j'utilise (refroidisseur en cuivre) pour refroidir mon moût n'est pas génial parce que ça mélange pas mal ce qu'on veut voir se déposer au fond de la cuve. Refroidir directement dans l'évier est vachement plus simple (c'est pratique de faire du 6L pour çà !)</li> +<li>Le teste à l'iode était positif: tout n'était pas converti. Mais à 90mn de mash, je ne crois pas pouvoir faire grand chose de plus.</li> +<li>Idée en vrac, à voir à la dégustation, mais ajouter un peu de cara pourrait être sympa.</li> +<li>L'irish moss à vraiment bien fonctionné. Je me demande si je ne devrais pas même laisser décanter un peu plus longtemps durant le whirlpool pour avoir un effet encore plus impressionnant.</li> +<li>Je trouve que l'efficacité de cette brasserie est vraiment pourrie.</li> +<li>Un peu d'eau est venue diluer le moût (DI = 1050 au lieu de 1060 souhaité)</li> +<li>Au goût, le moût à vraiment un goût qui m'assèche la gorge. Trop de modifications de l'eau ? A voir si l'effet persiste après fermentation.</li> +<li>A priori, d'après un article de Scott Janish, empâter avec de l'avoine cru ne fonctionne que si on empate haut. Ca à un impact sur l'efficacité générale (2h pour conversion totale, c'est peut-être pour ça que mon teste à l'iode était positif)</li> +<li>Sur l'avoine toujours, il faut <strong>dépasser 18%</strong> pour avoir un côté moelleux. Certains mettent jusqu'à 40% !</li> +</ul> \ No newline at end of file diff --git a/feeds/biere.atom.xml b/feeds/biere.atom.xml new file mode 100644 index 0000000..aa0f321 --- /dev/null +++ b/feeds/biere.atom.xml @@ -0,0 +1,49 @@ + +Carnets Web - bierehttps://blog.notmyidea.org/2017-11-06T00:00:00+01:00Un club des brasseurs amateurs Rennais2017-11-06T00:00:00+01:002017-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2017-11-06:/un-club-des-brasseurs-amateurs-rennais.html<p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante …</p><p>En Mars dernier, suite à quelques discussions entre brasseurs amateurs, on à décidé de monter <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">une liste de diffusion</a> pour faciliter les échanges autour du brassage amateur sur Rennes et ses alentours.</p> +<p>Un peu plus tard, <a href="https://www.facebook.com/groups/899071153568179/">un groupe Facebook</a> est venu s'ajouter, et c'est vrai qu'on sent une dynamique naissante autour de la brasserie artisanale dans le coin.</p> +<p>En six mois, on est maintenant une grosse trentaine de personnes à être inscrits sur les listes et à se retrouver de temps à autres.</p> +<p>On en profite pour s'échanger des bons plans, déguster nos créations, (essayer de) faire des commandes groupées de malt, et pour se rencontrer pour papoter entre passionnés.</p> +<p>On a pas mal d'idées de trucs sympa a faire, entre autres:</p> +<ul> +<li>brasser une fois en gros puis se séparer le batch en plein de petits fermenteurs pour essayer différentes levures, différents houblons en <em>dry hop</em>, etc.</li> +<li>A la dernière rencontre, on s'est mis d'accord sur un style de bière pour se lancer un petit défi: tous brasser <a href="https://blog.notmyidea.org/larrivee-du-trouble-ou-comment-faire-des-neipa.html">une NEIPA</a> pour ensuite comparer nos résultats.</li> +</ul> +<p>Bref, c'est plutôt chouette ! Je me suis rendu compte qu'on avait quasiment aucune existence en dehors des réseaux sociaux, alors je me permet de publier ce petit bout d'article avec quelques liens…</p> +<p>Si tu es dans le coin et que tu souhaite nous rencontrer, n'hésite pas à rejoindre <a href="https://www.facebook.com/groups/899071153568179/">notre groupe de discussion Facebook</a> et notre <a href="https://framalistes.org/sympa/subscribe/brassam-rennes">liste de diffusion mail</a>.</p> +<p>A bientôt ;)</p>L'arrivée du trouble (ou comment faire des NEIPA ?)2017-10-17T00:00:00+02:002017-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-10-17:/larrivee-du-trouble-ou-comment-faire-des-neipa.html<p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir …</p><p><strong>Ceci est une traduction d'un article paru dans le magazine « Brew Your Own » en Octobre 2016, écrit par Dave Green</strong></p> +<p>C'est la saison des élections aux états unis et la bataille entre les partis politiques semble être plus controversée que d'habitude. Coincidemment, les buveurs de bières « Craft» US semblent avoir leur propre bataille qui divise au moins autant: une IPA peut elle être aussi trouble qu'une hefeweizen ? En provenance du coin Nord Est des  États-Unis, l'IPA trouble est en passe de devenir culte depuis quelques années. Mais la mode ne vient pas sans contrecoup. En fait, tout le monde y va de son opinion chez les brasseurs artisanaux. Pour ceux qui apprécient ce type d'IPA, l'apparence trouble signifie que les gorgées qui suivent seront extrèmenent riches en huiles de houblons; pour les autres, l'apparence est un affront à des principes ancestraux. Que vous les appeliez des rince-bouches, des soupes boueuses, brillantes ou horribles, ne vous faites pas de fausse idée: ces ales troubles sont là pour rester.</p> +<p>Pour commencer cette histoire, revenons un peu au début des années 1990. La scène brassicole artisanale était en train de vivre son premier boom et les nouvelles brasseries faisaient leur apparition dans tous les coins des États-Unis. Menée par Sierra Nevada Brewing Company, les American Pale Ale et les American IPA étaient en train d’émerger en tant que styles populaires parmi les amateurs de bière, pour leurs caractéristiques riches en houblon.</p> +<p>Le niveau d'amertume était un trait notoire, et avoir la bonne morsure d'amertume était essentiel pour une IPA. L'innovation a ensuite commencée à arriver sur la cote Ouest des États Unis à la fin des années 1990, et au début des années 2000, quand quelques doubles ou impériales IPA telles que Pliny the Elder de Russian River et Ruination IPA de Stone Brewing ont commencées à sortir des fermenteurs. Alors que celles ci contenaient énormement de « morsure du houblon», ce qui séparaient ces bières de beaucoup d'autres versions du style était le fait que le nez et la saveur du houblon semblaient éclater de la bière.</p> +<p>Du point de vue du brasseur, les huiles essentielles de ces houblons étaient bien plus présents que les acides alpha. En utilisant un profil de malt neutre et une souche de levure neutre, ces bières laissaient la part belle aux houblons. Ces brasseurs utilisaient aussi des houblons souvent critiqués, forts en acides alpha, tels que Columbus, Centennial, Simcoe et Chinook à la fin de l'ébullition ou en houblonnage à cru... et en grosses quantitées. Cela peut sembler comme une pratique courante pour une IPA actuellement, mais il y a à peine 15 ans, la plupart de la littérature évitaient d'utiliser ces variétés de houblon pour une utilisation autre que de l'amérisant. Lévolution d'une nouvelle American IPA était en train de prendre forme, sur la cote Ouest des étants unis, un style que les buveurs de bière ont nommé la « West Coast IPA».</p> +<h1>La phase de démarrage</h1> +<p>De retour sur la cote Est des États-Unis, dans un petit brewpub de Burlington à Vermont, deux brasseurs commencent innocemment à développer un type d'American IPA avec des objectifs similaires que les brasseurs de la côte Ouest, mais en utilisant une stratégie différente. Crée en 1988 par Greg Noonan et Steve Polewacyk, le « Vermont Pub &amp; Brewery » deviendra le berceau d'une nouvelle révolution autour des IPA.</p> +<p>Souvent citée comme étant les premiers brasseurs des Black IPA modernes ainsi que des New England IPA, offrant une variété de bières qui était extrèmement rare à cette époque, le « Vermont Pub &amp; Brewery » a des racines provenant de la connaissance du brassage et de la chimie de Greg Noonan, ainsi que son flair pour la créativité.</p> +<p>Se reposant sur la révolution de la bière mondiale (menée par Michael Jackson), Greg Noonan à exploré des styles de bières qui étaient en dehors des sentiers battus, même pour les brasseurs qui étaient déjà en avance sur leur temps.</p> +<p>Arrive John Kimmich, qui, en 1994 à déménagé dans le Vermont avec l'objectif de brasser sous la tutelle de Greg Noonan. John à travaillé un temps à Pittsburg (en Pennsylvanie) dans un <em>home brewshop</em> nommé Country Wines. Il a travaillé avec Alexis Hartung et sa grande bibliothèque sur le brassage maison et a eu son premier éclair de génie brassicole en lisant le livre de Greg Noonan « New Brewing Lager Beer ». Un an plus tard, il commence à travailler au « Vermont Pub &amp; Brewery ». En quelques mois, Greg commence à avoir confiance dans les capacités de son nouveau protégé. Avec chaque bière que John travaillait, le mentor était impressionné. Après douze mois, Greg donne la liberté à John d’expérimenter seul sur les recettes.</p> +<p>En 1997, John part du « Vermont Pub &amp; Brewery » et cofonde avec sa femme Jen un brewpub en 2003, le « Alchemist Pub &amp; Brewery », situé 30mn à l'est de Burlington à Waterbury dans le Vermont. A cette époque, Waterbury était un petit village dormant du New England, n'attirant pas grand monde autre que quelques touristes. Il était par contre assez bien situé, à un croisement des chemins, juste à la sortie d'une autoroute majeure, Waterbury est facilement accessible par à la fois les voyageurs en route pour les endroits touristiques et pour les locaux en allant / revenant du travail ou pour leurs excursions shopping. Grâce à ces quelques éléments, Waterbury s'est donc révélé êre un excellent spot pour Jen et John.</p> +<p>Une caractéristique unique des bières houblonnées de Kimmich était que lorsque servies fraîches et non filtrées, elles étaient souvent assez troubles. Il trouvait que filtrer ses bières pouvait introduire de l'oxygène non souhaité, enlevant de la bière beaucoup d'aspects intéressants. Il utilisait une souche nommée Conan (VPB1188), une levure que son mentor a développé et que maintenant beaucoup connaissent. Avec les dérivés Anglais, la souche de levure Conan, les bonnes connaissances en brassage de John, ainsi que son habitude à expérimenter avec les houblons, on se retrouve avec une combinaison gagnante pour une révolution du brassage sur la côte est.</p> +<h1>La phase de croissance</h1> +<p>En 2007, alors que j'allais au festival des brasseurs du Vermont, la queue pour accéder au stand de The Alchemist était d'au moins 20 minutes pour un verre. Certaines personnes remplissaient leurs verres et retournaient faire la queue pour avoir la chance de goûter une autre de ces bières tant acclamées, en particulier pour Heady Topper. Pour la première fois brassée en 2003, Heady Toper retenait alors l'attention, alors qu'elle n'était réellement qu'une parmi les nombreuses IPA acclamées de chez The Alchemist. Des histoires circulaient comme quoi certaines personnes amenaient leurs pintes aux toilettes pour remplir des bouteilles, les capsuler et les ramener chez eux, puisque le bar ne proposait pas de remplir de Growlers à l'époque, ni ne vendait de bouteilles. Je pensais alors que l'engouement pour ces IPAs avait atteint une sorte de paroxysme. Je n'avais pas encore compris que le feu était seulement en train de se construire.</p> +<p>J'ai récemment demandé à Shaun Hill, de la brasserie « Hill Farmsted » à Greensborrow Bend dans le Vermont, classée « meilleure brasserie du monde » 3 des 4 dernières années sur RateBeer.com, quel était sa relation avec John Kimmich à l'époque. Shaun brassait à l'époque 30mn plus loin, à Stowe, dans un brewpub appelé « The Shed».</p> +<p>« En 2005, je ne tarissais pas d'éolges pour les bières de John me faisait le plaisir de critiquer mes bières » me dit Hill, « Cette relation à évoluée avec le temps, plus specialement lorsque j'ai déménagé au Danemark et que cette conversation est devenue une conversation entre pairs, poussant l'autre dans de nouvelles directions.». Avec le decès de Greg Noonan en 2009, l'ancien protégé est devenu le nouveau mentor. Lors d'un échange avec Joel Mahaffey de Foundation brewing Co, à Portland à propos des IPAs influentes pour cette nouvelle révolution, il dit de The Alchemist « Quiconque réponds à cette question et oublie Heady Topper, ils sont à coté de la plaque. Il s'agit de la première IPA trouble, et à laissée une marque sur la communauté brassicole.»</p> +<p>Ce qui à emergé dans le coin nord-est des états unis est une explosion de nouvelles brasseries produisant des Pale Ale, des IPA et des double IPA basées sur la non filtration, l'explosion de saveurs, et un corps doux, un style que Greg Noonan et John Kimmich ont découvert, et qu'ensuite Shaun Hill à continué à affiner. John et Shaun ont séparemment pointé du doigt le fait qu'ils brassaient juste des bières à leur convenance, et qu'ils appréciaient le produit fini. Le terme « Juicy IPA » s'est retrouvé être un nom pour ces bières, et la texture est souvent aussi importante que le nez et le gout de houblons. Et comme les IPA de la côte Ouest se sont répendues en 2008, les bières troubles, non filtrées, les New England IPA se répendent en 2016.</p> +<h1>C'est parti !</h1> +<p>Il est maintenant temps de passer à la brasserie et de regarder comment faire pour brasser une IPA, New England style. Shaun Hill dit « soyez vous mêmeet faites une bière qui goute, sent et ressemble à ce que vous voulez qu'elle soit », JC Tetreault de Trillum à Boston dans le Massachussetts ajoute « la réponse courte… tout est important ! Vous devez vous concentrer sur chaque aspect pour arriver à la bière que vous souhaitez. » L'objectif est d'arriver à une bière douce, un peu ronde, presque tropicale, à la texture ressemblant presque à un jus de fruit, laissant une morsure subtile sur la langue en fin de bouche graçe au houblon.</p> +<h2>Les malts</h2> +<p>Tout comme les IPAs de la cote Ouest, les NEIPA sont relativement simples en malts. Le style évite les malts qui ajoutent des saveurs de pain et de crackers. Les malts cristals et autres malts au dessus de 20°L (ndt: 52 EBC) sont d'une manière générale évités. Ces bières peuvent bénéficier de certains ajouts de malts cristal clairs, mais gardez les à l’œil. Des flocons d'avoine, d'orge, de blé et autres peuvent être ajoutés pour contribuer au corps, mais ne pensez pas qu'ils soient une necessité. J'ai pu jouer avec des pourcentages de 15% de flocons dans mes recettes, et les résultats étaient presque excessifs. JC Tetreault dit que « à propos des ajouts de céréales non maltés et de flocons… nous ne les utilisons pas dans toutes nos bières basées sur le houblon. En fait, une proportion plutôt petite de nos bières basées sur le houblon en font usage». Les ajouts de sucre tels que les dextrose, saccharose et sucres crus augmentent la densité du moût pour s'assurer de la sécheresse dans les versions plus alcoolisées. Si vous choisissez d'ajouter du sucre cru, encore une fois, faites en sorte que l'ajout soit modeste; j'ai trouvé que certaines saveurs de mélasses avaient tendance à arriver à partir de 10% du total du grain. L'objectif est de garder les houblons comme caractéristique principale de la bière, tout en ayant une base de malt douce mais présente.</p> +<h2>Les levures</h2> +<p>Et c'est ici que les NEIPA dérivent des IPA de la cote Ouest. L'ajout des levures ainsi que le traitement à partir de la fermentation semble être la plus grosse différence entre les deux styles. D'abord, regardons comment ces bières sont fermentées. La plupart des NEIPA ne sont pas clarifiées dans le fermenteur avec des agents clarifiant tels que de la gélatine, du Biofine® ou du Polyclar™, et elles ne sont pas filtrées ou centrifugées plus tard pour clarifier la bière. La pensée derrière ce process est qu'enlever les levures de la bière à également pour effet d'enlever les huiles essentielles ainsi que d'autres nuances subtiles qui permettent à la bière d'avoir son caractère propre. Cela permet de garder un niveau d'huiles assez elevé dans le produit fini. Deuxièmement, les brasseurs de New England fermentent en utilisant une souche de levure d'origine anglaise. Ashton Lewis, l'éditeur technique de Brew Your Own précise « D'après des études ADN, la levure California Ale (White Labs WLP001, Wyeast 1056 et les autres souches de Chico) viendraient plutôt de Cologne, en Allemagne ». Ces souches américaines ont été choisies pour leur capacité à produire des bières claires, transparentes et amères sans ajouter de caractère. Les souches de levure utilisées par les brasseurs de New England IPA sont utilisées pour ajouter des esters, qui aident à produire le profil juteux de ces bières. Les IPAs brassées avec ces souches ne semblent pas être aussi transparentes que les souches Americaines lorsqu'elles sont exposées à des niveaux d'huiles elevés. Ceci vient en désaccord avec la plupart de la littérature sur les souches Anglaises. Si vous lisez la description de la plupart des souches de levures utilisées pour produire ces IPA troubles, la plupart sont considéeées « hautement floculantes », alors que la souche Chico, souvent utilisée pour les IPA de la cote Ouest annonce plutôt une floculation moyenne à faible. Pourquoi alors ces bières ne se clarifient pas lorsqu'elles sont sujettes à des hautes doses de houblon en fin d'ébullition ou en houblonnage à cru ? Cela reste encore une zone floue, j'ai donc demandé à quelques personnes dans l'industrie à propos de ce flou. Certains brasseurs pointent du doigt le fait que ces souches de levures floculent trop rapidement. Cela ne laisse pas le temps aux polyphénols de s'attacher aux levures, laissant ces composés ainsi que d'autres composés dérivés du houblon dans la solution plutôt que des les en enlever. Ashton Lewis nous rappelle aussi que le trouble trouvé dans les hefeweizen est principalement causé par les interactions entre les protéines et les polyphénols, et non pas par les levures.</p> +<p>Donc, quelles sont les souches de levure que vous devriez utiliser ? Le choix est en fait assez large, pour ceux qui souhaitent brasser ces types de American IPA, referez vous donc aux suggestions données dans les recettes jointes pour quelques idées.</p> +<h2>L'eau</h2> +<p>L'eau joue un rôle prépondérant dans le développement des New England IPA. Concentrez vous sur les niveaux de dureté de votre eau. Si vous avez une eau assez douce, alors vous avez un bon point de départ. Si vous avez une eau plutôt dure, obtenez un relevé d'eau (ndt: allez faire un tour sur le site « Eau du bassin Rennais » !). Si vous n'avez pas ces relevés d'eau, vous pouvez aussi faire analyser votre eau par des laboratoires, ou vous pouvez le faire vous même grâce à des kits de test de l'eau. Peu importe ce que vous choisissez, utiliser de l'eau distillée ou osmosée peut vous fournir une bonne base pour construire le profil d'eau que vous souhaitez obtenir. Essayez de garder votre niveau de bicarbonate en dessous de 50 PPM pour votre eau d’empâtage et votre eau de rinçage.</p> +<p>La prochaine chose sur laquelle se concentrer est vos sulfates et vos chlorures. Ceci est parfois controversé, mais encore une fois peut potentiellement être un facteur différenciant entre les IPA de la côte Est et les IPA de la côte Ouest. Quand j'ai commencé à jouer avec la composition de mon eau, j'ai traité l'eau de mes IPA pour atteindre un rapport 2:1 de sulfates / chlorures, ce qui s'est traduit par 100:50 PPM. J'ai produit plusieurs bières qui pouvaient rivaliser (selon moi) avec certaines que mes idoles produisaient. Mais, dans l'esprit du brassage amateur, j'ai continué à expérimenter. J'ai changé l'équilibre de sulfate / chlorures à 200:50PPM sans que je perçoive un changement. J'ai ensuite essayé 100:100 et trouvé que ça me plaisait un peu plus. Mes trouvailles ne sont pas la seule preuve anecdotique que booster le niveau de chlorures peut bénéficier à ce style de bières. Si vous cherchez à ajuster vos sulfates et for chlorures pour votre eau d'empâtage et de rincage, je vous encourage à jeter un oeil à l'article de Scott Janish du 7 Mars 2016 intitulé « Mouthfeel softness ». Scott y parle des effets négatifs d'un taux de sulfates elevé et des aspects positifs d'un niveau de chlorures elevé.</p> +<h2>Les houblons</h2> +<p>Généralement, l'amertume des houblons dans ce type d'IPA joue un rôle support, qui vient équilibrer le corps et la douceur des malts. Premièrement, gardez l'ajout de houblons amérisants modéré à faible. Vous pouvez expérimenter avec l'ajout de houblons amérisants mais je n'ai jamais eu l'occasion de trouver qu'une utilisation importante de houblons amérisants menait à une meilleure New-England IPA. Utilisez des houblons hauts en alpha tels que Magnum, Warrior™ ou Bravo si vous choisissez d'utiliser des houblons en cône ou en pellets, et je recommande de garder les ajouts d'amérisants assez faibles. D'habitude, j'essaye houblonner pour un rapport de 1:3 BU:GU (amertume sur densité). Cela signifie que quand je vise une densité cible de 1.066, l'ajout de houblons à 60mn est de 22 IBUs. Cela est fait pour éviter d'ajouter une dureté qui peut provenir d'une ébullition d'une quantité plus elevée de houblons. L'autre option est d'utiliser des extraits de houblon, qui peuvent contribuer les acides alpha nécessaires pour obtenir la bonne amertume, sans ajouter de polyphénols, que certains brasseurs pensent être à l'origine d'une certaine dureté.</p> +<p>Les ajouts de houblons en fin d'ébullition jouent un rôle beaucoup plus important pour la production de New-England IPA. Des apports copieux à la fin de l'ébullition ou au <em>flame-out</em> sont utiles pour tout type d'IPA hautement aromatique. Cela ajoutera des IBUs pour compléter votre apport en houblons amérisants et commencera à créer votre profil d'huiles. Je trouve que des variétés plus mordantes / piquantes comme le Simcoe®, Columbus, Chinook et Apollo fonctionnent bien à cette étape. Chaque brasseur semble trouver sa technique ici, qu'il s'agisse de faire plusieurs ajouts à 20mn ou moins puis de baisser à une température précise pour faire un <em>hop stand</em>, ou bien de simplement ajouter tous les houblons au <em>flame-out</em> et de les laisser durant 20 minutes ou plus. Il ne semble pas qu'il y ait de mauvaise manière de faire, juste plusieurs manières d'extraire les huiles essentielles des houblons à une température pas trop haute.</p> +<p>Le houblonnage à cru est votre prochain objectif. J'aimerais me concentrer sur les techniques plutôt que sur les quantités ou variétés puisque la technique semble être le plus important ici. Ceci dit, une chose est sure, ne soyez pas trop timide avec les ajouts durant le houblonnage à cru. 7.5g/L est certainement un bon point de départ. Vous pouvez ajuster en fonction de vos résultats. Les brasseurs Scott Janish et Michael Tonsmeir ajoutent que mettre ces bières en fûts à quelques avantages. Houblonner dans le fût, purger au CO2 et le fait de ne pas avoir de période prolongée de carbonatation sont déjà deux des avantages des fûts sur les bouteilles.</p> +<p>Alors, quand est le meilleur moment pour faire son houblonnage à cru ? Biern que ce ne soit pas une necessité, le fait de faire son houblonnage à cru en deux fois semble être un bon choix pour ce genre d'IPA. Prenez ce que vous pensiez ajouter lors du houblonnage à cru et séparez le en deux. Le premier ajout se fera durant la phase active de fermentation alors que le second se fera quand la fermentation se sera calmée et que les levures auront flocculées. Le premier ajout peut se faire à différents stades de la fermentation primaire; certains brasseurs les ajoutent au même moment qu'ils ensemencent, certains autres lorsque le krausen est haut, alors que la plupart l'ajoutent vers la fin de la fermentation. Je préfère faire le premier ajout une fois que le krausen est redescendu. Les hétérosides et les bio-transformations sont des éléments importants dans cette discussion à propos de comment la levure intéragit avec les huiles des houblons et les autres dérivés du houblon. Je trouve que les houblons ajoutés à la fin de l'ébullition vont apporter des caractéristiques similaires que les huiles de houblons ajoutés durant le ébut de la fermentation. Pour ce qui est du second ajout, l'objectif est d'attendre que la fermentation se soit calmée. Le timing n'est pas vraiment un facteur important ici, mais l'introduction d'oxygène est un point crutial. Prenez bien soin d'introduire le moins possible d'oxygène dans la bière à ce moment çi.</p> +<p>Dernièrement, quelque chose qui est nouveau pour moi: le houblonnage à cru sous pression. Cela vous demandera de l'équipement supplémentaire, principalement quelque chose apellée une « Spunding Valve». Il s'agit d'une valve qui permet de garder une certaine pression dans le fermenteur. Si la pression dépasse la valeur cible, alors la valve s'ouvre pour faire redescendre le fermenteur à la valeur souhaité. Mais, en quoi cela pourrait-être interéssant pour nous ? Parce que nous cherchons à garder un maximum de houblons aromatiques, en évitant d'en perdre. Les brasseurs amateurs ainsi que les brasseurs pros se sont penchés sur la question des spuinding valve de plus en plus dernièrement pour la fermentation primaire et pour le houblonnage à cru.</p> +<p>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.</p> +<p>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 !</p> \ No newline at end of file diff --git a/feeds/conferences.atom.xml b/feeds/conferences.atom.xml new file mode 100644 index 0000000..82767cb --- /dev/null +++ b/feeds/conferences.atom.xml @@ -0,0 +1,27 @@ + +Carnets Web - conferenceshttps://blog.notmyidea.org/2015-11-02T00:00:00+01:00Rencontres python francophones, 20152015-11-02T00:00:00+01:002015-11-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2015-11-02:/rencontres-python-francophones-2015.html<p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation …</p><p>J'ai pris quelques notes durant la conférence annuelle de PyconFR, qui avait +lieu à Pau cette année, et les ai publiées entre deux étapes des vacances qui +ont suivi. Je prends maintenant un peu plus de temps pour ranger toutes ces +notes au bon endroit.</p> +<p>C'était un excellent cru: l'organisation était vraiment impressionnante (merci +, si vous me lisez !). Et puis comme toujours l'occasion de recroiser quelques +copains, et d'en découvrir quelques autres... J'en ai profité pour parler de +Kinto (voici d'ailleurs <a class="reference external" href="http://alexis.notmyidea.org/kinto-pycon/">les slides de la présentation que j'ai faite</a>).</p> +<p>Parmis les conférences qui m'ont marquées, je vous conseille <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-hospital-des-tests-en-prod.html">celle de Benoit +Bryon, sur Hospital</a>, qui parle de +heartbeat, ou de comment tester vos projets en prod, et celle <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-geoalchemy.html">sur Geo Alchemy, +par Éric Lemoine</a>. Et bien sur, <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-cliquet.html">celle +de Mathieu Leplatre sur Cliquet</a>, le +toolkit qui rassemble les bonnes pratiques que nous souhaitons mettre en avant +chez Mozilla services, mais là, je suis tout sauf impartial !</p> +<p>Sinon, il peut être interessant de jeter un coup d'oeil au <a class="reference external" href="https://blog.notmyidea.org/pyconfr-2015-table-ronde-diversite.html">compte rendu de la +table ronde sur la diversité</a>, si c'est un sujet qui vous +touche. Encore beaucoup de choses à faire sur le sujet, bien sur, mais cette table ronde +était un pas nécessaire dans la bonne direction. Un groupe de travail sur le +sujet est en train de se constituer au sein de l'association.</p> +<p>L'ensemble des notes que j'ai pu prendre sont disponibles dans la section <a class="reference external" href="http://blog.notmyidea.org/category/pyconfr2015.html">PyconFR 2015</a>.</p> + \ No newline at end of file diff --git a/feeds/crypto.atom.xml b/feeds/crypto.atom.xml new file mode 100644 index 0000000..6ba8c32 --- /dev/null +++ b/feeds/crypto.atom.xml @@ -0,0 +1,809 @@ + +Carnets Web - cryptohttps://blog.notmyidea.org/2016-03-25T00:00:00+01:00Avez vous confiance en SSL?2016-03-25T00:00:00+01:002016-03-25T00:00:00+01:00Alexis Métaireautag: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'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop …</p><p>Dans le cadre <a href="http://autodefense-numerique.readthedocs.org/en/latest/">des ateliers d'autodéfense numérique</a>, +j'ai passé un peu de temps à creuser sur l'utilisation de SSL puisque +contrairement à ce que la plupart des personnes ont encore tendance à croire, +le petit cadenas (qui prouve qu'une connexion SSL est en cours) n'est +<strong>absolument</strong> pas suffisant.</p> +<p>Allez hop, c'est parti pour:</p> +<ul> +<li>un tour d'horizon du fonctionnement de SSl</li> +<li>quelques moyens contourner cette "protection" en faisant une attaque en pratique</li> +<li>un tour des solutions existantes actuellement et de pourquoi je ne les trouve + pas vraiment satisfaisantes.</li> +</ul> +<h2>Comment fonctionne SSL?</h2> +<p>Pour expliquer les problèmes de SSL, j'ai d'abord besoin d'expliquer comment +tout ça fonctionne.</p> +<p>SSL repose sur l'utilisation de certificats, qui sont générés par des autorités +de certification (<em>Certificate Authority</em> que je nomme <em>CA</em> dans la suite de +l'article).</p> +<p>Les certificats SSL permettent deux 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 même.</li> +<li>De garantir que le site sur lequel vous vous connectez est bien celui que + vous imaginez.</li> +</ul> +<p>Le navigateur, lors d'une visite d'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>CA</em> en qui il a confiance.</p> +<p>Imaginons maintenant qu'une des <em>CA</em> essaye de savoir ce qui s'échange entre +mon navigateur et le site de ma banque (protégé par SSL). Comment cela se +passerait il ?</p> +<p>N'importe quel <em>CA</em> peut donc générer des certificats pour n'importe quel site, +et le navigateur vérifierait, lui, que le certificat a bien été généré par une +<em>CA</em>.</p> +<p>Tout cela ne poserait pas de soucis si les <em>CA</em> étaient gérés de manière fiable, +mais il s'agit d'un travail compliqué, et certains <em>CA</em> ont par le passé montré +des faiblesses.</p> +<p>Par exemple, <a href="https://en.wikipedia.org/wiki/DigiNotar">DigiNotar</a> (un <em>CA</em> des Pays-Bas) +a été compromise et les attaquant.e.s ont pu générer des certificats SSL +frauduleux, ce qui leur a permis d'attaquer des sites tels que Facebook ou GMail.</p> +<p>Vous pouvez retrouver une liste des risques et menaces autour des <em>CA</em> <a href="http://wiki.cacert.org/Risk/History">sur le +wiki de CACert</a>.</p> +<h2>Attaque de l'homme du milieu avec SSL</h2> +<p>A force de dire que c'était très facile à faire, j'ai eu envie d'essayer +d'espionner des connections protégées par SSL, et effectivement c'est +carrément flippant tellement c'est simple.</p> +<p>En l'espace de quelques minutes, il est possible de faire une <em>attaque de +l'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'ensemble du trafic SSL, j'ai simplement eu à lancer quelques +commandes et avoir un <em>CA</em> dans lequel le navigateur de la victime a confiance. +Je l'ai ajouté dans le navigateur cible pour simuler que je l'avais déjà +(c'est le cas si un des 1200 CA se fait pirater, ce qui me semble une surface +d'attaque assez large).</p> +<p>Je les colle ici si ça vous intéresse:</p> +<div class="highlight"><pre><span></span>$ sudo aptitude install mitmproxy +$ mitm-proxy -T --host +</pre></div> + + +<p>Il faut faire croire à votre victime que vous êtes la passerelle vers +l'extérieur et à la passerelle que vous êtes la victime:</p> +<div class="highlight"><pre><span></span>arpspoof -i wlan0 -t victime gateway +arpspoof -i wlan0 -t gateway victime +</pre></div> + + +<p>Puis dire à notre fausse passerelle de rediriger le trafic des ports 80 et 443 +vers notre proxy:</p> +<div class="highlight"><pre><span></span>sudo sysctl -w net.ipv4.ip_forward<span class="o">=</span><span class="m">1</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">443</span> -j REDIRECT --to-port <span class="m">4443</span> +sudo iptables -t nat -A PREROUTING -i wlan0 -p tcp --dport <span class="m">80</span> -j REDIRECT --to-port <span class="m">4443</span> +</pre></div> + + +<p>Et paf, <strong>on voit tout ce qui passe entre la machine et le serveur SSL</strong>. On peut +d'ailleurs même imaginer faire tourner ces quelques commandes sur un +raspberry pi, pour aller encore plus vite…</p> +<h3>Key-pinning dans les navigateurs</h3> +<p>Actuellement, n'importe quel <em>CA</em> peut générer des certificats pour +n'importe quel site, et c'est en grande partie ce qui pose souci. Une des +manières de faire évoluer la situation est d'épingler les certificats de +certains sites directement dans les 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>HTTP Public Key Pinning (HPKP)</h3> +<p><a href="https://developer.mozilla.org/en/docs/Web/Security/Public_Key_Pinning"><em>HTTP Public Key Pinning</em></a> +est également une solution de <em>pinning</em> qui permet d'établir une confiance lors +de la première connexion avec le site. C'est ce qu'on appelle du <em>Trust on First +Use</em> ou <em>TOFU</em>.</p> +<p>Le navigateur va alors mettre ces informations dans un cache et vérifiera que +les certificats correspondent bien lors des prochaines visites.</p> +<p><em>HPKP</em> est disponible dans Firefox depuis Janvier 2015 et dans Chrome +depuis Octobre 2015.</p> +<h3>Certificate transparency: des journaux 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 SSL certificates open to scrutiny by +domain owners, CAs, and domain users.</p> +<p>-- <a href="https://www.certificate-transparency.org/what-is-ct">Certificate Transparency</a></p> +</blockquote> +<p>Autrement dit, avec ce système les <em>CA</em> doivent rendre public le fait qu'ils +aient signé de nouveaux certificats intermédiaires. La signature est ajoutée à +un journal sur lequel il n'est possible que d'écrire.</p> +<p>Les navigateurs vont alors vérifier que les certificats utilisés sont bien des +certificats qui ont été ajoutés au journal.</p> +<p>Ici, toute l'intelligence est dans la vérification de ces journaux, qui +permettent donc de valider/invalider des certificats racines ou intermédiaires.</p> +<p>Il me semble donc qu'il serait possible d'ajouter un certificat frauduleux le +temps d'une attaque (et celui ci serait détecté et supprimé ensuite).</p> +<p><em>Certificate-Transparency</em> n'est donc pas une solution contre une écoute +globale mise en place par les gouvernements par exemple.</p> +<p>Si vous lisez bien l'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 écrite.</p> +<h3>DANE + DNSSEC</h3> +<blockquote> +<p>The DANE working group has developed a framework for securely +retrieving keying information from the DNS [RFC6698]. This +framework allows secure storing and looking up server public key +information in the DNS. 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 service.</p> +<p>-- <a href="https://datatracker.ietf.org/wg/dane/charter/">Dane WG</a></p> +</blockquote> +<p>Une autre solution est appelée "DANE" et repose par dessus le protocole +<em>DNSSEC</em>.</p> +<p>Je connais assez mal <em>DNSSEC</em> donc j'ai passé un peu de temps à lire des +documents. L'impression finale que ça me laisse est que le problème est +exactement le même que pour SSL: 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 confiance.</p> +<blockquote> +<p>Secure DNS (DNSSEC) uses cryptographic digital signatures signed with a +trusted public key certificate to determine the authenticity of data. +-- https://en.wikipedia.org/wiki/DNS_spoofing</p> +</blockquote> +<p>Et aussi:</p> +<blockquote> +<p>It is widely believed[1] that securing the DNS is critically important for +securing the Internet as a whole, but deployment of DNSSEC specifically has +been hampered (As of 22 January 2010) by several difficulties:</p> +<ul> +<li>The need to design a backward-compatible standard that can scale to the + size of the Internet</li> +<li>Prevention of "zone enumeration" (see below) where desired</li> +<li>Deployment of DNSSEC implementations across a wide variety of DNS servers + and resolvers (clients)</li> +<li>Disagreement among implementers over who should own the top-level domain + root keys Overcoming the perceived complexity of DNSSEC and DNSSEC + deployment</li> +</ul> +</blockquote> +<h2>Solutions basées sur la blockchain</h2> +<p>Une dernière piste semble être l'utilisation de la <em>blockchain</em> pour distribuer +des clés par site.</p> +<p>La solution <em>DNSChain</em> me paraissait tout d'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'ont fait changer d'avis.</p> +<p>Reste encore la piste de <em>Namecoin Control</em> que je n'ai pas encore creusée. +Peut-être pour un prochain billet. Toute piste de réflexion est bien sur la +bienvenue sur ces sujets!</p>Retours sur un atelier ZeroNet2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag: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'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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 …</p><p>Mardi dernier se tenait <a href="http://biblio.insa-rennes.fr/crypto">une <em>cryptoparty</em></a> +dans les locaux de l'INSA de Rennes.</p> +<p>L'évènement s'étant rempli au delà de toutes les espérances, on m'a proposé de +venir y tenir un atelier, que j'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'éviter la censure.</p> +<p>Avant toute autre chose, merci énormément à l'équipe de la bibliothèque de +l'INSA pour l'organisation de cet évènement qui à une réelle portée politique.</p> +<h2>Un peu d'histoire</h2> +<p>Il me semble que Tim Bernes Lee (l'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 accéder.</p> +<p>Avec ce fonctionnement, impossible alors d'accéder à des sites si leur auteur +n'est pas en ligne. Qu'à cela ne tienne, on s'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'utilisateurs des sites.</p> +<h2>Un Web 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'une visite d'un +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 site.</li> +<li>Vous validez que les fichiers servis sont bien les bons (en vérifiant la + signature attachée).</li> +</ol> +<p>N'importe quel visiteur devient alors un <em>pair</em>, qui sert le site aux autres +visiteurs.</p> +<p>Parmi les nombreux avantages de cette approche, je note particulièrement que:</p> +<ul> +<li>Il est très difficile de censurer un site — Il est sur l'ensemble des machines + des visiteurs.</li> +<li>Les attaques par <em>fingerprinting</em> sont impossibles: le navigateur Web se + connecte à un serveur <em>proxy</em> local.</li> +<li>Vous détenez directement vos données et (par design) ne les donnez pas à des + silos (Facebook, Google, etc.)</li> +</ul> +<p>Si vous êtes interessés par une démonstration rapide, j'ai enregistré une vidéo +de 10 minutes où je parle en anglais avec une voix très grave.</p> +<video controls="" src="http://alexis.notmyidea.org/zeronet.webm" width=800></video> + +<h2>Atelier</h2> +<p>Pour l'atelier, j'ai choisi de faire une présentation rapide du projet (<a href="{filename}/static/zeronet-presentation-fr.pdf">j'ai +traduit les slides</a> anglais +pour l'occasion — <a href="https://docs.google.com/presentation/d/158C_-V1ueNaaKHMBMBgGOVhunb9xrXzB3hC_g1N53c0/edit?usp=sharing">accès aux sources</a>) +avant d'installer ZeroNet sur les machines et de l'utiliser pour publier un +site.</p> +<h3>Partager sur le réseau 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'avais pas prévu le coup.</p> +<p>Voici donc comment faire pour contourner le 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'est packagé pour debian pour l'instant</a>) + J'ai choisi d'installer <a href="http://erdgeist.org/arts/software/opentracker/#build-instructions">OpenTracker</a></li> +<li>Ensuite lancer ZeroNet avec des options spécifiques.</li> +</ol> +<div class="highlight"><pre><span></span>$ python zeronet.py --trackers udp://localhost:6969 --ip_external <span class="m">192</span>.168.43.207 +$ python zeronet.py --trackers udp://192.168.43.207:6969 --ip_external <span class="m">192</span>.168.43.172 +</pre></div> + + +<p>Il est nécessaire de spécifier l'adresse IP externe que chaque nœud expose pour +éviter qu'elle n'essaye d'aller la trouver par elle même: nous voulons l'adresse +du réseau local, et non pas l'adresse internet.</p> +<p>La prochaine fois je tenterais de venir avec un HotSpot Wifi et un tracker +BitTorrent dans la poche!</p> +<h2>Questions / Réponses</h2> +<p>Il y avait quelques questions intéressantes auxquelles je n'ai pas toujours su +répondre sur le moment. Après quelques recherches, je rajoute des détails ici.</p> +<h3>Torrent + Tor = brèche de sécu ?</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'utilisation de BitTorrent par dessus Tor</a>.</p> +<blockquote> +<p>Dans certains cas, certains clients torrents (uTorrent, BitSpirit, etc) +écrivent directement votre adresse IP dans l'information qui est envoyée +au tracker et/ou aux autres pairs. +— 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'est pas le cas de ZeroNet</a>, ce qui évacue le souci.</p> +<h3>ZeroMail, c'est lent non ?</h3> +<p>Une des applications de démo, <em>ZeroMail</em>, propose un mécanisme qui permet de +s'envoyer des messages chiffrés sur un réseau pair à pair. L'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 siens.</p> +<p>Cela permet de ne <strong>pas</strong> fuiter de méta-données, <a href="{filename}../crypto/2015.05.pgp-problemes.rst">à l'inverse de PGP</a>.</p> +<p>Je n'ai en fait pas de réponse claire à donner à cette question: l'auteur de +ZeroNet me disait que 10MB (la limite de taille d'un site, par défaut) +correspondait à beaucoup de place pour stocker des messages, et qu'il était +possible de supprimer les anciens messages une fois qu'ils sont lus par 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'un +utilisateur peut recevoir.</p> +<p>Je vois plusieurs problèmes avec le design actuel de ZeroMail (il me semble +assez facile d'y faire un déni de service par exemple). A creuser.</p> +<h3>Comment héberger des très gros sites ?</h3> +<p>Par exemple, comment faire pour héberger Wikipedia ?</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 demande)</p> +<h3>Est-ce qu'on à vraiment besoin d'un tracker ?</h3> +<p>Le support d'une DHT <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">est souhaité</a>, +mais pour l'instant pas encore implémenté. L'utilisation de la DHT BitTorrent +n'est pas une option puisque <a href="https://github.com/HelloZeroNet/ZeroNet/issues/57">Tor ne supporte pas UDP</a>.</p>Let's Encrypt + HAProxy2016-02-11T00:00:00+01:002016-02-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-02-11:/lets-encrypt-haproxy.html<blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début …</p><blockquote class="epigraph"> +<p>It’s time for the Web to take a big step forward in terms of security and +privacy. We want to see HTTPS become the default. Let’s Encrypt was built +to enable that by making it as easy as possible to get and manage +certificates.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://letsencrypt.org/">Let's Encrypt</a></p> +</blockquote> +<p>Depuis début Décembre, la nouvelle <em>autorité de certification</em> Let's Encrypt +est passée en version <em>Beta</em>. Les certificats SSL sont un moyen de 1. chiffrer la +communication entre votre navigateur et le serveur et 2. un moyen d'être sur +que le site Web auquel vous accédez est celui auquel vous pensez vous connecter +(pour éviter des <a class="reference external" href="https://fr.wikipedia.org/wiki/Attaque_de_l'homme_du_milieu">attaques de l'homme du milieu</a>).</p> +<p>Jusqu'à maintenant, il était nécessaire de payer une entreprise pour faire en +sorte d'avoir des certificats qui évitent d'avoir ce genre d'erreurs dans vos +navigateurs:</p> +<img alt="Message de firefox lorsque une connexion n'est pas sécurisée." src="{filename}/static/unsecure-connection.png" /> +<p>Maintenant, grâce à Let's Encrypt il est possible d'avoir des certificats SSL +<strong>gratuits</strong>, ce qui représente un grand pas en avant pour la sécurité de nos +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 SSL valides avec Let's Encrypt et +le répartiteur de charge <a class="reference external" href="http://www.haproxy.org/">HAProxy</a>.</p> +<p>Je me suis basé pour cet article sur d'<a class="reference external" href="https://blog.infomee.fr/p/letsencrypt-haproxy">autres</a> <a class="reference external" 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 d'information.</p> +<div class="section" id="validation-des-domaines-par-let-s-encrypt"> +<h2>Validation des domaines par Let's Encrypt</h2> +<p>Je vous passe les détails d'installation du client de Let's Encrypt, qui sont +<a class="reference external" 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 à:</p> +<pre class="literal-block"> +letsencrypt-auto certonly --renew-by-default +--webroot -w /home/www/letsencrypt-requests/ \ +-d hurl.kinto-storage.org \ +-d forums.kinto-storage.org +</pre> +<p>Le <em>webroot</em> est l'endroit ou les preuves de détention du domaine vont être +déposées.</p> +<p>Lorsque les serveurs de Let's Encrypt vont vouloir vérifier que vous êtes bien +à l'origine des demandes de certificats, ils vont envoyer une requête HTTP sur +<tt class="docutils literal"><span class="pre">http://domaine.org/.well-known/acme-challenge</span></tt>, ou il voudra trouver des +informations qu'il aura généré via la commande <tt class="docutils literal"><span class="pre">letsencrypt-auto</span></tt>.</p> +<p>J'ai choisi de faire une règle dans haproxy pour diriger toutes les requêtes +avec le chemin <tt class="docutils literal"><span class="pre">.well-known/acme-challenge</span></tt> vers un <em>backend</em> nginx qui sert +des fichiers statiques (ceux contenus dans +<tt class="docutils literal"><span class="pre">/home/www/letsencrypt-requests/</span></tt>).</p> +<p>Voici la section de la configuration de HAProxy (et <a class="reference external" href="https://github.com/almet/infra/blob/master/haproxy/haproxy.cfg#L63-L72">la configuration +complete</a> +si ça peut être utile):</p> +<pre class="literal-block"> +frontend http + bind 0.0.0.0:80 + mode http + default_backend nginx_server + + acl letsencrypt_check path_beg /.well-known/acme-challenge + use_backend letsencrypt_backend if letsencrypt_check + + redirect scheme https code 301 if !{ ssl_fc } !letsencrypt_check + +backend letsencrypt_backend + http-request set-header Host letsencrypt.requests + dispatch 127.0.0.1:8000 +</pre> +<p>Et celle de NGINX:</p> +<pre class="literal-block"> +server { + listen 8000; + server_name letsencrypt.requests; + root /home/www/letsencrypt-requests; +} +</pre> +</div> +<div class="section" id="installation-des-certificats-dans-haproxy"> +<h2>Installation des certificats dans HAProxy</h2> +<p>Vos certificats SSL devraient être générés dans <tt class="docutils literal">/etc/letsencrypt/live</tt>, mais +ils ne sont pas au format attendu par haproxy. Rien de grave, la commande +suivant convertit l'ensemble des certificats en une version compatible avec +HAProxy:</p> +<pre class="literal-block"> +cat /etc/letsencrypt/live/domaine.org/privkey.pem /etc/letsencrypt/live/domaine.org/fullchain.pem &gt; /etc/ssl/letsencrypt/domaine.org.pem +</pre> +<p>Et ensuite dans la configuration de haproxy, pour le (nouveau) <em>frontend</em> https:</p> +<pre class="literal-block"> +bind 0.0.0.0:443 ssl no-sslv3 crt /etc/ssl/letsencrypt +</pre> +<p>Faites bien attention à avoir un <em>frontend</em> <cite>https</cite> pour tous vos sites en HTTPS. +<a class="reference external" 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 !</p> +</div> +<div class="section" id="automatisation"> +<h2>Automatisation</h2> +<p>Pour automatiser un peu tout ça, j'ai choisi de faire ça comme suit:</p> +<ul class="simple"> +<li>Un fichier domaine dans <tt class="docutils literal">letsencrypt/domains/domain.org</tt> qui contient le script <tt class="docutils literal">letsencrypt</tt>.</li> +<li>Un fichier d'installation de certificats dans +<tt class="docutils literal"><span class="pre">letsencrypt/install-certs.sh</span></tt> qui s'occupe d'installer les certificats +déjà générés.</li> +</ul> +<p>Et voila ! <a class="reference external" href="https://github.com/almet/infra/">Le tout est dans un dépot github</a>, si jamais ça peut vous servir, tant mieux !</p> +</div> +Ateliers d'autodéfense numérique2016-01-14T00:00:00+01:002016-01-14T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-01-14:/ateliers-dautodefense-numerique.html<p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de …</li></ul></blockquote><p>Il y a huit mois, je me rendais compte de l'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'époque était l'animation +d'ateliers.</p> +<blockquote class="epigraph"> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, +envers mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins +pour rendre le déchiffrement des messages plus longue, &quot;noyer le +poisson&quot;.</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="http://blog.notmyidea.org/chiffrement.html">Chiffrement</a></p> +</blockquote> +<p>J'ai mis un peu de temps à mettre le pied à l'étrier, mais je ressors +finalement du premier atelier que j'ai co-animé avec geb, auprès d'un public de +journalistes.</p> +<p>Pour cette première édition l'idée était à la fois d'aller à la rencontre d'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'autodéfense numérique.</p> +<p>L'objectif pour ce premier atelier était de:</p> +<ol class="arabic simple"> +<li>Échanger autour des besoins et <strong>faire ressortir des histoires</strong> ou le manque +d'outillage / connaissances à posé problème, dans des situations concrètes;</li> +<li>Se rendre compte des &quot;conduites à risque&quot;, <strong>faire peur</strong> aux personnes formées +pour qu'elles se rendent compte de l'état actuel des 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 appréhender.</li> +</ol> +<div class="section" id="faire-ressortir-les-problemes"> +<h2>1. Faire ressortir les 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 &quot;Groupes d'Interview Mutuels&quot;, +ou &quot;GIM&quot;:</p> +<blockquote class="epigraph"> +<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é vécu.</p> +<p class="attribution">&mdash;«<a class="reference external" href="http://www.scoplepave.org/pour-s-ecouter">Pour s'écouter</a>», SCOP Le Pavé.</p> +</blockquote> +<p>De ces <em>GIMs</em> nous avons pu ressortir quelques histoires, gravitant autour de:</p> +<ul class="simple"> +<li><strong>La protection des sources (d'information)</strong>: Comment faire pour aider +quelqu'un à faire &quot;fuiter&quot; des données depuis l'intérieur d'une entreprise ?</li> +<li><strong>Le chiffrement de ses données</strong>: Comment éviter de faire &quot;fuiter&quot; des données +importantes lors d'une perquisition de matériel ?</li> +</ul> +</div> +<div class="section" id="faire-peur"> +<h2>2. Faire 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'accéder à certaines données. <a class="reference external" href="http://blog.barbayellow.com/">Grégoire</a> m'avait conseillé quelques petites accroches +qui ont ma foi bien marché:</p> +<p>J'ai demandé aux présent.e.s de:</p> +<ul class="simple"> +<li>donner leur mot de passe à voix haute devant les autres: a priori personne ne +le fera;</li> +<li>venir se connecter à leur compte email depuis mon ordinateur. J'ai piégé une +personne, qui est venu pour taper son mot de passe.</li> +</ul> +<p>Cela à été un bon moyen de parler de l'importance des traces que l'on peut +laisser sur un ordinateur, et de la confiance qu'il faut avoir dans le matériel +que l'on utilise, à fortiori si ce ne sont pas les vôtres.</p> +<p>Pour continuer à leur faire peur, après une brève explication de ce qu'est SSL +nous avons montré comment il était facile de scruter le réseau à la recherche +de mots de passe en clair.</p> +</div> +<div class="section" id="proposer-des-solutions-concretes"> +<h2>3. Proposer des solutions concrêtes</h2> +<p>Une fois que tout le monde avait pleinement pris sonscience des problématiques +et n'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 attentes:</p> +<ul class="simple"> +<li>On a expliqué ce qu'était <a class="reference external" href="https://tails.boum.org">Tails</a>, et comment +l'utiliser et le dupliquer.</li> +<li>On a pu faire un tour des outils existants sur Tails, notamment autour de +l'<em>anonymisation</em> de fichiers et la suppression effective de contenus.</li> +<li>Certaines personnes ont pu créer une clé tails avec la persistance de +configurée.</li> +<li>Nous nous sommes connectés au réseau <a class="reference external" href="https://www.torproject.org">Tor</a> et testé +que nos adresses IP changeaient bien à la demande.</li> +<li>Nous avons utilisé <a class="reference external" href="https://crypto.cat">CryptoCat</a> par dessus Tor, afin de +voir comment avoir une conversation confidentielle dans laquelle il est +possible d'échanger des fichiers.</li> +</ul> +</div> +<div class="section" id="retours"> +<h2>Retours</h2> +<p>D'une manière générale, pour une formation de trois heures et demi, je suis +assez content de l'exercice, et de l'ensemble des sujets que nous avons pu +couvrir. Il y a beaucoup de place pour l'amélioration, notamment en amont (j'avais +par exemple oublié d'amener avec moi suffisamment de clés USB pour utiliser +Tails).</p> +<p>La plupart des retours qu'on a pu avoir jusqu'à maintenant sont positifs, et il +y a l'envie d'aller plus loin sur l'ensemble de ces sujets.</p> +</div> +<div class="section" id="la-suite"> +<h2>La suite</h2> +<p>Il y a beaucoup de sujets que nous n'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'après-midi par +exemple).</p> +<p>J'ai choisi volontairement de ne pas aborder le chiffrement des messages via +PGP parce que <a class="reference external" href="https://blog.notmyidea.org/les-problemes-de-pgp.html">je pense que la protection que ce média propose n'est pas +suffisante</a>, mais je suis en train de +revenir sur ma décision: il pourrait être utile de présenter l'outil, à minima, +en insistant sur certaines de ses faiblesses.</p> +<p>Un compte twitter à été créé recemment autour des crypto-party à Rennes, si +vous êtes interessés, <a class="reference external" href="https://twitter.com/CryptoPartyRNS">allez jeter un coup d'œil</a>!</p> +<p>Je n'ai pas trouvé de ressources disponibles par rapport à des plans de +formation sur le sujet, j'ai donc décidé de publier les nôtres, afin de +co-construire avec d'autres des plans de formation.</p> +<p>Ils sont pour l'instant disponibles <a class="reference external" href="http://autodefense-numerique.readthedocs.org/en/latest/">sur Read The Docs</a>. Tous les retours +sont évidemment les bienvenus !</p> +</div> +Web distribution signing2015-10-12T00:00:00+02:002015-10-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-12:/web-distribution-signing.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'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 problem.</p> +</div> +<p>One <a class="reference external" 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't actually +trust the software authors but are rather trusting the software distributors +and certificate authorities (CAs).</p> +<p>I'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 come!</p> +<div class="section" id="the-problem-attack-vectors"> +<h2>The problem (Attack vectors)</h2> +<p>Let's try to describe a few potential 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 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 CDN +which delivers the files,</p> +<p>Trusted <em>Certificate Authorities</em> (&quot;governments&quot; or &quot;hacking team&quot;) can also +trick the User Agents (i.e. Firefox) into thinking they're talking to <em>Indie +Hoster</em> even though they're actually talking to a different 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 users.</p> +</div> +<div class="section" id="problem-mitigation"> +<h2>Problem Mitigation</h2> +<p>Part of the problem is solved by the recently introduced <a class="reference external" href="https://w3c.github.io/webappsec/specs/subresourceintegrity/">Sub Resource +Integrity</a> +(SRI). To quote them: &quot;[it] defines a mechanism by which user agents may verify +that a fetched resource has been delivered without unexpected manipulation.&quot;.</p> +<p>SRI is a good start, but isn't enough: it ensures the assets (JavaScript files, +mainly) loaded from a specific HTML page are the ones the author of the HTML +page intends. However, SRI doesn't allow the User Agent to ensure the HTML page +is the one he 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's not automated, but at least it's possible.</p> +<p>For web applications, we don't have such a mechanism, but it should be +possible. Consider the following:</p> +<ul class="simple"> +<li><em>App Authors</em> publish a new version of their software; They provide a hash of +each of their distributed files (including the HTML files);</li> +<li><em>Crypto Experts</em> audit these files and sign the hashes 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're signed by a trusted +party.</li> +</ul> +</div> +<div class="section" id="chosing-who-you-trust"> +<h2>Chosing who you trust</h2> +<p>In terms of user experience, handling certificates is hard, and that's where +the community matters. Distributions such as <a class="reference external" 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't verified.</p> +<p>But, as highligted earlier, CAs are hard to trust. A new instance of the same +CA system wouldn'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 of).</p> +<blockquote class="epigraph"> +<p>[...] 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 CA scandals. Both schemes can also be attacked if the +authority does not verify keys before vouching for them.</p> +<p class="attribution">&mdash;<a class="reference external" 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 reliable:</p> +<blockquote class="epigraph"> +<p>Melara et al proposed CONIKS, using a series of chained commitments to Merkle +prefix trees to build a key directory [...] for which individual users can +efficiently verify the consistency of their own entry in the directory +without relying on a third 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 self-auditing.</p> +<p class="attribution">&mdash;<a class="reference external" 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'm pretty sure +this design has many security problems attached to it.</p> +<p>However, that's a problem I would really like to see solved one day, so here +the start of the discussion, don't hesitate to <a class="reference external" href="/pages/about.html">get in touch</a>!</p> +</div> +<div class="section" id="addendum"> +<h2>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'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 this.</p> +<p>A bit like User-Agents do for SSL, but for the actual signature of the files +being viewed.</p> +</div> +Les problèmes de PGP2015-05-25T00:00:00+02:002015-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-25:/les-problemes-de-pgp.html<blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois …</p><blockquote class="epigraph"> +<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 middle?</p> +<p class="attribution">&mdash;<a class="reference external" href="http://secushare.org/PGP">http://secushare.org/PGP</a></p> +</blockquote> +<p>Une fois passé l'euphorie du &quot;il faut utiliser PGP pour l'ensemble de nos +communications&quot;, j'ai réalisé lors de discussions que PGP avait plusieurs +problèmes, parmi ceux-ci:</p> +<ul class="simple"> +<li>Les <em>meta données</em> (y compris le champ &quot;sujet&quot; de la conversation) sont quand +même échangées en clair (il est possible de savoir qu'un message à été échangé +entre telle et telle personne, a telle date);</li> +<li>PGP 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 chiffrée;</li> +<li>Il est facile de connaître votre réseau social avec PGP, puisque tout le +principe est de signer les clés des personnes dont vous validez l'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 PGP 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 &quot;sécurisée&quot; (HTTPS). Tout le monde peut donc voir ces échanges et +savoir de qui vous cherchez la 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 clés).</li> +</ul> +<p>Je suis en train de creuser à propos les alternatives à PGP, par exemple <a class="reference external" href="https://pond.imperialviolet.org/">Pond</a>, qui lui ne construit pas par dessus un +standard déjà établi, et donc n'hérite pas de ses défauts (mais pas non plus de +son réseau déjà établi).</p> +<p>En attendant, quelques bonnes pratiques sur PGP ;)</p> +<div class="section" id="bonnes-pratiques"> +<h2>Bonnes pratiques</h2> +<p>Il est en fait assez facile d'utiliser PGP de travers. Riseup à fait <a class="reference external" href="https://help.riseup.net/en/security/message-security/openpgp/best-practices">un +excellent guide</a> +qui explique comment configurer son installation correctement.</p> +<ul class="simple"> +<li>J'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 oubliez.</li> +<li>Générez des clés RSA de 4096 bits, en utilisant sha512;</li> +<li>Il faut utiliser une date d'expiration de nos clés suffisamment proche (2 +ans). Il est possible de repousser cette date si nécessaire, par la suite.</li> +</ul> +<p>Parmi les choses les plus frappantes que j'ai rencontrées:</p> +<ul class="simple"> +<li>Utiliser le <em>flag</em> <cite>–hidden-recipient</cite> avec PGP pour ne pas dévoiler qui est +le destinataire du message;</li> +<li>Ne pas envoyer les messages de brouillons sur votre serveur, ils le seraient +en clair !;</li> +<li>Utilisez HPKS pour communiquer avec les serveurs de clés, sinon tout le +trafic est en clair.</li> +</ul> +<p>Le <a class="reference external" href="https://bitmask.net/">projet Bitmask</a> vise lui à rendre les outils de +chiffrement d'échanges de messages et de VPN simples à utiliser, encore quelque +chose à regarder.</p> +<p>Enfin bref, y'a du taf.</p> +</div> +Simplifier les preuves d'identités2015-05-11T00:00:00+02:002015-05-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-11:/simplifier-les-preuves-didentites.html<p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la …</p><p>L'un des problèmes non réellement résolu actuellement quant au chiffrement des +échanges est lié à l'authenticité des clés. Si quelqu'un décide de publier une +clé en mon nom, et en utilisant mon adresse email, cela lui est assez facile.</p> +<p>Il est donc nécessaire d'avoir des moyens de prouver que la clé publique que +j'utilise est réellement la mienne.</p> +<p>Traditionnellement, il est nécessaire de faire signer ma clé publique par +d'autres personnes, via une rencontre en personne ou des échanges hors du +réseau. C'est par exemple ce qui est réalisé lors des <a class="reference external" href="https://fr.wikipedia.org/wiki/Key_signing_party">Key Signing parties</a>.</p> +<p>Une manière simple d'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 personne.</p> +<p>PGP propose un mécanisme de signature des clés d'autrui, une fois celles ci +validées, ce qui permet de placer sa confiance dans les signataires de la clé.</p> +<p><a class="reference external" 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'il est possible +d'utiliser différents moyens afin de prouver l'identité des personnes. Par +exemple, leurs comptes Twitter, GitHub ou leurs noms de domaines. De la même +manière qu'il est possible de signer (valider) les clés de nos amis, il est +possible de les &quot;tracker&quot; selon le jargon de keybase.</p> +<p>Donc, en somme, <em>Keybase.io</em> est un annuaire, qui tente de rendre plus facile la +création de preuves. Bien.</p> +<div class="section" id="quelques-points-d-ombre"> +<h2>Quelques points d'ombre</h2> +<p>Il s'agit d'une <em>startup</em> américaine, domiciliée dans le Delaware, qui se trouve être +un des paradis fiscaux qui <a class="reference external" 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 class="reference external" href="https://github.com/keybase/keybase-issues/issues/1569">j'ai ouvert un ticket +sur GitHub pour en savoir plus</a> (après tout, le fait +d'être un paradis fiscal permet peut-être d'échapper à certaines lois sur la +requêtes de données). D'autant plus étonnant, la startup n'a pour l'instant <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/788">pas +de *business model*</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 là).</p> +<p>Le service (bien qu'en Alpha), n'est pas mis à disposition sous licence libre, +ce qui pour l'instant empêche quiconque de créer son propre serveur Keybase. +<a class="reference external" href="https://github.com/keybase/">Une partie des composants, cependant, le sont (open source)</a>.</p> +<p>J'ai du mal à croire en des initiatives qui veulent sauver le monde, mais dans +leur coin, je ne comprends pas pourquoi il n'y à pas de documentation sur +comment monter son propre serveur, ou comment les aider à travailler sur la +fédération. Mais bon, c'est pour l'instant une initiative encore fraîche, et je +lui laisse le bénéfice du doute.</p> +<p>Sur le long terme, une infrastructure comme <em>Keybase.io</em>, devra évidemment être +<a class="reference external" href="https://github.com/keybase/keybase-issues/issues/162">distribuée</a>.</p> +<blockquote class="epigraph"> +<p>We'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'd be so happy to get this +right.</p> +<p class="attribution">&mdash;<a class="reference external" href="http://chris.beams.io/posts/keybase/">Chris Coyne, co-founder of Keybase</a></p> +</blockquote> +<p>Afin de se &quot;passer&quot; de leur service centralisé, les preuves générées (qui sont +la force du système qu'ils mettent en place) pourraient être exportées sur des +serveurs de clés existants. C'est quelque chose <a class="reference external" href="https://github.com/keybase/keybase-issues/issues/890">qu'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'on s'y attarde un brin.</p> +<p>Par ailleurs, <a class="reference external" href="https://leap.se/nicknym">d'autres projets qui visent des objectifs similaires</a> existent, via le projet LEAP, mais je n'ai pas +encore creusé.</p> +</div> +Phrases de passe et bonnes pratiques2015-05-09T00:00:00+02:002015-05-09T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-09:/phrases-de-passe-et-bonnes-pratiques.html<blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi …</p></blockquote><blockquote class="epigraph"> +<p>Au contraire des autres mots de passe, les mots de passe cryptographiques +ont specifiquement besoin d'être longs et extremement difficiles à deviner. +La raison est qu'un ordinateur (ou un cluster de plusieurs ordinateurs) +peut être programmé pour faire des trillions d'essais de manière +automatique. Si le mot de passe choisi est trop faible ou construit d'une +manière trop prédictible, cette attaque par la force pourrait se revéler +fructueuse en essayant toutes les possibilités.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://www.eff.org/wp/defending-privacy-us-border-guide-travelers-carrying-digital-devices">The Electronic Frontier Foundation</a> (traduction de mon fait)</p> +</blockquote> +<p>Comprendre les concepts et l'écosystème qui permettent d'avoir une vie +numérique chiffrée n'est pas quelque chose d'aisé. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Plusieurs</a> <a class="reference external" 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 existants.</p> +<blockquote class="epigraph"> +<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 système.</p> +<p class="attribution">&mdash;La page de manuel de GPG.</p> +</blockquote> +<p>Une phrase de passe devrait:</p> +<ul class="simple"> +<li>Être suffisamment longue pour être difficile à deviner;</li> +<li>Ne pas être une citation connue (littérature, livres sacrés etc);</li> +<li>Difficile à deviner même pour vos proches;</li> +<li>Facile à se souvenir et à taper;</li> +<li>être unique et non partagée entre différents sites / applications etc.</li> +</ul> +<p>Une des techniques consiste à utiliser des mots du dictionnaire, sélectionnés de +manière aléatoire, puis modifiés.</p> +<div class="figure"> +<img alt="XKCD sur la force des mots de passe." src="https://imgs.xkcd.com/comics/password_strength.png" /> +</div> +<p>Micah Lee <a class="reference external" 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 longues.</p> +<div class="figure"> +<img alt="Capture d'écran du logiciel de génération et de mémorisation des phrases de passe." src="{filename}/static/passphrases.png" /> +</div> +<p>Oui, ce n'est pas aussi simple que ce qu'il y parait. Pour ma part, j'ai une +copie en local de mes clés, dans un fichier chiffré avec une autre clé que j'ai +généré pour l'occasion et que je ne partagerait pas. J'ai par ailleurs +<a class="reference external" href="https://github.com/jamessan/vim-gnupg">configuré</a> mon éditeur de texte pour +pouvoir chiffrer les documents textes par défaut.</p> +<p>J'ai donc regénéré une nouvelle fois mes clés de travail et personnelles, en +utilisant des phrases de passe plus complexes.</p> +<p>Reste encore la question de la sauvegarde de ces clés privées de manière +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.</p> + \ No newline at end of file diff --git a/feeds/diy.atom.xml b/feeds/diy.atom.xml new file mode 100644 index 0000000..d7aa857 --- /dev/null +++ b/feeds/diy.atom.xml @@ -0,0 +1,121 @@ + +Carnets Web - diyhttps://blog.notmyidea.org/2012-12-28T00:00:00+01:00Tricot2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/tricot.html<p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu …</p><p>Puisque j'ai décidé d'apprendre à faire les trucs moi-même, je me mets au +tricot. Et puis y'a aussi tout un symbole derrière: le tricot, c'est pour les +filles, tu sais, un &quot;truc de gonzesse&quot;.</p> +<p>Eh bah c'est pas gagné, jte le dis. Pour l'instant j'ai réussi à faire à peu +près un rang d'endroit et j'arrive pas à enchainer sur l'envers pour réussir +à faire un point jersey (jersey c'est un rang endroit puis un rang envers).</p> +<p>Enfin bref, si jamais ça vous botte vous aussi, voila quelques ressources que +j'ai trouvé sur internet (en plus des conseils avisés de maman chérie™):</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.youtube.com/watch?v=VcGiBG2BNxo&amp;list=UUskaiVNnKf7amRb5OI5op_w">Montage des mailles &quot;normales&quot;</a></li> +<li><a class="reference external" href="http://www.youtube.com/watch?v=aIQtNN89pqA&amp;list=UUskaiVNnKf7amRb5OI5op_w">Le point jersey</a></li> +</ul> +<p>La nana explique plutôt bien et assez lentement. En espérant que ça prenne.</p> +Bière maison !2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/biere-maison-fr.html<p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si …</p><p>Et voilà, c'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'il nous reste encore bien du chemin à parcourir pour avoir +quelque chose qui nous convienne réellement… c'est pas si pire comme on dit !</p> +<p>Cette fois-çi, on s'est penché sur la confection d'une IPA (Indian Pale Ale, une +bière un peu plus amère que celle qu'on à l'habitude de trouver en France).</p> +<p>Elle est plus amère car elle comporte plus de houblon que les autres, et +(dans notre cas en tout cas) parce qu'on fait la première fermentation en +présence de houblon.</p> +<div class="section" id="comment-qu-on-fait-de-la-biere"> +<h2>Comment qu'on fait de la bière ?</h2> +<p>Machine arrière; n'allons pas trop vite: comment est-ce qu'on fait de la bière, +d'abord ?</p> +<p>En fin de compte, les quelques étapes nécessaire à la confection de la bière ne +sont pas bien sorcières; concassage de l'orge maltée, cuisson (libération de +l'amidon dans l'eau), infusion du houblon, refroidissement, première +fermentation, embouteillage et seconde fermentation.</p> +<p>L'idée principale est transformer l'amidon d'orge maltée en sucre, pour le +&quot;donner à manger&quot; à des levures. Vous ajoutez un peu de houblon au milieu pour +donner un petit goût amer et le tour est joué. Enfin presque.</p> +</div> +<div class="section" id="etape-par-etape"> +<h2>Étape par étape</h2> +<p>Première étape: <strong>le concassage</strong>. On avait 6kg d'orge maltée à concasser (plus +exactement 6kg de malt pâle <em>7EDC</em> et 500g de malt cara <em>50EDC</em>).</p> +<img alt="Image de concassage." src="images/concassage.jpg" style="width: 400px;" /> +<p>Attention, pas trop fin dis donc ! On ne veut pas de la poudre, on veut +simplement permettre à l'amidon de se dissoudre dans l'eau. Si on concasse le +malt trop fin, on se retrouve avec un dépôt dégeulasse au fond de toutes les +bouteilles (c'est l'expérience qui parle, notre première bière avait plus goût +de céréale que de bière…)</p> +<p>Contrairement aux fois précédentes où nous avions utilisé la technique du +marteau et du torchon (oui, comme vous pouvez l'imaginer, c'est assez long et +fastidieux), On a utilisé… un moulin à malt ! Qui nous à permis de concasser les +6kg en 30 minutes (heureusement qu'on était trois pour se relayer sur le +moulin, parce que nos petits muscles fatiguaient assez vite; vous pouvez +envisager de faire ça tout seul si vous êtes un tennisman).</p> +<img alt="C'est dur !" src="images/concasse.jpg" style="width: 700px;" /> +<p>La seconde étape, <strong>l'empatage</strong>. Il s'agit de faire chauffer notre orge maltée +à différentes températures. Les fois précédentes, on avait utilisé plusieurs +paliers de température, mais il semble que ça ne soit pas si nécessaire que ça, +selon les informations de l'ami Fred. On à donc tenté de faire chauffer notre +malt directement à 50°C. Une petite erreur sur la route, on à eu peur de la +contamination bactérienne et on à décidé de faire bouillir nos 26L d'eau pour +être sur que les bactéries s'enfuient en courant. Je dis erreur parce que ça +nous à pris pas loin de 3h30, inertie quand tu nous tiens!</p> +<p>On se rends compte de la taille de la marmite un peu là:</p> +<img alt="Une grosse marmite" src="images/marmite.jpg" style="width: 400px;" /> +<p>Une fois l'eau à température (54°C), il faut ajouter le malt et le laisser +durant 30mn à cette température, puis augmenter jusqu'à 65°C durant 1h.</p> +<p>La troisième étape, c'est <strong>le rinçage</strong>, l'idée est de récupérer l'amidon qui +s'est dissout dans l'eau et de mettre de côté l'orge maltée (la partie solide). +Pour ça, il faut faire chauffer de l'eau de rinçage. On a utilisé 10L d'eau de +rinçage qu'on a fait chauffer à 78°C, en comptant sur le fait qu'elle perdra de sa +température (20°C à peu près) en étant utilisée. On a filtré deux fois pour +être sûr de ne rien perdre.</p> +<img alt="Filtrage filtrage..." src="images/filtrage.jpg" style="width: 700px;" /> +<p>L'étape d'après (la quatrième, vous suivez), c'est <strong>le houblonnage</strong>. +On va faire infuser notre &quot;solution aqueuse&quot; (wouah, on dirait de la chimie !) +avec du houblon. Il faut porter l'eau à ébullition et laisser faire durant 1h.</p> +<p>Dernière étape: <strong>le refroidissement</strong>. On dirait que c'est tranquilou comme +ça, mais en fait ça ne l'est pas tant que ça: il faut réussir à passer notre +liquide qui était en ébullition à 54°C en un temps acceptable. Pour ça, on +a utilisé un serpentin confectionné main.</p> +<img alt="Notre refroidisseur fait main par Fred." src="images/refroidisseur.jpg" style="width: 400px;" /> +<p>Ça nous a permis de passer de 100°C à 54°C en… 35 minutes quand même ! (Nous avions essayé les fois précédentes +de gérer ça à coup de baignoire et de glaçons, les temps n'étaient absolument +pas au rendez-vous).</p> +<img alt="Décidement pas." src="images/refroidissement.jpg" style="width: 700px;" /> +<p>Je disais dernière étape, mais il ne faut pas oublier de rajouter les +levures, qui elles vont faire tout le travail et transformer tout ça en… alcool +! Dans notre cas, on ajoute aussi dans la cuve de fermentation du houblon +question de donner l'amertume dont on a envie.</p> +<p>On à mesuré une densité de 1046, ce qui veut dire 6° d'alcool. La cuve est +maintenant en train de buller tranquillement (les levures produisent du gaz qui +est évacué), et ça doit durer 15 jours approximativement.</p> +</div> +<div class="section" id="mise-en-bouteille"> +<h2>Mise en bouteille</h2> +<p>Une fois ces deux semaines passées, il faut mettre en bouteille. Dans notre cas +nous avons récupéré des bouteilles à bouchon mécanique (vous savez, les +bouteilles de limonades) qu'on à bien rincé et nettoyé.</p> +<p>On s'équipe d'un siphon (pensez à prendre un tuyau avec un diamètre assez +important, le notre était petit et c'était assez long) et après avoir ajouté du +sucre dans le mélange (pour réactiver les levures), on remplit les bouteilles +! Il s'agit de la seconde fermentation, celle qui va faire les bulles (la +première fermentation se charge de l'alcool, la seconde des bulles).</p> +<p>Et voilà ! Il ne reste plus qu'à mettre les bouteilles de coté durant deux +semaines de plus et… à déguster le moment venu.</p> +<p>On a donc pu tester notre bière la semaine dernière et, ma foi, elle est pas +mal du tout. Elle ne mousse pas trop et à un goût un peu amer. Malheureusement +pas assez à mon goût, mais ça viendra. En comparaison à nos précédents essais, +c'est plutôt positif: la première était ratée puisque trop de pression et trop +de dépôt (et donc un fort goût de levures) alors que la seconde (on avait tenté +d'ajouter de la lavande) avait un goût de lavande amère, pour ne pas dire de +savon.</p> +<p>Cette dernière bière a un goût de… de bière ! Il nous reste encore à 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 !</p> +</div> + \ No newline at end of file diff --git a/feeds/journal.atom.xml b/feeds/journal.atom.xml new file mode 100644 index 0000000..616f45f --- /dev/null +++ b/feeds/journal.atom.xml @@ -0,0 +1,13 @@ + +Carnets Web - journalhttps://blog.notmyidea.org/2019-07-03T00:00:00+02:00Ours2019-07-03T00:00:00+02:002019-07-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-07-03:/ours.html<p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>De manière plus large, est-ce normal …</p><p>J'ai de plus en plus de mal à garder mon calme dans les situations ou je +rencontres des humains qui ont des comportements que je trouve déplacés. Je me +demande à quel point le fait d'être maintenant un commerçant impacte ma +capacité relationelle générale.</p> +<p>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 ?</p> +<p>Suis-je en train de devenir un ours ?</p>velotaf2019-06-27T00:00:00+02:002019-06-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-27:/velotaf.html<p>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 …</p><p>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 personelle et le taf à la brasserie.</p> \ No newline at end of file diff --git a/feeds/life.atom.xml b/feeds/life.atom.xml new file mode 100644 index 0000000..ed574c7 --- /dev/null +++ b/feeds/life.atom.xml @@ -0,0 +1,90 @@ + +Carnets Web - lifehttps://blog.notmyidea.org/2018-05-27T00:00:00+02:00De Mozilla à la Brasserie du Vieux Singe2018-05-27T00:00:00+02:002018-05-27T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2018-05-27:/de-mozilla-a-la-brasserie-du-vieux-singe.html<p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que …</em></p><p><em>Ce weekend avait lieu <a href="https://sudweb.fr/2018/">SudWeb</a> « la conférence Web surtout humaine », ou on m'a proposé de venir parler de ma reconversion professionnelle, ou comment un passionné de Logiciels Libres choisit de créer une petite brasserie artisanale.</em></p> +<p><em>Certaines parties de ce que je voulais transmettre sont passées à la trappe, alors que d'autres ont pris plus de place que prévu. J'avais donc envie de reprendre mes notes pour les transformer en billet de blog, question d'élaborer sur le sujet.</em></p> +<hr> +<p>J'ai toujours été motivé par mes passions. Quand j'ai commencé à travailler professionnellement, je me suis rendu compte que même si je faisais quasiment la même chose qu'auparavant, ça n'avait plus le même goût. J'étais maintenant <em>obligé</em> de le faire, et je n'en tirais pas le même plaisir.</p> +<p>Quand j'étais plus jeune au lycée j'écrivais des programmes en <em>Visual Basic</em> que je partageais en ligne sur mon site en <code>.free.fr</code>. Programmes que probablement personne n'a lu, mais l'intention était bel et bien celle de partager mes créations, et d'échanger à leur propos.</p> +<p>Cette culture du partage — celle du logiciel libre — est celle qui m'anime.</p> +<p>Quelques années plus tard, je découvre le langage de programmation Python, et avec lui toute une communauté, mue par ces mêmes valeurs de partage et d'amélioration de nos pratiques. Puis je rencontre le Logiciel Libre, avec l'écriture d'un programme (<a href="https://getpelican.com">pelican</a>) qui reste encore largement utilisé aujourd'hui. Autant dire que c'est une bonne claque que de voir des inconnus contribuer à un bout de code qu'eux aussi jugent utile.</p> +<p>À la fin de mes études, alors que je reste passionné par le développement logiciel, je ne veux ni travailler pour l'industrie, ni pour la finance. Je songe même déjà à cette époque à changer de métier (avant même d'avoir commencé !). Coup de bol, une structure qui m'est chère cherche des développeurs Python: Mozilla. Sans trop y croire, je passe une série d'entretiens qui se déroulent bien (!) et je commence quelques mois plus tard à travailler pour cette organisation incroyable, porteuse d'espoir et de toute une symbolique pour moi.</p> +<p>Je bosse sur du Logiciel Libre, en Python, en télétravail parfois, avec une bonne paie, sans parler du côté prestigieux. Grisant.</p> +<p>Mais au fur et à mesure je découvre l'envers du décors: une méritocratie ancrée et assumée, une hiérarchie de plus en plus importante, menant à une lourdeur administrative assez présente. À ajouter à la barrière de la langue, et aux différences culturelles. Finalement tout n'est pas rose ici.</p> +<p>Je décide alors de (je pense) faire un de mes meilleurs choix de vie à ce jour: passer aux 4/5èmes. Je récupère tous mes vendredis. Des weekends de 3 jours, toutes les semaines. Un espace précieux pour me reposer, et pour rêver un peu.</p> +<p>C'est à ce moment que Fred, un ami de longue date, en revenant du Québec (ou les brasseries sont légion), me propose de faire de la bière avec lui. Moi qui ne savais même pas qu'il était <em>possible</em> de faire de la bière. On tente donc l'expérience, et nos premières expériences sont des journées bien <em>funky</em>, à faire toutes les erreurs possibles.</p> +<p>Peu à peu, on découvre un nouveau monde: celui des brasseurs amateurs. De nouvelles compétences sont nécessaires, de la physique à la biochimie. On se met à rencontrer des professionnels, des passionnés, à échanger sur les forums. On se forme, petit à petit. Tout comme il y a la communauté des gens qui font du Python, il y a la communauté des gens qui font de la bière. Pas encore autant fédérés, ça semble balbutiant alors mais la passion elle est bien présente.</p> +<p>Tout comme le monde du Logiciel Libre est constitué autour d'un ennemi commun (les GAFA), le monde de la bière artisanale à la sien: les brasseries industrielles, qui uniformisent les goûts et les processus.</p> +<p>Je continue en parallèle mon travail chez Mozilla, pendant 4 années. Et puis un jour, une annonce d'arrêt d'un projet sur lequel je travaillais me fait réaliser que cette situation m'épuise. La fameuse goutte de trop.</p> +<p>Je décide alors de partir, de faire une pause, sans trop savoir ce que l'avenir me réserve. Une petite période de blanc de deux mois. Le regard des autres est parfois culpabilisant. Mes parents me demandent si « je ne veux pas attendre encore un peu ». La transition me fait peur, mais je choisis quand même de troquer mon confort matériel pour de la cohérence.</p> +<p>Petit à petit, l'idée de monter ce qui est maintenant devenu <a href="https://www.vieuxsinge.com">La Brasserie du Vieux Singe</a> se pose en évidence. Mais monter une brasserie ce n'est pas uniquement faire de la bière: c'est se mettre d'accord sur des valeurs, trouver comment les défendre, monter un projet pour, et tenir le cap.</p> +<p>Quelques mois après mon départ, on se retrouve donc à parler de ces valeurs de partage, de documentation, de goût. De gouvernance et de collaboration aussi. +Dans nos pratiques courantes, on décide d'intégrer du temps pour documenter la vie de la brasserie.</p> +<p>À titre d'exemple, nos étiquettes contiennent l'ensemble des ingrédients que l'on utilise de la manière la plus détaillée possible. On travaille aussi sur un projet de laveuse de fûts, qui sera publié sous licence libre, avec l'idée de pouvoir, petit à petit, constituer un ensemble d'outils utiles à tous les brasseurs, et peut être même réussir à favoriser les échanges entre toutes ces personnes.</p> +<p>Nous sommes deux brasseurs, deux chefs d'entreprise, mais aussi deux développeurs. Nos compétences de développeurs nous sont utiles quotidiennement: pour notre laveuse de fûts, pour nos créations de recettes (j'ai découvert la puissance des tableurs !), pour notre site de préventes, notre site Web, nos outils du quotidien. On se rend compte qu'il s'agit de compétences précieuses.</p> +<p>Mais monter une entreprise, c'est aussi assumer une partie administrative. Vous vous rappelez cette histoire de réactions face aux activités subordonnées ? Et bien quand je fais mes déclarations aux douanes, ce n'est pas de gaîté de cœur. Je sais par contre pourquoi je le fais: ce sont les règles du jeu. Des obligations, mais peut-être moins de coercition. J'y trouve plus de sens.</p> +<p>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.</p> +<p>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. </p>Groupement d'achats & partage d'expérience2018-03-03T00:00:00+01:002018-03-03T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-03-03:/groupement-dachats-partage-dexperience.html<p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers …</p><p>Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.</p> +<p>L'idée est simple:</p> +<ul> +<li>commander en gros, pour faire baisser les prix</li> +<li>se passer d'intermédiaires et favoriser les circuits courts</li> +<li>aller à la rencontre des producteurs locaux et échanger</li> +</ul> +<p>Notre groupement dessert actuellement 18 foyers et une 60aine de 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'expérience et quelques astuces / outils, au cas où l'envie vous prenne à vous aussi :)</p> +<h1>Organisation</h1> +<p>On organise environs trois ou quatre distributions par an. Le <em>modus operandi</em> est le suivant:</p> +<ul> +<li>chaque product·eur·rice à un·e référent·e, qui s'occupe de faire le lien;</li> +<li>une personne est désignée pour coordonner la distribution;</li> +<li>4 semaines avant la distribution, les référent·e·s mettent à jour les prix / produits dans le tableau de commandes;·e·</li> +<li>3 semaines avant la distribution, les commandes sont ouvertes;</li> +<li>2 semaines avant la distribution, les commandes sont closes;</li> +<li>Les référent·e·s ont ensuite deux semaines pour récupérer les commandes pour la distribution</li> +</ul> +<h1>Quels produits ?</h1> +<p>On essaye d'avoir uniquement des produits qui se conservent (on a également quelques autres produits plus frais, mais avec d'autres modalités).</p> +<p>Entre autres: bières, légumes secs, conserves, jus, miel, pâtes, semoule, café, vinaigres, pommes de terre, oignons, huiles, 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'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'est pas animé par la même éthique !).</p> +<h1>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'attendre la date de la distribution pour l'encaissement. La plupart des producteurs acceptent d'être payés sous quinzaine.</p> +<p>Le jour de la distribution, tout le monde apporte son chéquier. Nous avons mis +en place une moulinette qui s'occupe de faire la répartition des chèques automatiquement, chaque membre se retrouve à faire en moyenne un ou deux chèques.</p> +<p>Chaque référent·e est ainsi remboursé·e de la somme avancée, et chaque +membre du groupement d'achat paye ce qu'il doit payer. Nous n'avons +volontairement pas de structure juridique et pas de compte en banque. Les +paiements s'effectuent directement entre nous.</p> +<h1>Transports</h1> +<p>Chaque référent·e commande les produits, puis ensuite s'occupe de les rapatrier. À Rennes, on a la chance d'avoir pas mal de producteurs aux alentours, donc c'est assez simple.</p> +<p>Le mieux est de ramener les produits juste un peu avant la distribution au lieu de distribution, ça permet d'éviter de les stocker trop longtemps, et d'éviter aux producteurs d'attendre trop longtemps avant d'encaisser les chèques.</p> +<p>Pour les grosses commandes, les voitures se remplissent bien, mais ma petite Clio suffit, que ce soit dit !</p> +<h1>La distribution</h1> +<p>Un peu en amont de la distribution, il faut organiser l'espace. Des tas par membre sont constitués pour faciliter les choses le jour de la 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 pour:</p> +<ul> +<li>discuter de la date de la prochaine distribution;</li> +<li>trouver une nouvelle personne pour la coordonner;</li> +<li>discuter de nouveaux produits;</li> +<li>refaire le monde;</li> +<li>changer de référents pour les producteurs.</li> +</ul> +<p>Et c'est reparti pour un tour ;)</p> +<h1>Nos outils</h1> +<p>On utilise un tableur en ligne pour partager les prix et prendre les commandes. On a essayé d'utiliser <em>ethercalc</em> au début mais ça ne fonctionnait pas pour nous à l'époque (trop de petits bugs). On a donc préféré utiliser Google docs (ouch).</p> +<p>Il est d'ailleurs possible d'y intégrer de nouvelles fonctionnalités assez facilement, du coup Fred et Rémy ont planché sur un moyen d'automatiser la répartition des chèques (qu'on faisait dans un premier temps à la main - assez péniblement).</p> +<p>Le système n'est pas parfait mais fonctionne quand même assez bien !</p> +<p>Quelques ressources, donc:</p> +<ul> +<li><a href="https://gist.github.com/almet/8c77fafc9e487c02ded852ec4a91ae16">le code pour faire la répartition des 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'en faire une copie !).</li> +</ul> +<p>Bon groupement d'achat ;)</p> \ No newline at end of file diff --git a/feeds/misc.atom.xml b/feeds/misc.atom.xml new file mode 100644 index 0000000..f069c73 --- /dev/null +++ b/feeds/misc.atom.xml @@ -0,0 +1,43 @@ + +Carnets Web - mischttps://blog.notmyidea.org/2019-06-26T00:00:00+02:00Un espace des communs Rennais ?2019-06-26T00:00:00+02:002019-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2019-06-26:/un-espace-des-communs-rennais.html<p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le …</p><p><em>Ce document se veut surtout être quelques notes, et donc revêt un caractère « fouilli » paaaarfaitement assumé. D’ailleurs, ce n'est que ce que j'ai bien voulu retenir. Voilà.</em></p> +<p>Je ressors d'une discussion avec quelques complices autour de deux idées : +1. Avoir un espace pour fédérer différentes personnes intéressées par le sujet des <em>communs</em>; +2. Monter une structure Rennaise pour proposer de l’hébergement de services web.</p> +<p>Élaborons un peu...</p> +<h2>1. Un espace pour fédérer</h2> +<p>L'idée qui à été développée est celle d'avoir un espace (un ou des lieux, à différents moments dans l'année) pour que les rencontres entre les projets <em>du libre</em> à Rennes puissent se dérouler. Le constat est qu'il existe différentes structures actuellement en place, mais que a) certaines personnes ne se retrouvent pas dans ces espaces et b) la porosité entre ces différents groupes est assez faible.</p> +<p>Pour l'instant pas d'idée précise de ce qui pourrait être proposé, mais quelques pistes ont été évoquées. l'envie est de faire un document d'intention et de proposer à d'autres de rejoindre le collectif en création.</p> +<h3>Fréquence</h3> +<p>Deux pistes ont été évoquées:</p> +<ul> +<li> +<p><strong>Faire des rencontres suffisamment espacées les unes des autres</strong>, pour que leur caractère « exceptionnel » soit une force. Si la fréquence des réunions est assez faible, alors l'incitation pour y prendre part est peut-être plus grande ?</p> +</li> +<li> +<p>ou au contraire, <strong>avoir des rencontres avec une fréquence assez forte</strong>, pour qu'en cas d'incapacité à participer il n'y ait pas trop longtemps à attendre ?</p> +</li> +</ul> +<h3>Charte éthique</h3> +<p>Le fait d'avoir un <em>code de conduite</em> pour de tels évènements à été discuté, un des arguments évoqués étant le fait qu'un tel code n'est pas considéré nécessaire par certaines personnes, puisque les règles évoquées tiennent du bon sens.</p> +<p>Il a été précisé que l'établissement de ce type de document a pour objectif de: +- Faire que des minorités et/ou oppressés se sentent protégés et considérés, et donc bienvenues à ce type d'évènements; +- En cas de situations considérées comme problématiques, des personnes référentes soient désignées pour aider à leur résolution</p> +<h3>Gouvernance</h3> +<p>Le sujet de la gouvernance à été également abordé : pour avoir de tels rendez-vous, peu importe leur nature, il faut que ceux-cis soient organisés. La possibilité d'avoir des organisat·rices·eurs· tournantes à été proposé.</p> +<p>Pour :</p> +<ul> +<li>Cela permet de ne pas reposer uniquement sur quelques personnes;</li> +<li>Faire des fiches explicatives qui permettent à tou·te·s de s'impliquer</li> +</ul> +<p>Contre : </p> +<ul> +<li>Quand tout le monde est responsable, personne ne l'est.</li> +</ul> +<p>Peut-être que des solutions intermédiaires sont à trouver, en désignant d'une fois sur l'autre les personnes qui s’occupent du prochain rendez-vous, par exemple.</p> +<h2>2. Hébergement de services Web</h2> +<p>On a discuté très rapidement de la possibilité de monter une structure pour faire de l’hébergement de services web sur Rennes. Le sujet n'a pas été vraiment développé, mais la question de la relation entre avoir un espace pour fédérer (le 1.) et être un hébergeur de service (le 2.) a été rapidement abordé.</p> +<p>Faut-il avoir une seule et même structure / groupe de personnes pour ces deux projets ? Dans le cas ou l'un s'arrête, entraînerait-il l'autre dans sa « chute » ? Est-il logique de lier les deux ?</p> +<h2>Et donc ?</h2> +<p>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 :-)</p> \ No newline at end of file diff --git a/feeds/musique.atom.xml b/feeds/musique.atom.xml new file mode 100644 index 0000000..e9f1f6a --- /dev/null +++ b/feeds/musique.atom.xml @@ -0,0 +1,22 @@ + +Carnets Web - musiquehttps://blog.notmyidea.org/2012-12-28T00:00:00+01:00Languages2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-28:/languages.html<p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe><p>Ouriel Ellert &quot; Languages&quot; avec Anthony Jambon &amp; Natascha Rogers, c'est +enregistré par le <a class="reference external" href="http://www.studiomezzanine.fr">Studio Mezzanine</a> qui comme d'hab font un +travail impeccable.</p> +<p>Plus d'infos sur Natasha Rogers et son groupe ici: +<a class="reference external" href="http://www.studiomezzanine.fr/natascha-rogers/">http://www.studiomezzanine.fr/natascha-rogers/</a></p> +<iframe width="650" height="480" src="http://www.youtube.com/embed/3I5PPdsTFz0" frameborder="0" allowfullscreen></iframe>"Groovy"2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/groovy.html<p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>C'est pour ça que j'ai du …</p><p>“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta tête commence +à hocher.</p> +<p>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 ;)</p> + \ No newline at end of file diff --git a/feeds/notes.atom.xml b/feeds/notes.atom.xml new file mode 100644 index 0000000..4efee0a --- /dev/null +++ b/feeds/notes.atom.xml @@ -0,0 +1,354 @@ + +Carnets Web - noteshttps://blog.notmyidea.org/2014-11-20T00:00:00+01:00Le secret du bonheur2014-11-20T00:00:00+01:002014-11-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2014-11-20:/le-secret-du-bonheur.html<p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village …</p><p>Un enfant demande à son père :</p> +<blockquote> +Dis papa, quel est le secret pour être heureux ?</blockquote> +<p>Sans dire un mot, le père demande à son fils de le suivre ; +Ils sortent de la maison, le père sur leur vieil âne et le fils suivant à pied.</p> +<p>Et les gens du village de dire :</p> +<blockquote> +Mais quel mauvais père qui oblige ainsi son fils d'aller à pied !</blockquote> +<p>Le lendemain ils sortent de nouveau.</p> +<p>Le père ayant installé son fils sur l'âne et lui marchant à côté.</p> +<p>Les gens du village dirent alors :</p> +<blockquote> +Quel fils indigne, qui ne respecte pas son vieux père et le laisse aller à pied !</blockquote> +<p>Le jour suivant, ils s'installent tous les deux sur l'âne avant de quitter la maison. +Les villageois commentèrent en disant :</p> +<blockquote> +Ils ne respectent pas leur bête à la surcharger ainsi !</blockquote> +<p>Le jour suivant, ils partirent en portant eux-mêmes leurs affaires, l'âne trottinant derrière eux. +Cette fois les gens du village y trouvèrent encore à redire :</p> +<blockquote> +Voilà qu'ils portent eux-mêmes leurs bagages maintenant ! C'est le monde à l'envers !</blockquote> +<p>De retour à la maison, le père dit à son fils :</p> +<blockquote> +Tu me demandais l'autre jour le secret du bonheur. +Peu importe ce que tu fais, il y aura toujours quelqu'un pour y trouver à redire. +Fais ce qui te plaît et là tu seras vraiment heureux.</blockquote> +Le revenu de base2013-10-03T00:00:00+02:002013-10-03T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-10-03:/le-revenu-de-base.html<iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra …</p><iframe width="560" height="315" src="http://www.youtube.com/embed/-cwdVDcm-Z0" +frameborder="0" allowfullscreen></iframe><p>Quelques notes prises en visualisant le documentaire &quot;le revenu de base&quot;.</p> +<ul class="simple"> +<li>4 Allemands sur 10 travaillent.</li> +<li>3/10 (les enfants et jeunes)</li> +<li>2/10 retraite / rente</li> +<li>1/10 assurance chomage / AS</li> +<li>41% sont le fruit d'un travail rémunéré.</li> +</ul> +<p>Le revenu de base est inconditionnel.</p> +<p>Le marché du travail ne pourra pas suffire à toute la population. En refusant +l'idée du RDB, on est obligé de croire en la croissance économique.</p> +<p>Différence entre une approche qantitative du travail VS une approche sociale.</p> +<p>La croissance éco ≠ croissance de l'emploi.</p> +<p>Parallelle entre le RDB et la déclaration des droits de l'homme. &quot;Et qui voudra +faire le sale boulot ?&quot;</p> +<p>Utopie veut dire le &quot;non lieu&quot;, le lieu qu'on à pas encore trouvé ici sur +terre, à part dans notre imaginaire.</p> +<p>Agriculture: Il y à 100 ans, qqn qui travaillait dans l'agriculture produisait assez pour +3 autres personnes. ajd un agriculteur produit assez pour 120 personnes, via +des machines énormes et à la rationalisation.</p> +<p>Rationalisation: moins d'emploi.</p> +<p>La condition de pouvoir refuser un travail est très importante.</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Le financmenet est acquis, la dificulté c'est la liberté</p> +<p class="attribution">&mdash;NA</p> +</blockquote> +<blockquote> +<p>Il faut en finir avec cette idée fausse, selon laquelle seul le travail +rémunéré constitue une contribution méritoire à la société, en réalité, c'est +souvent exactement l'inverse.</p> +<p class="attribution">&mdash;Katja Kipping, membre du parlement allemand.</p> +</blockquote> +<blockquote> +<p>Si les gens on déjà une sécurité matérielle, ils sont plus difficiles +à corrompre.</p> +<p class="attribution">&mdash;Katja Kipping</p> +</blockquote> +<blockquote> +<p>Soutenir les populations sans poser de condition. c'est un principe qui à la +longe, devra s'imposer. Mais il lui faudra d'abord affronter les droits et +privilèges dont on bénéficie aujourd'hui.</p> +<p class="attribution">&mdash;Anonyme.</p> +</blockquote> +<blockquote> +Si les revenus étaient uniquement lié au travail, il faudrait donner les plus +hauts revenus aux machines.</blockquote> +<p>Le sens de l'économie, c'est de libérer l'homme du travail Beaucoup de gens qui +ont une &quot;place de travail&quot;, n'ont en réalité qu'une &quot;place de revenu&quot;.</p> +</div> +<div class="section" id="chiffres"> +<h2>Chiffres</h2> +<p>Un sondage à été effectué. La question est: &quot;Si vous aviez un revenu de base, +est-ce que vous iriez encore travailler ?&quot;</p> +<ul class="simple"> +<li>~60% disent oui</li> +<li>30% répondent oui, mais plus à plein temps.</li> +<li>10% pour faire autre chose.</li> +</ul> +<p>Avec une question différente:</p> +<p>&quot;Si on instaurait un revenu de base, est-ce que vous pensez que les autres +iraient travailler ?&quot;</p> +<ul class="simple"> +<li>~80% répondent non.</li> +</ul> +<p>C'est un changement aussi dans les modes d'éducation, on nous enseigne à être +&quot;employable&quot;, et non pas à apprendre quelque chose qui nous interesse. Les gens +ont peur de ne pas trouver du travail.</p> +</div> +<div class="section" id="ressources"> +<h2>Ressources</h2> +<ul class="simple"> +<li>Le sens commun, Thomas Payne.</li> +<li>Peter Ulrich</li> +</ul> +</div> +<div class="section" id="comment-financer-le-rdb"> +<h2>Comment financer le RDB</h2> +<p>Si l’on se fie à son produit intérieur brut (PIB), la France est aujourd’hui le +cinquième pays le plus riche du monde. En 2010, le revenu disponible (après +versement des pres- tations sociales et prélèvement des impôts directs) s’y +élevait à 1 276 euros par mois et par personne, adultes et enfants confondus. +Nous disposons donc de ressources suffisantes pour garantir à chaque individu 1 +276 euros si l’on décidait d’opérer un partage strictement égalitaire. C’est +nettement plus que le seuil de pauvreté actuel, fixé en France à 60 % du revenu +médian (1), soit 960 euros par adulte. Qui peut le plus pouvant le moins, la +France a donc sans nul doute les moyens d’assurer à tous ses résidents un +revenu au moins égal au seuil de pauvreté.</p> +</div> +<div class="section" id="a-reculons-par-andre-gorz"> +<h2>À Reculons, par André Gorz.</h2> +<p>(Paru dans le monde diplomatique de Juin 1990)</p> +<p><em>Proche de Jean-Paul Sartre, cofondateur, en 1964, du Nouvel Observateur, le +philosophe André Gorz (1923-2007) s’est converti progressivement à un +écosocialisme dont il est devenu l’un des principaux théoriciens. En 1990, dans +nos colonnes, sous le titre « Pourquoi la société salariale a besoin de +nouveaux valets », il formulait une critique de l’idéologie du travail qui +devait l’amener quelques années plus tard à se prononcer en faveur d’un revenu +d’existence.</em></p> +<p>Dans l’ensemble des pays capitalistes d’Europe, on produit trois à quatre fois +plus de richesses qu’il y a trente-cinq ans ; cette production n’exige pas +trois fois plus d’heures de travail, mais une quantité de travail beaucoup plus +faible. (...)</p> +<p>Nous sortons de la civilisation du travail, mais nous en sortons à reculons, et +nous entrons à reculons dans une civilisation du temps libéré, incapables de la +voir et de la vouloir, incapables donc de civiliser le temps libéré qui nous +échoit, et de fonder une culture du temps disponible et une culture des +activités choisies pour relayer et compléter les cultures techniciennes et +profes- sionnelles qui dominent la scène. (...)</p> +<p>Pour près de la moitié de la population active, l’idéologie du travail est +devenue une mauvaise farce ; l’identification au travail est désormais +impossible, car le système économique n’a pas besoin ou n’a pas un besoin +régulier de leur capacité de travail. La réalité que nous masque l’exaltation +de la « ressource humaine », c’est que l’emploi stable, à plein temps, durant +toute l’année et toute la vie active, devient le privilège d’une minorité. +Pour [les autres], le travail cesse d’être un métier qui intègre dans une +communauté productive et définit une place dans la société. Ce que le patronat +appelle « flexibilité » se traduit pour les salariés par la précarité. (...)</p> +<p>Que doit être une société dans laquelle le travail à plein temps de tous les +citoyens n’est plus nécessaire, ni économiquement utile ? Quelles priorités +autres qu’économiques doit-elle se donner ? Comment doit-elle s’y prendre pour +que les gains de productivité, les économies de temps de travail profitent à +tout le monde ? Comment peut-elle redistribuer au mieux tout le travail +socialement utile de manière à ce que tout le monde puisse travailler, mais +travailler moins et mieux, tout en recevant sa part des richesses socialement +produites ?</p> +<p>La tendance dominante est d’écarter ce genre de questions et de poser le +problème à l’envers : comment faire pour que, malgré les gains de productivité, +l’économie consomme autant de travail que par le passé ? Comment faire pour que +de nouvelles activités rémunérées viennent occuper ce temps que, à l’échelle de +la société, les gains de productivité libèrent ? A quels nouveaux domaines +d’activité peut-on étendre les échanges marchands pour remplacer tant bien que +mal les emplois supprimés par ailleurs dans l’industrie et les services +industrialisés ?</p> +<p>On connaît la réponse, pour laquelle les Etats-Unis et le Japon ont montré la +voie : le seul domaine dans lequel il est possible, en économie libérale, de +créer à l’avenir un grand nombre d’emplois, c’est celui des services aux +personnes. Le développement de l’emploi pourrait être illimité si l’on +parvenait à transformer en prestations de services rétribuées les activités que +les gens ont, jusqu’à présent, assumées chacun pour soi. Les économistes +parlent à ce sujet de « nouvelle croissance plus riche en emplois », de « +tertiarisation » de l’économie, de « société de services » prenant le relais de +la « société industrielle » (1). (...)</p> +<p>Le problème de fond auquel nous sommes confrontés est celui d’un au-delà de +l’économie et, ce qui revient au même, d’un au- delà du travail rémunéré. La +rationalisation économique libère du temps, elle continuera d’en libérer, et il +n’est plus possible, par conséquent, de faire dépendre le revenu des citoyens +de la quantité de travail dont l’économie a besoin. Il n’est plus possible, non +plus, de continuer à faire du travail rémunéré la source principale de +l’identité et du sens de la vie pour chacun.</p> +<p>La tâche d’une gauche, si gauche il doit y avoir, consiste à transformer cette +libération du temps en une liberté nouvelle et en des droits nouveaux : le +droit de chacun et de chacune de gagner sa vie en travaillant, mais en +travaillant de moins en moins, de mieux en mieux, tout en recevant sa pleine +part de la richesse socialement produite. Le droit, d’autre part, de travailler +de façon discontinue, intermittente, sans perdre durant les intermittences de +l’emploi le plein revenu – de manière à ouvrir de nouveaux espaces aux +activités sans but économique 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.</p> +</div> +Notes: Économie libidinale et économie politique2013-07-06T00:00:00+02:002013-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-06:/notes-economie-libidinale-et-economie-politique.html<p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un …</p><p>Une enquete d'un cabinet de marketing american ARI qui pour la première fois en +2004 disait qu'on voyait aparaitre des &quot;alter consommateurs&quot;, qui n'étaient pas +de gens qui consommaient moins, mais qui étaient des gens malheureux de +consommer. Et qui définissaient la consommation comme une dépendance et une +addiction.</p> +<p>Un autre comportement s'est développé: le modèle &quot;collaboratif et contributif&quot;. +Ce modèle ne se repose pas sur la consommation mais sur l'implication et la +collaboration. Ce modèle est induit par internet, qui ne repose plus sur +l'opposition production / consommation.</p> +<p>Sur internet nous ne sommes pas des simples consommateurs, puisque vous êtes un +expéditeur / distributeur.</p> +<p>Le changement prduit par internet est le fait que les gens ne sont plus +simplement des consommateurs,mais sont également producteurs de contenus +/ viennent améliorer les contenus existants.</p> +<p>Note perso: quid du culte de la personalité qui en ressort ? Ce qu'il apelle +l'écologie relationelle ?</p> +<p>Quel est le manque que vient combler facebook par exemple ? Et quel est +l'impact que ces nouveaux réseaux ont sur les modèles relationels que l'ont +connait (famille, école, droit, etc.).</p> +<div class="section" id="citations"> +<h2>Citations</h2> +<blockquote> +<p>Une révolution c'est le fait de faire une boucle est d'arriver au terme de +quelque chose. D'avoir clôt un cycle. La lune fait des révolutions aussi.</p> +<p>81% des Américains déclarent que le consumerisme est une plaie pour l'amérique +(d'après Juliet Score)</p> +</blockquote> +</div> +François Elie : Quelle école pour la société de l’information ?2013-06-14T00:00:00+02:002013-06-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-06-14:/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html<p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens …</p></blockquote><p><a class="reference external" href="http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference">http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference</a></p> +<p>Quelques bouts selectionnés.</p> +<blockquote> +<p>Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens font ça entre eux et on n’est pas non plus +dans une école de l’apprentissage où l’école a pour but de donner un métier, un +bagage utilisable. L’école ne sert évidemment pas à ça. D’ailleurs heureusement +parce que sinon on n’enseignerait pas la philosophie qui ne sert à rien à part +fabriquer des profs de philosophie !</p> +<p>On n’a pas besoin de tableau numérique pour enseigner l’informatique elle-même +pour enseigner la science. De la même façon on n’a pas besoin de machine à +calculer pour enseigner les mathématiques. Évidemment ! On n’a pas besoin d’une +machine à calculer pour savoir faire une division. Au contraire, surtout pas !</p> +<p>Il faut cesser d’opposer l’enseignement de la programmation d’une part et +l’enseignement des usages, c’est important mais ça c’est l’école des maîtres et +des esclaves. Ce qu’il faut enseigner, vite et à tous, c’est la science, pas la +technologie ou l’usage. C’est en amont de la programmation, l’algorithmique. +C’est, en amont de telle instanciation, du codage, du chiffrement, la théorie, +quelque chose qui comme les maths n’ont besoin que d’une craie et d’un tableau +noir.</p> +<p>Ce n'est pas un hasard si le mot &quot;numérique&quot; à remplaçé le mot &quot;informatique&quot;, +c'est qu'on voudrait nous faire croire qu'il n'y a pas besoin de l'apprendre.</p> +</blockquote> +Habitat collectif2012-12-28T00:00:00+01:002012-12-28T00:00:00+01:00Alexis Métaireautag: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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais …</p><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 autres.</p> +<p>Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.</p> +<p>Voilà quelques ressources qui peuvent être utiles si jamais vous aussi ça vous +titille:</p> +<ul class="simple"> +<li><a class="reference external" href="http://www.habicoop.fr/IMG/pdf/Memoire_hbtat_coop_Vaulx-2.pdf">L’Habitat Coopératif : Solution au problème de responsabilisation sociale des +copropriétaires sur la commune de Vaulx en Velin +?</a> - mémoire REPIQUET Anne +2005.</li> +<li>Un bouquin à lire avec plein d'infos: <a class="reference external" href="http://www.ecosociete.org/t101.php">Vivre autrement</a> de Diana Leafe Christian.</li> +<li>…</li> +</ul> +Astuces SSH2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/astuces-ssh.html<div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s …</pre></div><div class="section" id="tunelling"> +<h2>Tunelling</h2> +<p>Parce que je m'en rapelle jamais (tête de linote):</p> +<pre class="literal-block"> +$ ssh -f hote -L local:lolnet.org:destination -N +</pre> +</div> +<div class="section" id="ssh-config"> +<h2>.ssh/config</h2> +<p>(merci <a class="reference external" href="http://majerti.fr">gaston</a> !)</p> +<p>La directive suivante dans .ssh/config permet de sauter d'hôte en hôte +séparés par des &quot;+&quot;</p> +<pre class="literal-block"> +Host *+* + ProxyCommand ssh $(echo %h | sed +'s/+[^+]*$//;s/\([^+%%]*\)%%\([^+]*\)$/\2 -l \1/;s/:/ -p /') +PATH=.:\$PATH nc -w1 $(echo %h | sed 's/^.*+//;/:/!s/$/ %p/;s/:/ /') +</pre> +<p>On peut donc spécifier des &quot;sauts&quot; ssh du style:</p> +<pre class="literal-block"> +ssh root&#64;91.25.25.25+192.168.1.1 +</pre> +<p>Ensuite on peut essayer de rajouter:</p> +<pre class="literal-block"> +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é +</pre> +</div> +Notre dame des landes2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-27:/notre-dame-des-landes.html<p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre …</p><p>La lutte à Notre Dame des Landes ne fait pas du tout que commencer, mais il se +trouve que les médias se sont &quot;emparés&quot; de la question que très récemment, +depuis que JM Ayrault s'est retrouvé premier ministre.</p> +<p>Voici une sélection d'articles que j'ai trouvé pertinents, à partir de décembre +2012:</p> +<ul class="simple"> +<li>Article dans le monde qui explique la complexité de la lutte sur place: <a class="reference external" href="http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html">http://www.lemonde.fr/idees/article/2012/12/13/notre-dame-des-landes-une-resistance-qui-ne-se-laissera-pas-dicter-sa-conduite_1805511_3232.html</a></li> +<li>autour de relations à la presse: +<a class="reference external" href="http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html">http://www.rennestv.fr/catalogue/magazine/notre-dame-des-landes-l-inaceptable-interdiction-de-la-presse.html</a></li> +<li>Notre-Dame-des-Landes : un pilote annonce un fiasco pour le futur aéroport <a class="reference external" href="http://www.bastamag.net/article2866.html">http://www.bastamag.net/article2866.html</a></li> +</ul> +Semences paysannes2012-12-20T00:00:00+01:002012-12-20T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-20:/semences-paysannes.html<p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité …</p><p><a class="reference external" href="http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed">http://www.dailymotion.com/video/x5nhq0_les-semences-paysannes_news#from=embed</a></p> +<p>A l'heure actuelle, il est interdit pour deux agriculteurs de s'échangers des semences dans le but d'en revendre la production.</p> +<p>Les états ont crée la propriété interellectuelle pour relancer l'industrie après les dégats de la guerre et les selectionneurs en ont profité en 1960 au sein de l'UPOV pour faire des textes pour s'approprié les selections qu'ils ont fait. Les textes ont été votés par les députés depuis: bien prové au lieu de bien collectif.</p> +<p>Les semenciers n'existent que depuis 150 ans. Ils revendiquent maintenant le monopole de selection.</p> +<p>Un catalogue est prévu pour les semences dites &quot;de conservation&quot; (alors qu'elles évoluent, conservation n'est pas un terme adapté). C'est la voie qui est possible pour pouvoir échanger des semences entre agriculteurs.</p> +<p>→ Quelles sont les semences de conservation depuis 2002 ? → Quid des semences paysannes, qui évoluent et que l'on garde d'année en année, en selectionnant les meilleures especes. → Existe-il un autre catalogue ? → Au niveau européen, quelles sontles contraintes d'inscription ? Gratuité demandée, qu'en est il ?</p> +<p>→ Relocalistion sur les terroirs des échanges.</p> +<p>→ Biodiversité serait tué par l'utilisation d'espèces inscrites.</p> +<p>Série de vidéos sur la paysannerie: <a class="reference external" href="http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86">http://www.latelevisionpaysanne.fr/video.php?lirevideo=86#86</a></p> + \ No newline at end of file diff --git a/feeds/pyconfr2015.atom.xml b/feeds/pyconfr2015.atom.xml new file mode 100644 index 0000000..8155a25 --- /dev/null +++ b/feeds/pyconfr2015.atom.xml @@ -0,0 +1,676 @@ + +Carnets Web - pyconfr2015https://blog.notmyidea.org/2015-10-18T00:00:00+02:00PyconFR 2015 — Assemblée générale2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-assemblee-generale.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Mot de feth sur Nelle, qui était une présidente très présente. Merci !</p> +<div class="section" id="passe"> +<h2>Passé</h2> +<p>Il existe des communautés locales à Lyon Grenoble, Nantes. +Des Afpyro ont été organisés dans toutes ces villes + Rennes + Marseille +Support pour 2 Django Carrots. +Par rapport au mentoring, très peu de retours, peut etre de nouvelles choses +à faire.</p> +<p>FOSDEM 2015 était complet. Il y avait une salle python tojours pleine. +Dsicussions sur la diversité.</p> +</div> +<div class="section" id="futur"> +<h2>Futur</h2> +<p>Amandine propose d'organiser des soirées à NUMA l'an prochain. +Global code retreat: participation +Migrer le serveur de l'AFPY +Reboot des status: nos pratiques ne sont pas en ligne avec nos status. +Mise en place de mentoring pour python.</p> +<div class="section" id="status"> +<h3>Status</h3> +<p>Comité directeur renouvelé par tiers. Il est composé de 18 personnes. Les +discussions qui sont dans le CD n'en sortent pas, et les discussions sont donc +effectuées en priuvées.</p> +<p>L'idée actuelle serait de réduire le CD de 18 à 9 personnes. Tout le travail +serait fait en dehors du CD. Il est possible de mettre en place un groupe de +travail pour travailler sur l'évolution de la charte.</p> +<p>Il faut faire évoluer les status: ils ne sont pas actuellement bien faits par +rapport à notre utilisation.</p> +</div> +</div> +PyconFR 2015 — Hospital - des tests en prod2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-hospital-des-tests-en-prod.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Benoit Bryon, Peopledoc.</p> +<p>Pour une procédure de déploiement, comment est-ce qu'on valide que tout va bien +une fois que tout est dépoyé ? Si on a une application très simple (upload et +envoi de fichiers).</p> +<p>Pour des applications plus complexes, il y a beaucoup de choses à tester (base +de données, cache, email, etc). Beaucoup de parties sont utiles: reverse +proxy, django, base de données etc.</p> +<p>Lors d'un déploiement, comment faire pour vérifier que tout tourne lorsque tout +est déployé ?</p> +<div class="section" id="comment-faire"> +<h2>Comment faire ?</h2> +<ul class="simple"> +<li>Les tests permettent de tester hors sol.</li> +<li>Le provisionning permet de valider que tout tourne correctement, mais</li> +<li>simplement au démarrage. Les pannes ne sont pas détectées.</li> +<li>Le logging va permettre de detecter les erreurs, mais trop tard.</li> +<li>Le monitoring permet d'avoir une vue de l'exterieur.</li> +</ul> +<p>Hostpital propose de faire des assertions sur la configuration, +l'environnement, <em>en cours de fonctionnement</em>. Ce sont les developeurs qui +ajoutent ces assertions.</p> +<p>Cela peut servir à valider un déploiement, pour etre rassuré une fois que le +déploiement effectué. Cela peut aussi service à surveiller un service et +diagnostiquer les problèmes.</p> +</div> +<div class="section" id="hospital"> +<h2>Hospital</h2> +<dl class="docutils"> +<dt>::</dt> +<dd>pip install hospital</dd> +</dl> +<p>Hospital est un outil en python. On définit des tests, de la même manière que +l'on définit des tests unitaires. On fait des assertions, comme pour les tests +unitaires. Hospital propose des helpers pour les cas courants: +<cite>assert_http_response</cite> ou <cite>assert_ping</cite>.</p> +<p>La vue est une vue de l'intérieur. La différence avec le monitoring est que +l'on teste la connectivité entre les services (exemple d'une requete +elasticsearch qui échoue depuis un service django).</p> +<p>Pour la supervision, les healthchecks sont lancés avec une ligne de commande +<cite>hospital-cli</cite>. Il est possible de lancer également ces tests avec nose ou +py.test.</p> +<p>Il est aussi possible de faire le monitoring avec une API HTTP <cite>hospital +serve</cite>.</p> +<div class="section" id="les-lacunes-de-hospital"> +<h3>Les lacunes de hospital</h3> +<p>Les healthchecks sont fait actuellement en synchrone. Cela peut prendre du +temps. Il pourrait etre interessant de lancer des taches de manière distribuée +/ en paralelle.</p> +<p>Il pourrait etre utile de faire la distinction entre les smoketests et les +diagnostiques: les premiers sont des petits checks qui permettent de dire si ça +marche, de manière très simple. De l'autre coté, les diagnostiques seraient eux +plus fins.</p> +</div> +</div> +<div class="section" id="wrap-up"> +<h2>Wrap up</h2> +<p>Validez votre configuration, la connectivité avec les services externes. Faites +des tests souvent !</p> +</div> +PyconFR 2015 — We don't need your loop2015-10-18T00:00:00+02:002015-10-18T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-18:/pyconfr-2015-we-dont-need-your-loop.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: serge_sans_paille.</p> +<p>Retour sur le passé des boucles: ASM, fortran, C. Avec APL, la boucle est +cachée au fur et à mesure des évolutions. Écrire une boucle ne devrait pas etre +exprimer comment atteindre le resultat.</p> +<p>En python, par exemple, il vaut mieux utiliser <cite>sum</cite> plutôt que de faire +l'addition nous même (pour faire une addition des elements d'une liste).</p> +<p>Actuellement, le compilateur python est lent si on utilise numpy.sum sur des +matrices complexes.</p> +<div class="section" id="comment-aller-plus-vite"> +<h2>Comment aller plus vite?</h2> +<p>Cython est assez compliqué, il faut savoir ce que l'on fait pour optimiser et +écrire du bon code Cython.</p> +<p>Avec pythran, l'intelligence est dans le compilateur, qui permet d'écrire +notemment des boucles correctement.</p> +<p>En donnant plus d'informaitons au compilateur, plutôt que de faire des boucles, +cela lui permet d'avoir un contexte qui lui permet d'optimiser le code.</p> +<p>Par contre, cela veut dire que plus de connaissances sont necessaire pour lire +le code python.</p> +<p>pythran permet de compiler directement vers du C++ sans avoir à changer son +code de base (python). C'est utile pour du code numpy notemment.</p> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<p>Possible de paralelliser de manière explicite <strong>ou</strong> implicite.</p> +<p><strong>C'est très utile pour les gens qui font du &quot;number crunching&quot;. Est-ce que +c'est utile pour d'autres domaines d'application (Web)?</strong></p> +<p>Pas vraiment. CPython est déjà bien fait pour ces cas d'utilisation.</p> +<p><strong>Est-il possible de lancer pythran sans faire de commentaires ?</strong></p> +<p>C'est possible mais cela ne servira pas à grand chose. Il est necessaire de +connaitre le type des objets qui sont utilisés lors des boucles.</p> +<p><strong>Est-ce que vous songez à un compilateur à la volée ?</strong></p> +<p>De gros efforts ont été faits dernièrement pour diminuer le temps de +compilation. Mais pour une fonction qui renvoie None prends de l'ordre d'une +seconde ou une demi seconde. Ce n'est pas très utile pour un compilateur à la +volée puisqu'il faudrait des gains de perfs supérieurs à cela.</p> +</div> +PyconFR 2015 — Cliquet2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-cliquet.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous …</p></div><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Mathieu Leplatre (&#64;leplatrem), Mozilla</p> +<p>Toolkit HTTP, pour éventuellement faire des microservices.</p> +<ol class="arabic simple"> +<li>Origines</li> +<li>Protocole</li> +<li>Toolkit</li> +<li>Conversation</li> +</ol> +<div class="section" id="origines"> +<h2>Origines</h2> +<p>Stockage de données, Cloud Services, Mozilla. +Le boulot, c'est de faire des APIs. On nous demande de faire des APIs, tout +le temps.</p> +<p>Souvent, les mêmes questions sont à l'ordre du jour. Heartbeat, codes +d'erreurs, etc. L'inventaire de tout ce qui est attendu d'une API, au dela de +ce qui est la valeur ajoutée du service.</p> +<p>Définition d'un protocole. Définir une API REST n'est pas aussi évident qu'il +y parait. Il faut définir les formats de JSON, les status, etc.</p> +<p>La réutilisation de certaines protocoles existants était possible (Sync, en +production depuis quelques années).</p> +<p>Réutiliser du code nous permettait et faire un template pour démarrer plus +facilement, pour se concentrer sur le métier de l'API. Puisque les besoins ne +sont pas toujours les mêmes, avoir une boite à outil permet de choisir ce que +l'on souhaite.</p> +</div> +<div class="section" id="protocole"> +<h2>Protocole</h2> +<ul class="simple"> +<li>Création d'un protocole qui respecte les bonnes pratiques. CORS, avoir les +bons codes de status, arrêter de se poser toujours les mêmes questions. +Contrairement à ce qu'on imagine, la spécification HTTP n'est pas si facile +à suivre. Plutôt que d'écrire un document, un toolkit à été créé.</li> +<li>Les ops ont besoin de quelques endpoints: un heartbeat (monitoring) des +endpoints de batch, un endpoint &quot;hello&quot;, pour connaitre le type de service, +ses URLs etc.</li> +<li>La service renvoie toujours un JSON avec la description de l'erreur. Cela +permet d'avoir tout le temps la même gestion des erreurs. Utilisation du +header &quot;backoff&quot; qui permet de demander aux clients d'arreter de faire des +requetes durant une durée spécifée par le serveur.</li> +<li>Pour les resources &quot;REST&quot;, quelques règles sont définies: quel est le format +du JSON, quel est la syntaxe du querystring pour filtrer, ordonner, gérer les +opérations concurentes, etc.</li> +<li>Comment la validation fonctionne ? La pagination ? La définition des +permissions ? Les erreurs.</li> +</ul> +<p>Définir le protocole une seule fois permet de se mettre d'accord avec les Ops. +On ne créé pas une RFC pour l'instant, il faut qu'on valide ce qu'on a fait, +il est necessaire de valider notre approche.</p> +</div> +<div class="section" id="toolkit"> +<h2>Toolkit</h2> +<p>La stack en place est basée sur Pyramid et Cornice. Autre chose aurait pu petre +utilisé. Mais pyramid à été choisi pour son approche simpliste et qui permet de +rajouter de la complexité au fur et à mesure.</p> +<p>Cliquet propose de faire l'ensemble du boilerplate, la lecture du protocole, et +vous permet de créer les backends souhaités.</p> +<p>Il est possible de choisir les methodes HTTP acceptables, les URLs à utiliser +etc. Tweaker l'API est possible, la chose qui reste toujouts stable est le +protocole.</p> +<p>le toolkit vise à faire quelque chose de pluggable. Tout est controllable +depuis la configuration.</p> +<p>Pour le deploiement, cela veut dire que le monitoring est déjà connecté, et il +est possible de changer la configuration depuis un fichier <cite>.ini</cite>.</p> +<p>Il est aussi possible de faire du profiling en ajoutant deux lignes de code, +qui permet de générer des graphs qui permettent d'identifier les goulots +d'étranglement.</p> +</div> +<div class="section" id="microservices"> +<h2>Microservices ?</h2> +<ul class="simple"> +<li>Cliquet apporte une manière standard de surveiller, deployer, configurer des +services.</li> +<li>Il est possible de se focaliser sur la logique de l'application, en faisait +une abstraction des backends, etc.</li> +<li>Le fait de figer l'API permet d'avoir des clients génériques que l'on peu +réutiliser d'une application à l'autre.</li> +</ul> +</div> +<div class="section" id="cliquet-est-utilise-pour"> +<h2>Cliquet est utilisé pour</h2> +<ul class="simple"> +<li>Kinto, un service générique de stpclage de données.</li> +<li>Syncto, un proxy pour Sync en utilisant le protocole.</li> +<li>La liste de lecture, service qui à été shutdown.</li> +</ul> +</div> +<div class="section" id="questions"> +<h2>Questions</h2> +<ul class="simple"> +<li><strong>Qu'est-ce qui est pluggable ?</strong> Les choix qui sont fait dans cliquet +concernent le protocole. Le toolkit est lui fait de manière &quot;pluggable&quot;. Il +est par exemple possible de changer le backend, l'authentification, le cache +ou les permissions.</li> +<li><strong>Quelles sont les parties non standard? Est-il prévu de representer ça via +une RFC ?</strong> Le seul sujet qui pourrait etre utile dans une RFC serait de +définir les headers attendus pour la validation et l'écriture +concurrentielle. L'ensemble de ce qui est proposé est standard.</li> +<li><strong>Existe-il un client JavaScript, comme pour Kinto ?</strong> Actuellement, non. Par +contre, Kinto.js est prévu pour que la partie commune entre les APIs (le +protocole) peut etre extrait.</li> +</ul> +</div> +PyconFR 2015 — Geoalchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-geoalchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: Eric Lemoine, Camp to camp. (&#64;elemoine)</p> +<p>Bibliothèque python basée sur SQL alchemy, pour interagir avec des bases de +données geographiques / spatiales.</p> +<p>Une base de donnée optimisée pour representer et rechercher des données qui +representent des objets dans un espace géométrique.</p> +<ul class="simple"> +<li>Il est possible d estocker des ligne,s de polygones, des points. Il y a une +colonne géometrie pour stocker ces données.</li> +<li>Il y a aussi des fonctions qui permettent de travailler sur ces données +(transfomrations, projections, etc).</li> +<li>Indexs géographiques qui permettent de faire des recherches de manière +performante.</li> +</ul> +<div class="section" id="postgis"> +<h2>POSTGIS</h2> +<p>POSTGIS s'appuie sur postres pour offrir des types géographiques, des fonctions +et des indexes (R-Tree), qui permettent de ranger les géométries dans des +&quot;boites englobantes&quot;.</p> +<p>Pour créer une base de données postgis, il faut faire un &quot;create extension +postgis&quot;, ce qui installe tout ce dont on a besoin.</p> +<p>il est possible d'apeller <cite>GEOMETRY(POINT)</cite> par exemple.</p> +<p><cite>ST_GeomFromText('POINT(lat long)')</cite> permet de convertir un point dans un objet +geometrie interne à postgres.</p> +<p><cite>ST_DWithin</cite> permet de trouver les personnes qui sont autour d'un rayon donné.</p> +<p>L'ensemble des fonctions proposées par postgres commencent par <cite>ST_*</cite></p> +</div> +<div class="section" id="sqlalchemy"> +<h2>SQLAlchemy</h2> +<p>Il s'agit d'une bote à outil qui permet de faire des requetes de manière +simple. Il y a une philosophie forte.</p> +<ul class="simple"> +<li>Il ne sohaite pas cacher la base de données</li> +<li>C'est un language pour faire du SQL en python</li> +<li>Rien n'est caché.</li> +<li>Fourni un vocabulaire riche pour générer le SQL</li> +<li>L'objectif est de changer la manière dont on pense à SQL, redonner le gout du +SQL aux developeurs.</li> +</ul> +<p>Deux parties: +- ORM +- CORE</p> +<p>Il est possible d'utiliser simplement le core si l'on sohaite (sans utiliser +l'ORM)</p> +<div class="section" id="core"> +<h3>Core</h3> +<p>Il est possible d'utiliser SQL Alchemy pour générer les tables à l'origine. +Core permet d'utiliser des tables, et d'executer une insertion, depuis python. +Il est possible de representer les requetes avec des methodes chainées +<cite>select().where()</cite> etc.</p> +<p>Le &quot;core&quot; ne fait pas de mapping du tout, il manipule des Tables SQLA +directement.</p> +</div> +<div class="section" id="orm"> +<h3>ORM</h3> +<p>L'ORM fait, lui, du mapping. C'est cette couche que l'on va utiliser dans une +application Web complexe par exemple.</p> +<ul class="simple"> +<li>il est possible de travailler avec une session <cite>Session()</cite> puis on effectue +des opérations et on <cite>commit()</cite>.</li> +</ul> +<div class="section" id="geoalchemy"> +<h4>GeoAlchemy</h4> +<ul class="simple"> +<li>Créé en 2009, pour supporter uniquement postgis.</li> +<li>Depuis, d'autres bases de données (MySQL, Spatialite, MySQL server) etc.</li> +<li>Réécriture depuis grace à la nouvelle API de SQLAlechemy, mais perte du +support d'autres backends.</li> +<li>Finalement, retour sur POSTGIS uniquement, pour évite d'avoir à supporter les +différences de tous les backends.</li> +</ul> +</div> +</div> +</div> +<div class="section" id="features"> +<h2>Features</h2> +<p>Très simple de s'intégrer avec les features de POSTGIS, par exemple en +déclarant une colonne en tant que &quot;Géometrie&quot;.</p> +<p>Exemple: session.query(Lake).filter(Lake.geom.ST_Buffer(2).ST_Area) permet de +lister l'ensemble des lacs avec une aire de 2 au moins.</p> +<p>S'intègre bien avec des services existants (shapely, pyramid, etc).</p> +<p>Utilisation de geojsondumps pour representer des features en geojson.</p> +</div> +<div class="section" id="status"> +<h2>Status</h2> +<p>Le projet est completement documenté sur read the docs. La documentation est +assez complete et solide. Il est intégralement testé, sur differentes versions +de python, sqlalchemy et postgres.</p> +<dl class="docutils"> +<dt>3 ou 4 developeurs actifs sur le projet, ça fonctionne plutôt bien. Pour</dt> +<dd><p class="first">contribuer, il est possible de faire cela sur github.</p> +<p class="last">Slides de la presentation sur <a class="reference external" href="http://erliem.net/talks/pyconfr2015">http://erliem.net/talks/pyconfr2015</a></p> +</dd> +</dl> +<p>Resources:</p> +<ul class="simple"> +<li><a class="reference external" href="https://pypi.python.org/pypi/Shapely">https://pypi.python.org/pypi/Shapely</a> - Manipulation and analysis of geometric +objects in the Cartesian plane.</li> +</ul> +<p>Question:</p> +<ul class="simple"> +<li>Dans les exemples geoalchemy, les données geométriques sont passées sous +forme de chaine. Est-ce normal ? Oui.</li> +<li>Les rasters sont également supportés.</li> +</ul> +</div> +PyconFR 2015 — SQL Alchemy2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-sql-alchemy.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent …</li></ul><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p>Speaker: David Allouche</p> +<p>SQL Alchemy vous permet de produire le SQL que vous voulez. Il faut que vous +souhaitiez comprendre ce que va etre produit.</p> +<p>Déclaratif:</p> +<ul class="simple"> +<li>On créé des classes qui representent nos tables, et les liaisons entre les +tables, en utilisant <cite>relationship</cite> (qui à énormement d'attributs).</li> +<li>On définit quelles osnt les clés étrangères entre les tables.</li> +<li>Puis on va définir les attributs qui sont liés entre les tables +(relationship).</li> +<li>Pour définir des relations entre les Tables, il est possible d'utiliser des +chaines de caractère <cite>relationship('OtherTable')</cite>.</li> +<li>La session es tun concept important.</li> +<li>Lire efficacement. Attention à ne pas faire énormement de requetes avec +L'ORM.</li> +</ul> +<p><strong>Performance SQL</strong></p> +<ul class="simple"> +<li>Générer le SQL (python)</li> +<li>Ne pas faire énormement de petites requetes.</li> +</ul> +<p>Il est possible de demander à la session de charger les données qui sont +associées. (avec un joinedload). Par defaut, cela risque de charger +l'ensemble des colonnes.</p> +<p>Pour la générer avec SQLAlchemy, il est possible de faire un +<cite>.query(Table).join(Table).join(Table2).filter_by(field=value)</cite></p> +<p>En pratique, le mieux est de lister clairemnet le nom des tables</p> +<p>2ème partie:</p> +<p>Pour de l'import de données,</p> +<ul class="simple"> +<li>first() fait une requete SQL. A éviter dans les boucles</li> +<li>session.flush() c'est quand la session écrit en base tout ce qui est en cours +dans la transaction. Par default, la session fait un flush avant chaque +requete.</li> +<li>une option backçpopulates mets à jour la liste des documents associés à une +table qui à une foreign key. +backref modifie implicitement la classe associée. Il est recommandé +d'utiliser <cite>back_populates</cite> et non pas <cite>backref</cite>.</li> +<li><cite>subqueryload</cite> permet de générer une requete séparée plutôt qu'une jointure.</li> +</ul> +PyconFR 2015 — Table ronde diversité2015-10-17T00:00:00+02:002015-10-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-10-17:/pyconfr-2015-table-ronde-diversite.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et …</strong></p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Voici quelques notes prises durant la PyconFR 2015, à Pau. N'hésitez pas +à les completer si besoin.</p> +</div> +<p><em>Prise de notes: Gordon et Alexis</em></p> +<p><strong>Présent·e·s: Jean Phillipe, Laurence (Directrice de l'école qui acueille la +Pycon), Amandine, Vivianne, Anna (de django carrots) + representes de django +girls bordeaux (Laurenne et Alexia).</strong></p> +<p><strong>JP — Pourquoi</strong>:On a eu une discussion sur la ML de l'AFPy suite à une décision +de l'afpy de ne pas financer un évènement qui n'était pas ouvert à tous-tes +(restreint aux femmes et personnes trans). Cette décision à été prise +conformément a la charte de l'AFPY qui dit que les evènements promus sont +ouverts à tous. Ce qui veut dire que cela n'inclue pas les évènement exclusifs. +(Je n'ai jamais demandé de financement à l'AFPY. J'ai juste demandé la +diffusion sur la mailing interne de la création de Pyladies Paris. Je ne sais +pas d'où vient cette histoire de financement! Pyladies Paris)</p> +<p>Suite à ça, une modification de la charte à été proposée. Demain matin, la +modification de la charte sera proposée lors de l'AG. Suite à la proposition de +modification, les discussions se sont enchainées, avec des points de vue +divergents. Cette table ronde vient donc dans ce contexte. +I +BD d'introduction: +<a class="reference external" href="http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/">http://www.commitstrip.com/fr/2015/09/17/meanwhile-in-a-parallel-universe-2/</a></p> +<div class="section" id="tour-de-presentation"> +<h2>Tour de présentation:</h2> +<ul class="simple"> +<li>Laurence directrice de l'école qui accueille d'évènement, docteure en Maths. +Contente de voir que la tendance s'inverse un peu (de plus en plus de filles).</li> +<li>Vivianne, maitre de conférence en informatique à paris sud. Études dans un +milieu assez masculin. Dans le domaine du developpement pour la recherche, ou +des environnements techniques, c'est très masculin. Essaye de voir comment +faire pour que les filles s'intéressent plus a l'informatique.</li> +<li>Amandine Neyrolle, diplomée d'école de commerce (plutot 50% fille/garcon dans +ces fillières). Intégrée le monde de l'informatique par la suite en autodidacte +et formations. Rencontré la créatrice de pyladies et discuté de ces questions.</li> +<li>Laurenne Chelan, organistrice des django girls bdx. Nouvelle dans cet +univers. Travaille dans des musées de science depuis quelques années. L'idée de +dj girs bdx part de l'idée de découvrir le code. Les djangogirls viennent de +berlin, créé par ???.</li> +<li>Alexia Sumois. organisatrice de django girls bdx. Nouvelle dans le milieu du +code. Les conférences d'aujourd'hui on donné envie d'apprendre.</li> +<li>Anna, créatrice de 4ideas. Essaye de faire en sorte que plus de femmes +viennent dans l'IT. En reconversion pro. Choisi ce domaine il ya un an. Trouve +que ce sujet est vraiment extremement important, et sur lequel il est possible +de faire quelque chose, et d'influencer positivement. L'idée étant de +démystifier l'IT, et laisser le choix aux femmes de choisir cette profession.</li> +<li>Jean Phillipe Campguillhem, secrétaire de l'AFPY</li> +</ul> +</div> +<div class="section" id="pourquoi-django-girls"> +<h2>Pourquoi Django Girls ?</h2> +<p><strong>Alexia</strong> — Le déclencheur de cette aventure vient des goodies (!). La décoration +de l'évènement a attiré l'attention et donné envie de creuser.</p> +<p><strong>Laurenne</strong> — C’est pour ça qu’on se pose la question « comment attirer ces +publics, ces personnes-là ? », importance de l’image qu’on renvoie. Ce n’est +pas tant une question de genre, mais d’initié·e·s : on a souvent peur d’entrer +dans ce milieu. Django-girls vise une plus grande bienveillancet Carte de la +convivialité, chaleureux, et facile d'accès pour les débutants. Tout est livré +clé en main, et l'évènement est facile à prendre en main. Le 28 oct à bordeau, +recherche de coachs / sponsors pour l'évènement. +<a class="reference external" href="http://djangogirls.com/bordeaux">http://djangogirls.com/bordeaux</a></p> +<p><strong>Laurence</strong> — Aspect macho présent dans la communication de l’école (pas +forcément explicite). « On a toujours dessiné des symboles de métiers +identifiés par des garçons »</p> +<p><strong>Laurenceu</strong> — Il y a une partie d'inconscient dans l'ensemble de +l'enseignement qui est donné. Il y a peu de candidates qui essayent. Pas +question de discrimination positive puisque cela a des effets indésirables +(communautarisme). La question est tout de meme posée, mais il est impensable +d'accepter des gens grace / a cause de leur genre. L'ambiance change lorsqu'il +y a de la mixité. À la recherche d’idées pour faire venir plus de candidates.</p> +<p><strong>Viviane</strong> — En tant que femme, on reçoit en permanence le message que ce +métier n’est pas fait pour nous. Ces messages ont un impact, le résultat est +que les filles ne vont pas dans les écoles d’informatiques. Il faut aller +convaincre les jeunes filles que c’est aussi fait pour elles. Ça passe par +changer les plaquettes. Il faut réussir à changer l'image existante des confs / +communautés. Un développeur peut aussi etre une développeuse. Dans l'assemblée, +on se rend compte que certaines femmes sont en dehors du parcours. Il faut +qu'en tant que communauté on soit capables d'accueillir les nouvelles / +nouveaux. C’est en ayant une diversité qu’on parviendra à changer l’image du +métier. Les rencontres pyladies permettent aussi de rencontrer d'autres femmes +qui ont les mêmes problématiques. Accompagner les nouvelles entrantes pour +trouver du boulot, découvrir l'AFPY et les initatives existantes. Les +initiatives existantes django girls / pyladies est très important.</p> +<p><strong>Amandine</strong> — C’est pourquoi ce genre d’évènements non-mixtes permet de faire +des séances de rattrapage pour permettre d’intégrer la communauté dans son +ensemble. C’est le point clé pour faire accepter ce genre d’initiatives.</p> +<p><strong>Laurenne</strong> — DjangoGirls et Django Carrots ne sont pas des évènements +excluants. Ils sont simplement orientés en priorité aux femmes. Sur la question +de « comment amener des jeunes filles vers ces études-là », ça se joue bien +avant, dans l’enfance, bien avant l’école. cf les jeux genrés. Il faut +travailler à ce niveau-là.</p> +<p><strong>Anna</strong> — Pour illustrer ce que dit Laurenne, l'importance des clichés +existants. Avant le mi-80s, il y avait autant de femmes que dans d'autres +domaines. Si on regarde les stats, dans tousles autres domaines, le pourcentage +de femmes augmente. Et en IT, en 84 il y a un pic qui inverse la tendance. Ce +sont des stats américaines. A priori cela s'applique aussi en Europe. En IT, la +culture qui à été créé autour des hackers qui ont des super pouvoirs, mangent +des pizzas, etc. Ces clichés ont influencé le monde. Nous ne sommes pas +complètement autonomes, et nous sommes influencés par la culture autour de +nous. Les dommages qui ont été fait dans le domaine de l'IT sont graves, et il +est important de renverser la tendance. La question de l'image est centrale. +Les personnes ont besoin de place pour faire leurs évènements. Il est important +de comprendre et respecter que les autres veuillent faire de la discrimination +positive. Ce sont des actions qui sont supportées par la France. Ce sont des +valeurs qui sont beaucoup lus fortes en France qu'ailleurs (Anna souligne +qu'elle est Polonaise). On devrait respecter ce droit.</p> +<p><strong>Vivianne</strong> — Certaines evènements sont non-mixtes (pour les personnes qui +s'identifient comme des femmes). Ce ne doit pas etre les seules initiatives. +Elle est pour la mixté. PyLadies est assez spécifique : ce n’est pas de la +formation, mais principalement des évènements tournés autour du réseau. Il est +important d'avoir un endroit ou les jeunes femmes seront moins imprésionnées. +Les situations exposées dans la BD sont réelles. De se retrouver dans un +environnement où elles sont sûres qu’elles ne subiront pas de micro-agressions.</p> +<p><strong>Laurence</strong> — Témoignage d'une mère qui dit à sa fille, en passant devant un +panneau de l'école, mentionnant maths et informatique, et qui dit à sa fille « +oh non, c'est pas pour toi ça » . On dit « attention les garçons, vous devez +être sympas avec les filles ». Les garçons ont envie que ça se passe bien avec +les filles.</p> +<p><strong>JP</strong> — Sans revenir sur les décisions qui ont été prises, nous n'avons pas +dit que nous étions contre ces évènements (à l'AFPY). A plusieurs reprises, +j'ai du faire des blagues sexistes. Évidemment qu'on est mieux ensemble. Pour +revenir sur la discussion de la mailing-list, je me suis rendu compte que +j'avais un regard biaisé. Si on en est la, c'est quil y a énormement de +travail. Que faire, du coup ? En tant qu'hommes ? Qu'association ? Si il est +necessaire de créer une zone de confort / sécurité, c'est qu'il y a une zone +d'inconfort / insécurité qui est forte. Les couleurs, les jolis goodies, sont +le sommet de l’iceberg. Rappel de l'éxistence du Code of Conduct : il y a déjà +eu des incidents par le passé. On passe la parole à Florent, qui est à +l’origine du CoC. Remerciement envers les intervenantes.</p> +<p><strong>Florent (vice secrétaire de l'AFPY)</strong> — Comme le dit JP, un code of conduct +est affiché devant toutes les portes et à l'entrée. Tout le monde n’aimait pas +forcément l’idée d’en avoir, on a fini par trancher. Le but est d’avoir des +endroits safes. Avant d’avoir un CoC, on ne peut pas dire qu’on soit safes, +envers l'ensemble des minorités. On a écrit le CoC en conséquence des +agressions. Aujourd’hui, pas de tolérance pour des comportements qui n’ont pas +lieu d’être (qu’on a définis comme tels). Ça fonctionne sur la dénonciation +lorsque l’on est témoin de ça. On n’a pas vraiment de mal à rencontrer des +femmes, mais plus de mal à faire comprendre qu’elles sont bienvenues. Impact +important de blagues sexistes, qu’on défend comme « c’est pour rire ». Merci de +lire le Code of Conduct. Les blagues sexistes etc. ne sont pas les bienvenues. +Merci de réagir lors de ces cas.</p> +</div> +<div class="section" id="questions"> +<h2>Questions.</h2> +<p><strong>Questiond de Gawel</strong>: Question pour Amandine. Est-ce que tu te sens bien à l'AFPY ? Si non, que faire pour que tu te sente mieux ?</p> +<p>Amandine — Oui je me sens bien, est-ce qu’il y a eu des évènements ? oui, sans +doute mais j’y suis aguerrie, donc je me rends peu compte. Qu’est-ce qu’on peut +faire ? L’idée du CoC est d’aller à l’encontre des comportements négatifs, mais +l’idée derrière est une ouverture à la différence dans son ensemble, promouvoir +l’ouverture à l’autre et à la différence. L’enjeu culturel est d’arriver à +changer d’état d’esprit et d’identifier ces biais cognitifs. Il faudrait pas +qu’on se dise « ho là là, il y a une fille, faut rien dire sinon je vais me +faire taper » Il faut cultiver la différence. et être curieux/se.</p> +<p><strong>Question</strong> : « c’est pas fait pour moi », mais plutôt « je suis mauvais, donc +je dois travailler », on en revient à l’importance de l’éducation. Il faut +continuer de pointer du doigt les problèmes. Je suis aussi membre d’un LUG, +nous sommes entre hommes diplomés blancs de 30 à 40 ans. La réflexion sur les +plaquettes pas accueillantes est pertinente : le site de l’asso est très +masculin.</p> +<p><strong>Question de Bruno</strong>. Pour l’école: quand j’étais étudiant, 20% de filles. +(Aujourd’hui on est partis de 7/8% pour arriver à 15%). Est-ce que les filles +réussissent plus ?</p> +<p>Laurence — on n’a pas de stats, mais elles posent moins de problèmes. Les +filles sont favorisées par les employeurs.</p> +<p>Vivianne — la motivation des filles à la sortie est identique aux garçons, mais +tout n’est pas rose. En entretien par exemple, ils sont faits par des hommes, +mais au niveau des stats, le nombre de femmes qui quittent le milieu est +important. Effort à faire au niveau de la communauté, des entreprises. Schémas +masculins, mais sur le long terme, on subit des agressions. Difficile de rester +dans le métier et faire une carrière intéressante, à compétences/motivation +identiques aux hommes. Il faut en avoir conscience</p> +<p><strong>Question de Benoit</strong>: il y a peut-être une façon de créer des +lieux/évènements protégés, en utilisant ceux qui existent déjà. Est-ce qu’on +peut aller organiser des évènements dans des écoles/lycées, des endroits où les +gens se sentent déjà à l’aise, où les populations sont plus représentées ?</p> +<p>Vivianne — ça se fait. En tant qu’enseignante, dès que j’ai une occasion, que +ce soit pour aller chercher des JF ou des étudiants maths/infos, même si c’est +ouvert à tous, je le fais. Si c’est que des hommes, les femmes n’ont pas envie +d’y aller.</p> +<p>Laurenne — c’est quelque chose qui se fait beaucoup. On met en avant des femmes +chercheuses dès qu’on le peut.</p> +<p><strong>Question d'Alexis</strong> : je suis très content qu’il y ait cette discussion qui +se fasse. Question par rapport aux discriminations positives, qu’on a pu voir +par le passé (notamment lors de conférences). Difficile de dire « on va +préférer des femmes ». Question irrésolue, parce que pour faire évoluer, on a +besoin d'initier quelque chose, d’essayer. Mais ça a un côté dérangeant.</p> +<p>Vivianne — à la PyCon (US), j’ai été impressionnée du nombre de femmes qui +parlaient. On va pas mettre un quota, ça serait stupide, on va forcer personne. +Mais il faut en avoir conscience. Cette année, on est 4 oratrices, y’a du +travail à faire. En tant qu’hommes, il faut aussi se mettre en retrait et +inviter des femmes à en parler à notre place. Faire le pas d'aller faire un +exposé dans une communauté où on ne se sent pas à sa place (même si on lutte +contre) est difficile. Inviter des gens, sans forcément passer par un énorme +processus. Ça passe par des events comme PyLadies.</p> +<p>Anna — pour les personnes par encore convaincues, juste apres le droit de vote +des femmes en 46, à l'assemblée nationale il y avait très peu de femmes. Puis +en 93, 6.1% apres que des mesures aient été prises. Ensuite de femmes puis vers +20% Les choses ne vont pas se changer toutes seules. Il est necessaire d'avoir +du temps pour faire évoluer les choses. Il est important de noter que PyconFR +fait déjà des choses. Et lors de django carrots, je me suis sentie très +accueillie. J'ai eu beaucoup de très bonnes expériences avec des personnes qui +étaient prêtes à aider.</p> +<p>JP — Remerciement pour Rémy qui abat un travail de ouf. C'est grace à Rémy si +il y a django carrots demain. Il faut faire des choses. :-) Merci !</p> +</div> + \ No newline at end of file diff --git a/feeds/tech.atom.xml b/feeds/tech.atom.xml new file mode 100644 index 0000000..e6408c8 --- /dev/null +++ b/feeds/tech.atom.xml @@ -0,0 +1,2937 @@ + +Carnets Web - techhttps://blog.notmyidea.org/2018-02-25T00:00:00+01:00Webnotes2018-02-25T00:00:00+01:002018-02-25T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-25:/webnotes.html<p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière …</p><p>Quand je navigue en ligne, j'aime bien prendre des notes sur ce que je lis. C'est utile pour les retrouver plus tard. Il existe quelques outils pour ce genre de cas, mais j'ai vraiment eu du mal à trouver un outil qui faisais ce que je voulais, de la manière que je voulais, c'est à dire:</p> +<ul> +<li>enregistrer une sélection de texte ainsi que son contexte: heure, site web.</li> +<li>fonctionner sur Firefox;</li> +<li>stocker mes notes à un endroit que je contrôle (ce sont mes données, après tout !)</li> +<li>rester en dehors de mon chemin: je suis en train de lire, pas en train d'organiser mes notes.</li> +<li>automatiquement partager les notes sur une page web.</li> +</ul> +<p>J'ai donc pris un peu de temps pour fabriquer mon outil de prises de notes, que j'ai baptisé « Webnotes ». C'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'est aussi simple que sélectionner du texte, faire « clic droit » puis « save as webnote », entrer un tag et le tour est joué !</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 !</p>Comment est-ce que vous générez vos formulaires ?2016-05-31T00:00:00+02:002016-05-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-31:/comment-est-ce-que-vous-generez-vos-formulaires.html<p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est …</em></p><p>TL; DR: Je viens à peine de <em>releaser</em> la première version d'un service de génération de formulaires. +Allez jeter un coup d'œ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'un service de génération de formulaires</a>. +Depuis, pas mal d'eau à coulé sous les ponts, on est passé par pas mal d'é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'organisateurs d'é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'est +pas libre et que les données sont stockées chez 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'ils puissent y répondre. +Je reviens ensuite plus tard pour voir la liste des réponses apportées.</p> +<p><img alt="Capture de l'interface de création du formulaire" src="{filename}/static/formbuilder-build.png"></p> +<h2>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'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 à +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'opération terminée.</p> +<p><img alt="Capture de l'écran avec les URLs générées" src="{filename}/static/formbuilder-created.png"> +<img alt="Capture d'écran d'un exemple de formulaire" src="{filename}/static/formbuilder-form.png"></p> +<h3>Pas de compte</h3> +<p>Vous n'avez pas besoin d'avoir un compte sur le site pour commencer à l'utiliser. +Vous créez simplement un nouveau formulaire puis envoyez le lien à vos amis pour +qu'eux puissent à leur tour le remplir.</p> +<p><img alt="Capture de la page d'accueil, ou aucun compte n'est requis" src="{filename}/static/formbuilder-welcome.png"></p> +<h3>Gardez la main sur vos 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="{filename}/static/formbuilder-results.png"></p> +<h3>API</h3> +<p>L'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 HTTP. Ce qui fait qu'il est très facile de +réutiliser les formulaires que vous avez construits (ou leurs réponses) depuis +d'autres outils.</p> +<h3>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'instance qui est mise à votre disposition sur +<a href="https://www.fourmilieres.net">wwww.fourmilieres.net</a>, mais vous pouvez +également l'héberger vous même très +simplement, et vous êtes d'ailleurs fortement encouragés à le faire ! Notre +objectif n'est pas de stocker l'ensemble des formulaires du monde, mais de +(re)donner le contrôle aux utilisateurs !</p> +<h2>On commence petit…</h2> +<p>Cette <em>release</em> n'est (bien sur) pas parfaite, et il reste encore pas mal de +travail sur cet outil, mais je pense qu'il s'agit d'une base de travail +intéressante pour un futur où Google n'a pas la main sur toutes nos données.</p> +<p>La liste des champs supportés est pour l'instant assez faible (Texte court, +Texte long, Oui/Non, choix dans une liste) mais elle à vocation à s'étendre, en +fonction des besoins de chacun.</p> +<p>J'ai d'ailleurs créé <a href="https://www.fourmilieres.net/#/form/cfd878264cec4ed2">un formulaire pour que vous puissiez me faire part de vos +retours</a>, n'hésitez pas !</p> +<h2>Et, euh, comment ça marche ?</h2> +<p>Le <em>formbuilder</em>, comme j'aime l'appeler se compose en fin de compte de deux +parties 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 HTTP</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'envoyer les données sur les <em>APIs</em> coté + 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'il génère en fin de compte du +<a href="http://jsonschema.net/">JSON Schema</a>, un format de validation de données <em>JSON</em>.</p> +<p>Donc, reprenons! Vous arrivez sur la page d'accueil puis cliquez sur +"Create a new form", puis vous vous retrouvez face à une interface ou vous pouvez +ajouter des champs de formulaire. Une fois ce travail effectué, vous appuyez sur +"Create the form".</p> +<ul> +<li>Le JSON Schema est alors envoyé au serveur Kinto, qui l'utilisera pour valider + les données qu'il recevra par la suite.</li> +<li>Ce JSON Schema sera aussi utilisé lors de l'affichage du formulaire aux + personnes qui le remplissent.</li> +<li>Un jeton d'accès est généré et ajouté à l'URL, il s'agit de l'identifiant du + formulaire.</li> +<li>Un second jeton d'accès administrateur et généré, il vous faut le garder de + coté pour avoir accès aux 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 !</p>What's Hawk and how to use it?2014-07-31T00:00:00+02:002014-07-31T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-31:/whats-hawk-and-how-to-use-it.html<p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original …</p><p>At Mozilla, we recently had to implement <a class="reference external" 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 apps.</p> +<p>But maybe you don't know Hawk.</p> +<p>Hawk is a relatively new technology, crafted by one of the original <a class="reference external" href="https://en.wikipedia.org/wiki/OAuth">OAuth</a> specification authors, that intends to +replace the 2-legged OAuth authentication scheme using a simpler approach.</p> +<p>It is an authentication scheme for HTTP, built around <a class="reference external" href="https://en.wikipedia.org/wiki/Hmac">HMAC digests</a> of requests and responses.</p> +<p>Every authenticated client request has an Authorization header containing a MAC +(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 +server.</p> +<div class="section" id="exchange-of-the-hawk-id-and-hawk-key"> +<h2>Exchange of the hawk id and hawk key</h2> +<p>To sign the requests, a client needs to retrieve a token id and a token key +from the 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 class="reference external" href="http://accounts.firefox.com">Firefox Accounts</a> put together a scheme to do that, which acts +like the following:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p>All this derivation crazyness might seem a bit complicated, but don't worry, +we put together some libraries that takes care of that for you automatically.</p> +<p class="last">If you are not interested into these details, you can directly jump to the +next section to see how to use the libraries.</p> +</div> +<p>When your server application needs to send you the credentials, it will return +it inside a specific <cite>Hawk-Session-Token</cite> 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 requests.</p> +<p>In order to get the hawk credentials, you'll need to:</p> +<p>First, do an <a class="reference external" href="http://en.wikipedia.org/wiki/HKDF">HKDF derivation</a> on the +given session token. You'll need to use the following parameters:</p> +<pre class="literal-block"> +key_material = HKDF(hawk_session, &quot;&quot;, 'identity.mozilla.com/picl/v1/sessionToken', 32*2) +</pre> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">The <tt class="docutils literal">identity.mozilla.com/picl/v1/sessionToken</tt> is a reference to this way of +deriving the credentials, not an actual URL.</p> +</div> +<p>Then, the key material you'll get out of the HKDF need to be separated into two +parts, the first 32 hex caracters are the hawk id, and the next 32 ones are the +hawk key.</p> +<p>Credentials:</p> +<div class="highlight"><pre><span></span><span class="nx">credentials</span> <span class="o">=</span> <span class="p">{</span> + <span class="s1">&#39;id&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">0</span><span class="o">:</span><span class="mi">32</span><span class="p">],</span> + <span class="s1">&#39;key&#39;</span><span class="o">:</span> <span class="nx">keyMaterial</span><span class="p">[</span><span class="mi">32</span><span class="o">:</span><span class="mi">64</span><span class="p">],</span> + <span class="s1">&#39;algorithm&#39;</span><span class="o">:</span> <span class="s1">&#39;sha256&#39;</span> +<span class="p">}</span> +</pre></div> +</div> +<div class="section" id="httpie"> +<h2>Httpie</h2> +<p>To showcase APIs in the documentation, I like to use <a class="reference external" href="https://github.com/jakubroztocil/httpie">httpie</a>, a curl-replacement with a nicer +API, built around <a class="reference external" 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 class="reference external" href="https://github.com/mozilla-services/requests-hawk">I wrote +a wrapper</a> around <a class="reference external" href="https://github.com/kumar303/mohawk">mohawk</a> to add hawk support to the requests lib.</p> +<p>Doing hawk requests in your terminal is now as simple as:</p> +<pre class="literal-block"> +$ pip install requests-hawk httpie +$ http GET localhost:5000/registration --auth-type=hawk --auth='id:key' +</pre> +<p>In addition, it will help you to craft requests using the requests library:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Alternatively, if you don'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 you:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +</div> +<div class="section" id="integrate-with-python-pyramid-apps"> +<h2>Integrate with python pyramid apps</h2> +<p>If you're writing pyramid applications, you'll be happy to learn that <a class="reference external" 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'm chocked how simple it +is to use it.</p> +<p>Here is a demo of how we implemented it for Daybed:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>The <cite>get_hawk_id</cite> function is a function that takes a request and +a tokenid and returns a tuple of <cite>(token_id, token_key)</cite>.</p> +<p>How you want to store the tokens and retrieve them is up to you. The default +implementation (e.g. if you don't pass a <cite>decode_hawk_id</cite> function) decodes the +key from the token itself, using a master secret on the server (so you don't +need to store anything).</p> +</div> +<div class="section" id="integrate-with-node-js-express-apps"> +<h2>Integrate with node.js Express 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 class="reference external" href="https://github.com/mozilla-services/express-hawkauth">express-hawkauth</a>.</p> +<p>In order to plug it in your application, you'll need to use it as +a middleware:</p> +<div class="highlight"><pre><span></span><span class="kd">var</span> <span class="nx">express</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express&quot;</span><span class="p">);</span> +<span class="kd">var</span> <span class="nx">hawk</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s2">&quot;express-hawkauth&quot;</span><span class="p">);</span> +<span class="nx">app</span> <span class="o">=</span> <span class="nx">express</span><span class="p">();</span> + +<span class="kd">var</span> <span class="nx">hawkMiddleware</span> <span class="o">=</span> <span class="nx">hawk</span><span class="p">.</span><span class="nx">getMiddleware</span><span class="p">({</span> + <span class="nx">hawkOptions</span><span class="o">:</span> <span class="p">{},</span> + <span class="nx">getSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which pass to the cb the key and algorithm for the</span> + <span class="c1">// given token id. First argument of the callback is a potential</span> + <span class="c1">// error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">,</span> <span class="p">{</span><span class="nx">key</span><span class="o">:</span> <span class="s2">&quot;key&quot;</span><span class="p">,</span> <span class="nx">algorithm</span><span class="o">:</span> <span class="s2">&quot;sha256&quot;</span><span class="p">});</span> + <span class="p">},</span> + <span class="nx">createSession</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">id</span><span class="p">,</span> <span class="nx">key</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function which stores a session for the given id and key.</span> + <span class="c1">// Argument returned is a potential error.</span> + <span class="nx">cb</span><span class="p">(</span><span class="kc">null</span><span class="p">);</span> + <span class="p">},</span> + <span class="nx">setUser</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">req</span><span class="p">,</span> <span class="nx">res</span><span class="p">,</span> <span class="nx">tokenId</span><span class="p">,</span> <span class="nx">cb</span><span class="p">)</span> <span class="p">{</span> + <span class="c1">// A function that uses req and res, the hawkId when they&#39;re known so</span> + <span class="c1">// that it can tweak it. For instance, you can store the tokenId as the</span> + <span class="c1">// user.</span> + <span class="nx">req</span><span class="p">.</span><span class="nx">user</span> <span class="o">=</span> <span class="nx">tokenId</span><span class="p">;</span> + <span class="p">}</span> +<span class="p">});</span> + +<span class="nx">app</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;/hawk-enabled-endpoint&quot;</span><span class="p">,</span> <span class="nx">hawkMiddleware</span><span class="p">);</span> +</pre></div> +<p>If you pass the <cite>createSession</cite> parameter, all non-authenticated requests will +create a new hawk session and return it with the response, in the +<cite>Hawk-Session-Token</cite> 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't have any <cite>createSession</cite> parameter +defined.</p> +</div> +<div class="section" id="some-reference-implementations"> +<h2>Some reference implementations</h2> +<p>As a reference, here is how we're using the libraries I'm talking about, in +case that helps you to integrate with your projects.</p> +<ul class="simple"> +<li>The Mozilla Loop server <a class="reference external" href="https://github.com/mozilla-services/loop-server/blob/master/loop/index.js#L70-L133">uses hawk as authentication once you're logged in with +a valid BrowserID assertion</a>; +request, to keep a session between client and server;</li> +<li><a class="reference external" href="https://github.com/spiral-project/daybed/commit/f178b4e43015fa077430798dcd3d0886c7611caf">I recently added hawk support on the Daybed project</a> +(that's a pyramid / cornice) app.</li> +<li>It's also interesting to note that Kumar put together <a class="reference external" href="http://hawkrest.readthedocs.org/en/latest/">hawkrest, for the +django rest framework</a></li> +</ul> +</div> +New year python meme, 20122013-07-01T00:00:00+02:002013-07-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-07-01:/new-year-python-meme-2012.html<p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this …</p><p>This series, also known as &quot;<a class="reference external" href="http://ziade.org">Tarek Ziadé</a> strikes again&quot;, +is a good occasion to take a look back at 2012 and see what I've done related +to python. So, let's try.</p> +<p><strong>1. What’s the coolest Python application, framework or library you have +discovered in 2012 ?</strong></p> +<p>I discovered <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">Pyramid</a> this year and +quite enjoyed it. I like the way they bring back some nice concepts on the +table, and how they compete with other frameworks. That's nicely decomposed and +everything fits together really well. I learned a bit about its internal +routing mechanism when working on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, and +it's really well done.</p> +<p><strong>2. What new programming technique did you learn in 2012 ?</strong></p> +<p>I learned about asynchronous programming, something I wasn't really aware of. +(Yes, that's a shame). This was really helpful to understand some bits of +<a class="reference external" href="http://circus.io">Circus</a>. I also started to learn about some related +concepts present in <a class="reference external" href="http://golang.org">go</a> or in <a class="reference external" href="http://erlang.org">erlang</a> with <a class="reference external" href="http://en.wikipedia.org/wiki/Actor_model">the actor model</a></p> +<p><strong>3. Which open source project did you contribute to the most in 2012 ? What did +you do ?</strong></p> +<p>I worked a bunch on <a class="reference external" href="http://cornice.rtfd.org">Cornice</a> and <a class="reference external" href="http://circus.io">Circus</a>, not as much as I would like, but that was two really +interesting projects. For Cornice, I completely <a class="reference external" href="http://blog.notmyidea.org/refactoring-cornice.html">refactored the internals</a> back in May, and since +that, I added support for <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a> +and am currently working on porting it to Python 3 and adding support for <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>. For Circus, I worked on the web interface and +on other bits of the projects related to stats.</p> +<p>I didn't contributed that much to <a class="reference external" href="http://getpelican.com">Pelican</a>, mainly +because I'm less excited about it than I was previously: the project is +working and needs to focus more on code quality than features. We started in +this direction, hopefully it will pay-off; but I committed a lot less code than +previously.</p> +<p><strong>4. Which Python blog or website did you read the most in 2012 ?</strong></p> +<p>I really don't know. I found some interesting python-related news on <a class="reference external" href="http://news.ycombinator.com/">hacker +news</a> and on the printed version as well, +<a class="reference external" href="http://hackermonthly.com/">hacker monthly</a>. Twitter and IRC got me some +interesting articles as well.</p> +<p><strong>5. What are the three top things you want to learn in 2013 ?</strong></p> +<p>On the computer science side, I want to learn more about other paradigms, maybe +in other languages. I like python, but I want to learn about other concepts, +maybe some of them don't really fit with python.</p> +<p>For instance, I don't know that much about pattern matching or about the actor +model. Well I know what it is, but I would like to make good use of them in +order to have something nice and useful.</p> +<p>Also, I want to learn how to make a product. From scratch. Which means +designing, implementing and maintaining something. Maybe this will be the case +with <a class="reference external" href="https://github.com/spiral-project/daybed">daybed</a> ? Who knows.</p> +<p>I want to get better at building communities. Working with others is something +that can be complex and quite hard sometimes. I want to learn how to handle +this better.</p> +<p>On the other side, I want to learn about tons of other non-tech things: taking +pictures, finding a good balance between life and work, working with children, +teaching and animating workshops, writing articles, be better at reading (being +critic when I'm thinking!).</p> +<p><strong>6. What is the top software, application or library you wish someone would +write in 2013 ?</strong></p> +<p>The one missing thing, IMO, is a <strong>good</strong> webmail reader, in python. One we +could contribute to, one we could write features for, and one that could come +and compete with gmail, in term of features of UI.</p> +<p>However, most of the time, I'm just impressed by the new ideas that come from +others. I would like to have a library to handle the actor model in a nice way +in Python, I would like to see packaging fixed in python :-)</p> +<p>Want to do your own list? Here's how:</p> +<ul class="simple"> +<li>copy-paste the questions and answer to them in your blog</li> +<li>tweet it with the #2012pythonmeme hashtag</li> +</ul> +Implementing CORS in Cornice2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/cross-origin-in-cornice.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">I'm cross-posting <a class="reference external" href="https://blog.mozilla.org/services/">on the mozilla services weblog</a>. Since this is the +first time we'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.</p> +</div> +<p>For security reasons, it's not possible to do cross-domain requests. In other +words, if you have a page served from the domain <cite>lolnet.org</cite>, it will not be +possible for it to get data from <cite>notmyidea.org</cite>.</p> +<p>Well, it's possible, using tricks and techniques like <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a>, but that doesn't work all the time (see +<a class="reference external" 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's API.</p> +<p>Thankfully, there is a nicer way to do this, namely, &quot;Cross Origin +Resource-Sharing&quot;, or <a class="reference external" href="http://www.w3.org/TR/cors/">CORS</a>.</p> +<div class="section" id="you-want-an-icecream-go-ask-your-dad-first"> +<h2>You want an icecream? Go ask your dad first.</h2> +<p>If you want to use CORS, you need the API you're querying to support it; on the +server side.</p> +<p>The HTTP server need to answer to the <cite>OPTIONS</cite> verb, and with the appropriate +response headers.</p> +<p><cite>OPTIONS</cite> is sent as what the authors of the spec call a &quot;preflight request&quot;; +just before doing a request to the API, the <em>User-Agent</em> (the browser most of +the time) asks the permission to the resource, with an <cite>OPTIONS</cite> call.</p> +<p>The server answers, and tell what is available and what isn't:</p> +<img alt="The CORS flow (from the HTML5 CORS tutorial)" src="images/cors_flow.png" /> +<ul class="simple"> +<li>1a. The User-Agent, rather than doing the call directly, asks the server, the +API, the permission to do the request. It does so with the following headers:<ul> +<li><strong>Access-Control-Request-Headers</strong>, contains the headers the User-Agent +want to access.</li> +<li><strong>Access-Control-Request-Method</strong> contains the method the User-Agent want +to access.</li> +</ul> +</li> +<li>1b. The API answers what is authorized:<ul> +<li><strong>Access-Control-Allow-Origin</strong> the origin that's accepted. Can be <cite>*</cite> or +the domain 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 methods.</li> +<li><strong>Access-Allow-Headers</strong> a list of allowed headers, for all of the +methods, since this can be cached as well.</li> +</ul> +</li> +<li><ol class="first arabic" start="2"> +<li>The User-Agent can do the &quot;normal&quot; request.</li> +</ol> +</li> +</ul> +<p>So, if you want to access the <cite>/icecream</cite> resource, and do a PUT there, you'll +have the following flow:</p> +<pre class="literal-block"> +&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 +</pre> +<p>You can see that we have an <cite>Origin</cite> Header in the request, as well as +a <cite>Access-Control-Request-Methods</cite>. We're here asking if we have the right, as +<cite>notmyidea.org</cite>, to do a <cite>PUT</cite> request on <cite>/icecream</cite>.</p> +<p>And the server tells us that we can do that, as well as <cite>GET</cite> and <cite>DELETE</cite>.</p> +<p>I'll not cover all the details of the CORS specification here, but bear in mind +than with CORS, you can control what are the authorized methods, headers, +origins, and if the client is allowed to send authentication information or +not.</p> +</div> +<div class="section" id="a-word-about-security"> +<h2>A word about security</h2> +<p>CORS 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 CORS, so you'll need to +write a proxy yourself, to provide this.</p> +<p>Secondly, if misunderstood, CORS 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're authorizing.</p> +<p>An incorrectly secured CORS 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 VPN 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 want.</p> +</div> +<div class="section" id="how-this-is-different-from-jsonp"> +<h2>How this is different from JSONP?</h2> +<p>You may know the <a class="reference external" href="http://en.wikipedia.org/wiki/JSONP">JSONP</a> protocol. JSONP +allows cross origin, but for a particular use case, and does have some +drawbacks (for instance, it's not possible to do DELETEs or PUTs with JSONP).</p> +<p>JSONP exploits the fact that it is possible to get information from another domain +when you are asking for javascript code, using the <cite>&lt;script&gt;</cite> element.</p> +<blockquote> +Exploiting the open policy for &lt;script&gt; elements, some pages use them to +retrieve JavaScript code that operates on dynamically generated +JSON-formatted data from other origins. This usage pattern is known as +JSONP. Requests for JSONP retrieve not JSON, but arbitrary JavaScript code. +They are evaluated by the JavaScript interpreter, not parsed by a JSON +parser.</blockquote> +</div> +<div class="section" id="using-cors-in-cornice"> +<h2>Using CORS in Cornice</h2> +<p>Okay, things are hopefully clearer about CORS, let's see how we +implemented it on the 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 CORS support as +well.</p> +<p>In Cornice, you define a service like this:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>To add CORS support to this resource, you can go this way, with the +<cite>cors_origins</cite> parameter:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> +</pre></div> +<p>Ta-da! You have enabled CORS for your service. <strong>Be aware that you're +authorizing anyone to query your server, that may not be what you want.</strong></p> +<p>Of course, you can specify a list of origins you trust, and you don't need +to stick with <cite>*</cite>, which means &quot;authorize everyone&quot;.</p> +<div class="section" id="headers"> +<h3>Headers</h3> +<p>You can define the headers you want to expose for the service:</p> +<div class="highlight"><pre><span></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_origins</span><span class="o">=</span><span class="p">(</span><span class="s1">&#39;*&#39;</span><span class="p">,))</span> + +<span class="nd">@foobar.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> +</pre></div> +<p>I've done some testing and it wasn't working on Chrome because I wasn't +handling the headers the right way (The missing one was <cite>Content-Type</cite>, 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 developing.</p> +<p>So I introduced an <cite>expose_all_headers</cite> flag, which is set to <cite>True</cite> by +default, if the service supports CORS.</p> +</div> +<div class="section" id="cookies-credentials"> +<h3>Cookies / Credentials</h3> +<p>By default, the requests you do to your API endpoint don't include the +credential information for security reasons. If you really want to do that, +you need to enable it using the <cite>cors_credentials</cite> parameter. You can activate +this one on a per-service basis or on a per-method basis.</p> +</div> +<div class="section" id="caching"> +<h3>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's not redone before each actual call.</p> +<p>The caching period is defined by the server, using the <cite>Access-Control-Max-Age</cite> +header. You can configure this timing using the <cite>cors_max_age</cite> parameter.</p> +</div> +<div class="section" id="simplifying-the-api"> +<h3>Simplifying the API</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 CORS-policy for your services, that +can be a bit tedious to pass these to your services all the time.</p> +<p>I introduced another way to pass the CORS policy, so you can do something like +that:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">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> +</pre></div> +</div> +</div> +<div class="section" id="comparison-with-other-implementations"> +<h2>Comparison with other implementations</h2> +<p>I was curious to have a look at other implementations of CORS, in +django for instance, and I found <a class="reference external" href="https://gist.github.com/426829.js">a gist about it</a>.</p> +<p>Basically, this adds a middleware that adds the &quot;rights&quot; headers to the answer, +depending on the request.</p> +<p>While this approach works, it's not implementing the specification completely. +You need to add support for all the resources at once.</p> +<p>We can think about a nice way to implement this specifying a definition of what's +supposed to be exposed via CORS and what shouldn't directly in your settings. +In my opinion, CORS support should be handled at the service definition level, +except for the list of authorized hosts. +Otherwise, you don't know exactly what's going on when you look at the definition of the service.</p> +</div> +<div class="section" id="resources"> +<h2>Resources</h2> +<p>There are a number of good resources that can be useful to you if you want to +either understand how CORS works, or if you want to implement it yourself.</p> +<ul class="simple"> +<li><a class="reference external" href="http://enable-cors.org/">http://enable-cors.org/</a> is useful to get started when you don't know anything +about CORS.</li> +<li>There is a W3C wiki page containing information that may be useful about +clients, common pitfalls etc: <a class="reference external" href="http://www.w3.org/wiki/CORS_Enabled">http://www.w3.org/wiki/CORS_Enabled</a></li> +<li><em>HTML5 rocks</em> has a tutorial explaining how to implement CORS, with <a class="reference external" 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 class="reference external" href="http://caniuse.com/#search=cors">clients support-matrix for this feature</a>.</li> +<li>About security, <a class="reference external" href="https://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity">check out this page</a></li> +<li>If you want to have a look at the implementation code, check <a class="reference external" href="https://github.com/mozilla-services/cornice/pull/98/files">on github</a></li> +</ul> +<p>Of course, the W3C specification is the best resource to rely on. This +specification isn't hard to read, so you may want to go through it. Especially +the <a class="reference external" href="http://www.w3.org/TR/cors/#resource-processing-model">&quot;resource processing model&quot; section</a></p> +</div> +Status board2012-12-29T00:00:00+01:002012-12-29T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-12-29:/status-board-fr.html<p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org …</cite></p><p>À force de démarrer des services web pour un oui et pour un non, de proposer +à des copains d'héberger leurs sites, de faire pareil pour quelques assos etc, +je me suis retrouvé avec, comme dirait l'autre, <em>une bonne platrée</em> de sites et +de services à gérer sur <cite>lolnet.org</cite>, mon serveur.</p> +<p>Jusqu'à très récemment, rien de tout ça n'était sauvegardé, et non plus monitoré. +Après quelques recherches, je suis tombé sur <a class="reference external" href="http://www.stashboard.org/">stashboard</a>, un &quot;status board&quot; qu'il est bien fait. Le seul +problème, c'est écrit pour se lancer sur GAE, <em>Google App Engine</em>. +Heureusement, c'est open-source, et ça a été forké pour donner naissance +à <a class="reference external" href="https://github.com/bfirsh/whiskerboard">whiskerboard</a> (la planche +moustachue, pour les non anglophones).</p> +<img alt="Capture d'écran du site." src="images/status_board.png" /> +<div class="section" id="verifier-le-statut-des-services"> +<h2>Vérifier le statut des services</h2> +<p>Donc, c'est chouette, c'est facile à installer, tout ça, mais… mais ça ne fait +en fait pas ce que je veux: ça ne fait que m'afficher le statut des services, +mais ça ne vérifie pas que tout est bien &quot;up&quot;.</p> +<p>Bon, un peu embêtant pour moi, parce que c'est vraiment ça que je voulais. Pas +grave, je sais un peu coder, autant que ça serve. J'ai ajouté quelques +fonctionnalités au soft, qui sont disponibles sur mon fork, sur +github:: <a class="reference external" href="https://github.com/ametaireau/whiskerboard">https://github.com/ametaireau/whiskerboard</a> .</p> +<p>Entres autres, il est désormais possible de lancer <a class="reference external" 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 spécifique.</p> +<p>C'é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 dépote).</p> +<p>Les modifications sont assez simples, vous pouvez aller jeter un œil aux +changements ici: +<a class="reference external" href="https://github.com/ametaireau/whiskerboard/compare/b539337416...master">https://github.com/ametaireau/whiskerboard/compare/b539337416...master</a></p> +<p>En gros:</p> +<ul class="simple"> +<li>ajout d'une <cite>connection_string</cite> aux services (de la forme +protocol://host:port)</li> +<li>ajout d'une commande <cite>check_status</cite> qui s'occupe d'itérer sur les services et +de lancer des taches celery qui vont bien, en fonction du protocole</li> +<li>ajout des taches en question</li> +</ul> +</div> +<div class="section" id="deploiement"> +<h2>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, forcément.</p> +<p>Après un essai (plutôt rapide en fait) sur <a class="reference external" href="http://heroku.com">heroku</a>, je me +suis rendu compte qu'il me fallait payer pas loin de 35$ par mois pour avoir un +process <cite>celeryd</cite> qui tourne, donc j'ai un peu cherché ailleurs, pour +finalement déployer la chose chez <a class="reference external" href="https://www.alwaysdata.com/">alwaysdata</a></p> +<p>Après quelques péripéties, j'ai réussi à faire tourner le tout, ça à été un peu +la bataille au départ pour installer virtualenv (j'ai du faire des changements +dans mon <cite>PATH</cite> pour que ça puisse marcher), voici mon <cite>.bash_profile</cite>:</p> +<pre class="literal-block"> +export PYTHONPATH=~/modules/ +export PATH=$HOME/modules/bin:$HOME/modules/:$PATH +</pre> +<p>Et après y'a plus qu'à installer avec <cite>easy_install</cite>:</p> +<pre class="literal-block"> +easy_install --install-dir ~/modules -U pip +easy_install --install-dir ~/modules -U virtualenv +</pre> +<p>Et à créer le virtualenv:</p> +<pre class="literal-block"> +virtualenv venv +venv/bin/pip install -r requirements.txt +</pre> +<p>Dernière étape, la création d'un fichier <cite>application.wsgi</cite> qui s'occupe de +rendre l'application disponible, avec le bon venv:</p> +<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">os</span> +<span class="kn">import</span> <span class="nn">sys</span> + +<span class="n">activate_this</span> <span class="o">=</span> <span class="s1">&#39;/home/lolnet/venv/bin/activate_this.</span> +<span class="nb">execfile</span><span class="p">(</span><span class="n">activate_this</span><span class="p">,</span> <span class="nb">dict</span><span class="p">(</span><span class="vm">__file__</span><span class="o">=</span><span class="n">activate_this</span><span class="p">))</span> + +<span class="n">paths</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;/home/lolnet/public&#39;</span><span class="p">,]</span> + +<span class="k">for</span> <span class="n">path</span> <span class="ow">in</span> <span class="n">paths</span><span class="p">:</span> + <span class="k">if</span> <span class="n">path</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="p">:</span> + <span class="n">sys</span><span class="o">.</span><span class="n">path</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">path</span><span class="p">)</span> + + <span class="kn">import</span> <span class="nn">django.core.handlers.wsgi</span> + <span class="n">os</span><span class="o">.</span><span class="n">environ</span><span class="p">[</span><span class="s1">&#39;DJANGO_SETTINGS_MODULE&#39;</span><span class="p">]</span> <span class="o">=</span> <span class="s1">&#39;settings&#39;</span> + <span class="n">application</span> <span class="o">=</span> <span class="n">django</span><span class="o">.</span><span class="n">core</span><span class="o">.</span><span class="n">handlers</span><span class="o">.</span><span class="n">wsgi</span><span class="o">.</span><span class="n">WSGIHandler</span><span class="p">()</span> +</pre></div> +</div> +<div class="section" id="ssl-et-requests"> +<h2>SSL et Requests</h2> +<p>Quelques tours de manivelle plus loin, j'ai un celeryd qui tourne et qui +consomme les taches qui lui sont envoyées (pour des questions de simplicité, +j'ai utilisé le backend <cite>django</cite> de celery, donc pas besoin d'AMQP, par +exemple).</p> +<p>Problème, les ressources que je vérifie en SSL (HTTPS) me jettent. Je sais pas +exactement pourquoi à l'heure qu'il est, mais il semble que lorsque je fais une +requête avec <a class="reference external" 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 <cite>CURL</cite> fonctionnent, donc j'ai fait <a class="reference external" href="https://github.com/ametaireau/whiskerboard/blob/master/board/tasks.py#L17">un fallback +vers CURL lorsque les autres méthodes échouent</a>. +Pas super propre, mais ça fonctionne.</p> +<p><strong>EDIT</strong> Finalement, il se trouve que mon serveur était mal configuré. +J'utilisais haproxy + stunnel, et la négiciation SSL se passait mal. Une fois +SSL et TLS activés, et SSLv2 désactivé, tout fonctionne mieux.</p> +</div> +<div class="section" id="et-voila"> +<h2>Et voilà</h2> +<p>Finalement, j'ai mon joli status-board qui tourne à merveille sur +<a class="reference external" href="http://status.lolnet.org">http://status.lolnet.org</a> :-)</p> +</div> +Gnome 3, extensions2012-12-27T00:00:00+01:002012-12-27T00:00:00+01:00Alexis Métaireautag: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'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial …</a></li></ul><p>Après avoir tenté pendant un bout de temps unity, le bureau par defaut de +ubuntu, j'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.</p> +<p>Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.</p> +<ul class="simple"> +<li><a class="reference external" href="https://extensions.gnome.org/extension/547/antisocial-menu/">Antisocial Menu</a> vire les +boutons et textes en rapport avec le web social. J'en avais pas besoin +puisque je suis connecté à mon instant messenger dans un terminal, en +utilisant weechat.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/97/coverflow-alt-tab/">Coverflow Alt-Tab</a> change le +switcher d'applications par defaut. Je le trouve bien plus pratique que celui +par defaut puisqu'il me permet de voir &quot;en grand&quot; quelle est la fenêtre que +je vais afficher.</li> +<li><a class="reference external" 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'intègre niquel avec +Spotify, et ça c'est chouette.</li> +<li><a class="reference external" href="https://extensions.gnome.org/extension/149/search-firefox-bookmarks-provider/">Rechercher dans les bookmarks firefox</a> +permet de… à votre avis ?</li> +</ul> +<p>Un peu moins utile mais sait on jamais:</p> +<ul class="simple"> +<li>“<a class="reference external" href="https://extensions.gnome.org/extension/130/advanced-settings-in-usermenu/">Advanced Settings in UserMenu</a>” +permet d'avoir un raccourci vers les paramètres avancés dans le menu +utilisateur (en haut à droite)</li> +<li>Une <a class="reference external" href="https://extensions.gnome.org/extension/409/gtg-integration/">intégration à Getting things Gnome</a> (un truc de +GTD). Je suis en train d'expérimenter avec cet outil, donc je ne sais pas +encore si ça va rester, mais pourquoi pas.</li> +</ul> +<p>Vous pouvez aller faire un tour sur <a class="reference external" href="https://extensions.gnome.org/">https://extensions.gnome.org/</a> +pour en trouver d'autres à votre gout.</p> +Cheese & code - Wrap-up2012-10-22T00:00:00+02:002012-10-22T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-10-22:/cheese-code-wrap-up.html<p>This week-end I hosted a <em>cheese &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 &amp; code</em> session in the country-side of Angers, +France.</p> +<p>We were a bunch of python hackers and it rained a lot, wich forced us to stay +inside and to code. 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 well.</p> +<p>Here is a summary of what we worked on:</p> +<div class="section" id="daybed"> +<h2>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 REST web service, in python, and open +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're using <strong>CouchDB</strong> as a backend.</p> +<img alt="Daybed is a big couch!" src="images/daybed.jpg" style="width: 400px;" /> +<p>We mainly hacked on daybed and are pretty close to the release of the first +version, meaning that we have something working.</p> +<p><a class="reference external" href="http://github.com/spiral-project/daybed">The code</a> is available on github, +and we also wrote <a class="reference external" href="http://daybed.rtfd.org">a small documentation</a> for 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'm pretty confidend that we now have really good basis for this project.</p> +<p>Also, we will have a nice todolist application, with the backend <strong>and</strong> the +frontend, in javascript / html / css, you'll know more when it'll be ready :-)</p> +<p>Once we have something good enough, we'll release the first version and I'll +host it somewhere so that people can play with it.</p> +</div> +<div class="section" id="cornice"> +<h2>Cornice</h2> +<p>Daybed is built on top of <a class="reference external" href="http://cornice.rtfd.org">Cornice</a>, a framework to +ease the creation of web-services.</p> +<p>At Pycon France, we had the opportunity to attend a good presentation about <a class="reference external" href="https://github.com/SPORE/specifications">SPORE</a>. SPORE is a way to describe your +REST web services, as WSDL is for WS-* services. This allows to ease the +creation of generic SPORE clients, which are able to consume any REST API with +a SPORE endpoint.</p> +<p>Here is how you can let cornice describe your web service for you</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>And you'll get a definition of your service, in SPORE, available at <cite>/spore</cite>.</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, etc.</p> +<p>I released today <a class="reference external" href="http://crate.io/packages/cornice/">Cornice 0.11</a>, which adds +into other things the support for SPORE, plus some other fixes we found on our +way.</p> +</div> +<div class="section" id="respire"> +<h2>Respire</h2> +<p>Once you have the description of the service, you can do generic clients +consuming them!</p> +<p>We first wanted to contribute to <a class="reference external" href="https://github.com/bl0b/spyre">spyre</a> but +it was written in a way that wasn't supporting to <cite>POST</cite> data, and they +were using their own stack to handle HTTP. A lot of code that already exists in +other libraries.</p> +<p>While waiting the train with <a class="reference external" href="http://natim.ionyse.com/">Rémy</a>, we hacked +something together, named &quot;Respire&quot;, a thin layer on top of the awesome +<a class="reference external" href="http://python-requests.org">Requests</a> 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're still hacking on it so it may break +(for the better), but that had been working pretty well for us so far.</p> +<p>You can <a class="reference external" 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 daybed)</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>Finally, we were out of cheese so everyone headed back to their respective +houses and cities.</p> +<p>Until next time?</p> +</div> +Cheese & Code party: October 20-212012-09-20T00:00:00+02:002012-09-20T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-20:/afpy-computer-camp-october-20-21.html<p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing …</p><p>At PyconFR, this week-end, a few ideas were thrown in the air and one of them +was to have a /dev/fort doing some python-related coding.</p> +<p>The concept of a /dev/fort is to put a bunch of hackers together and see what +comes out from it. Tarek is doing something related with the Afpy Computer +Camps at his house each year, I've been there twice and it really was a nice +experience.</p> +<p>At Djangocong 2012, in Montpellier (south of France), <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu Leplatre</a> and myself started to work on a model +validation and storage service, named <a class="reference external" href="https://github.com/spiral-project/daybed/">Daybed</a>.</p> +<p>I've talked about this project to some persons this week-end (I've even done <a class="reference external" href="http://alexis.notmyidea.org/lightning-daybed.html">a +lightning talk</a> about it) +and it gathered some interest from people in the python community, so we +thought about sprinting on this.</p> +<div class="section" id="and-21-october-a-computer-camp"> +<h2>20 and 21 October - A Computer Camp !</h2> +<p>Add to this a few beers, and the sprint turns magically into a camp. We'll be +sprinting at the end of October (the 20 and 21) near Angers, on daybed.</p> +<p>We plan to have great food and wine, so if you feel like it and if you want to +come and work on some python-related things, you're invited!</p> +<p>Although, I can host a limited number of persons, so you'll need to contact me +before :), that's <cite>alexis at notmyidea dot org</cite>.</p> +<p>I've setup a wiki page to organize a bit everything (knowing how many people will +come by will allow me to handle things better), please put information there:</p> +<p><a class="reference external" href="http://wiki.python.org/moin/ComputerCampAlexis">http://wiki.python.org/moin/ComputerCampAlexis</a></p> +</div> +Circus sprint at PyconFR2012-09-17T00:00:00+02:002012-09-17T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-09-17:/circus-sprint-at-pyconfr.html<p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're …</p><p>Last Thursday to Sunday, <a class="reference external" 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 general.</p> +<p>We had three tracks this year, plus sprints the two first days. We sprinted on +<a class="reference external" href="http://circus.io">Circus</a>, the process and socket manager we're using +at Mozilla for some of our 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 features.</p> +<p>Having people wanting to sprint on our projects is exciting because that's +when making things in the open unleashes its full potential. You can't imagine +how happy I was to have some friends come and work on this with us :)</p> +<p>Here is a wrap-up of the sprint:</p> +<div class="section" id="autocompletion-on-the-command-line"> +<h2>Autocompletion on the command-line</h2> +<p><a class="reference external" 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're using bash. It seems that not that much work is needed to +make it happen on zsh as well :)</p> +<p><a class="reference external" href="https://github.com/mozilla-services/circus/blob/master/extras/circusctl_bash_completion">Have a look at the feature</a></p> +<p>On the same topic, we now have a cool shell for Circus. If you start the +<cite>circusctl</cite> command without any option, you'll end-up with a cool shell. Thanks +<a class="reference external" href="https://github.com/jojax">Jonathan Dorival</a> for the work on this! You can +have a look at <a class="reference external" href="https://github.com/mozilla-services/circus/pull/268">the pull request</a>.</p> +</div> +<div class="section" id="future-changes-to-the-web-ui"> +<h2>Future changes to the web ui</h2> +<p><a class="reference external" 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'm glad of this. +Currently, it's done with bottle.py and we want to switch to 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 instance.</p> +</div> +<div class="section" id="bug-and-doc-fixing"> +<h2>Bug and doc fixing</h2> +<p>While reading the source code, we found some inconsistencies and fixed them, +with <a class="reference external" href="http://mathieu.agopian.info/">Mathieu Agopian</a>. We also tried to +improve the documentation at different levels.</p> +<p>Documentation still needs a lot of love, and I'm planning to spend some time on +this shortly. I've gathered a bunch of feedback on this</p> +</div> +<div class="section" id="circus-clustering-capabilities"> +<h2>Circus clustering 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 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 be.</p> +<p>Remy wrote <a class="reference external" href="http://tech.novapost.fr/circus-clustering-management-en.html">a good summary about our brainstorming</a> so I'll not do +it again here, but feel free to contact us if you have ideas on this, they're +very welcome!</p> +</div> +<div class="section" id="project-management"> +<h2>Project management</h2> +<p>We've had some inquiries telling us that's not as easy as it should to get +started with the Circus project. Some of the reasons are that we don't +have any release schedule, and that the documentation is hairy enough to lost +people, at some point :)</p> +<p>That's something we'll try to fix soon :)</p> +<p>PyconFR was a very enjoyable event. I'm looking forward to meet the community +again and discuss how Circus can evolve in ways that are interesting to +everyone.</p> +<p>Tarek and me are going to <a class="reference external" href="http://python.ie/pycon/2012/">Pycon ireland</a>, feel +free to reach us if you're going there, we'll be happy to meet and enjoy beers!</p> +</div> +Refactoring Cornice2012-05-14T00:00:00+02:002012-05-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-05-14:/refactoring-cornice.html<p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" href="http://docs.pylonsproject.org/en/latest/docs/pyramid.html">pyramid</a> routing system, +allowing to register services in …</p><p>After working for a while with <a class="reference external" href="http://cornice.readthedocs.com">Cornice</a> to +define our APIs at <a class="reference external" href="http://docs.services.mozilla.com">Services</a>, it turned +out that the current implementation wasn't flexible enough to allow us to do +what we wanted to do.</p> +<p>Cornice started as a toolkit on top of the <a class="reference external" 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 HTTP headers <a class="reference external" href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">as defined by the HTTP specification</a> without the need +from the developer to deal with them nor to know them.</p> +<p>If you're not familiar with Cornice, here is how you define a simple service +with it:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>This external API is quite cool, as it allows to do a bunch of things quite +easily. For instance, we've written our <a class="reference external" href="https://github.com/mozilla-services/tokenserver">token-server</a> code on top of this in a +blast.</p> +<div class="section" id="the-burden"> +<h2>The 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 internally.</p> +<p>The API of the <cite>cornice.service.Service</cite> class was as following (simplified so +you can get the gist of it).</p> +<div class="highlight"><pre><span></span><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="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="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> +</pre></div> +<p>I encourage you to go read <a class="reference external" 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 done.</p> +<p>A bunch of things are wrong:</p> +<ul class="simple"> +<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 <cite>get_drink</cite>, you will instead get a decorator which +contains this view.</li> +<li>second, we are using decorators as APIs we expose. Even if decorators are +good as shortcuts, they shouldn't be the default way to deal with an API. A +good example of this is <a class="reference external" href="https://github.com/mozilla-services/cornice/blob/4e0392a2ae137b6a11690459bcafd7325e86fa9e/cornice/resource.py#L56">how the resource module consumes this API</a>. +This is quite hard to follow.</li> +<li>Third, in the <cite>api</cite> 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 API.</li> +</ul> +</div> +<div class="section" id="how-do-we-improve-this"> +<h2>How do we improve this?</h2> +<p>Python is great because it allows you to refactor things in an easy way. What I +did isn'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 API that much.</p> +<p>Here is the gist of the new architecture:</p> +<div class="highlight"><pre><span></span><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="bp">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="bp">None</span><span class="p">):</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="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="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> +</pre></div> +<p>So, the service is now only storing the information that'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 +<cite>register_service_views</cite> and has the following signature:</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>To sum up, here are the changes I made:</p> +<ol class="arabic simple"> +<li>Service description is now separated from the route registration.</li> +<li><cite>cornice.service.Service</cite> now provides a <cite>hook_view</cite> method, which is not a +decorator. decorators are still present but they are optional (you don't +need to use them if you don't want to).</li> +<li>Everything has been decoupled as much as possible, meaning that you really +can use the <cite>Service</cite> class as a container of information about the services +you are describing. This is especially useful when generating 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. <cite>cornice.services.Service</cite> 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 system.</p> +<p>However, no integration with other frameworks is done at the moment even if the +design allows it.</p> +<p>The same way, the sphinx description layer is now only a consumer of this +service description tool: it looks at what's described and build-up the +documentation from it.</p> +<p>The resulting branch is not merged yet. Still, you can <a class="reference external" 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 :-)</p> +</div> +Thoughts about a form generation service, GIS enabled2012-02-04T00:00:00+01:002012-02-04T00:00:00+01:00Alexis Métaireau, Mathieu Leplatretag:blog.notmyidea.org,2012-02-04:/carto-forms.html<p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of it.</p> +<p>This idea has been stuck …</p><p>We have a plan. A &quot;fucking good&quot; 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't +explicitly ask that but that's the gist of 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've named it +<em>carto-forms</em> for now, but that's only the &quot;codename&quot;.</p> +<p>To put it shortly: what if we had a way to build forms, ala Google forms, but +with geographic information in them?</p> +<p>If you don't know Google forms, it means having an user-friendly way to build +forms and to use them to gather information from different users.</p> +<p>In my opinion, Google forms is missing two important things: first, it's not +open-source, so it's not possible to hack it or even to run it on your own +server. Second, it doesn't really know how to deal with geographic data, and +there is no way to filter the information more than in a spreadsheet.</p> +<p>I knew that <a class="reference external" href="http://blog.mathieu-leplatre.info/">Mathieu</a> and some folks at <a class="reference external" href="http://makina-corpus.com">Makina Corpus</a> would be interested +in this, so I started a discussion with him on IRC and we refined the details +of the project and its objectives.</p> +<p>Imagine the following:</p> +<ol class="arabic simple"> +<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) ;</li> +<li>In situ, users fill the form fields with what they see. Geo fields can be +pre-populated using device geolocation ;</li> +<li>At the end of the day, we can see a map with all user contributions seized +through this particular form ;</li> +<li>If relevant, a script could eventually import the resulting dataset and +publish/merge with OpenStreetMap.</li> +</ol> +<div class="section" id="some-use-cases"> +<h2>Some use cases</h2> +<p>I can see some use cases for this. The first one is a collaborative map, with +facet filtering. Let's draw a potential user flow:</p> +<ul> +<li><p class="first">An &quot;administrator&quot; goes to the website and creates a form to list all the +alternative-related events. He creates the following fields:</p> +<ul class="simple"> +<li>Name: a plain text field containing the name of the event.</li> +<li>Category: the category of the event. Can be a finite list.</li> +<li>Location: The location of the event. It could be provided by selecting a +point on a map or by typing an address.</li> +<li>Date: the date of the event (a datepicker could do the 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 etc)</p> +</li> +<li><p class="first">Once finished, the form is generated and the user gets an url (say +<a class="reference external" href="http://forms.notmyidea.org/alternatives">http://forms.notmyidea.org/alternatives</a>) for it.</p> +</li> +<li><p class="first">REST APIs allow third parties to get the form description and to +push/edit/get information from there.</p> +</li> +<li><p class="first">He can communicate the address in any way he wants to his community so they +can go to the page and add information to it.</p> +</li> +<li><p class="first">Then, it is possible to filter the results per location / date or category. +This can be done via API calls (useful for third parties) or via a nice +interface in the browser.</p> +</li> +</ul> +<p>So, as you may have noticed, this would allow us to create interactive maps really +easily. It's almost just a matter of some clicks to the users. If we also come +up with a nice Web API for this, we could do server-side validation and build +even phone applications 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 clients.</p> +<p>As mentioned before, the idea of a simple tool to support collaborative mapping +fullfils a recurring necessity !</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'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 class="reference external" href="http://fixmystreet.ca">http://fixmystreet.ca</a>), +geocaching, trajectories (e.g hiking, runners, cyclists)...</p> +<p>Here are some other examples of where <em>carto-forms</em> could be useful:</p> +<div class="section" id="simple-gis-storage-backend"> +<h3>Simple GIS storage backend</h3> +<p>Let's say you are a mobile developer, you don't want to bother with PostGIS +nor write a custom and insecure code to insert and retrieve your GIS data! You +need carto-forms! A simple API helps you design your models/forms and the +same API allows you to CRUD and query your data. Thus, you only need to focus +on your application, not on how GIS data will be handled.</p> +<p>We make a distinction between storage and widgets.</p> +<p>Besides, if you are a django / drupal / plomino... maintainer : you +can develop a module to &quot;plug&quot; your models (content types) and UI to carto-forms! +Carto forms are then exposed to your backoffice users (ex: drupal admin UI, django +adminsite), and likewise you can write your own HTML widgets that consume datasets +in frontend views (facets in JSON/XML, and map data in GeoJSON).</p> +</div> +<div class="section" id="visualization-tool"> +<h3>Visualization tool</h3> +<p>Since data submission can be done programmatically using the API, you could use Carto-forms +results page as a visualization 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're in +front of a decision support system!</p> +<p>Of course, filtered raw data can be downloaded (GeoJSON, XML) and a permalink allows to +share the page with the state of the filters and the zoom/location of the map.</p> +</div> +<div class="section" id="generic-forms-service"> +<h3>Generic forms service</h3> +<p>If you want to generate a configuration file (or whatever, email messages, ...), +you will need a form and a template to inlay user submitted values and get the result.</p> +<p>A form service would be really useful to create forms programmatically and retrieve +cleaned and validated input 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 result).</p> +<p>Note that for this use-case, there is no specific need of GIS data nor storage of records +for further retrieval.</p> +</div> +</div> +<div class="section" id="what-s-out-in-the-wild-already"> +<h2>What's out in the wild already?</h2> +<p>Of course, there is Google forms, which allows you to do these kind of things, +but it's closed and not exactly what we are describing here.</p> +<p>We've discovered the interesting <a class="reference external" 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't handle APIs and +geolocation information.</p> +<p>The idea of <a class="reference external" href="http://thoth.io">http://thoth.io</a> is very attractive : an extremely simple web API to store +and retrieve data. In addition, <em>carto-forms</em> would do datatype validation and have +basic GIS fields (point, line, polygon).</p> +<p><a class="reference external" href="http://mapbox.com">http://mapbox.com</a> also did an awesome work on cartography, but didn't take into +account the form aspect we're leveraging here.</p> +</div> +<div class="section" id="so-let-s-get-it-real"> +<h2>So… Let's get it real!</h2> +<p>As you may have understood, this isn't a really complicated problem. We have +been sometimes chatting about that with Mathieu about what we would need and +how we could achieve this.</p> +<p>We can probably come with an elegant solution without too much pain. Mathieu is +used to work with GIS systems (which is really cool because I'm not at all) and +knows his subject, so that's an opportunity to learn ;-)</p> +<p>We will be at <a class="reference external" 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 join!</p> +<p>We don'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 welcome!</p> +<p>Here is the etherpad document we worked on so far: +<a class="reference external" href="http://framapad.org/carto-forms">http://framapad.org/carto-forms</a>. Don't hesitate to add your thoughts and edit +it, that's what it's made for!</p> +<p>Thanks to <a class="reference external" href="http://sneakernet.fr/">Arnaud</a> and <a class="reference external" href="http://qwerty.fuzz.me.uk/">Fuzzmz</a> for proof-reading and typo fixing.</p> +</div> +Using JPype to bridge python and Java2011-11-06T00:00:00+01:002011-11-06T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-11-06:/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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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 HTML pages, like menus, footers and other &quot;boilerplate&quot; +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, 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 VM level. This means you need to start a VM +from your python script, but it does the job and stay fully compatible with +Cpython and its C extensions.</p> +<div class="section" id="first-steps-with-jpype"> +<h2>First steps with JPype</h2> +<p>Once JPype installed (you'll have to hack a bit some files to integrate +seamlessly with your system) you can access java classes by doing something +like that:</p> +<div class="highlight"><pre><span></span><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> +</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 them.</p> +</div> +<div class="section" id="interfacing-with-boilerpipe"> +<h2>Interfacing with Boilerpipe</h2> +<p>To install boilerpipe, you just have to run an ant script:</p> +<pre class="literal-block"> +$ cd boilerpipe +$ ant +</pre> +<p>Here is a simple example of how to use boilerpipe in Java, from their sources</p> +<div class="highlight"><pre><span></span><span class="kn">package</span> <span class="nn">de.l3s.boilerpipe.demo</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">java.net.URL</span><span class="o">;</span> +<span class="kn">import</span> <span class="nn">de.l3s.boilerpipe.extractors.ArticleExtractor</span><span class="o">;</span> + +<span class="kd">public</span> <span class="kd">class</span> <span class="nc">Oneliner</span> <span class="o">{</span> + <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="kd">final</span> <span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="kd">throws</span> <span class="n">Exception</span> <span class="o">{</span> + <span class="kd">final</span> <span class="n">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="n">URL</span><span class="o">(</span><span class="s">&quot;http://notmyidea.org&quot;</span><span class="o">);</span> + <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="n">ArticleExtractor</span><span class="o">.</span><span class="na">INSTANCE</span><span class="o">.</span><span class="na">getText</span><span class="o">(</span><span class="n">url</span><span class="o">));</span> + <span class="o">}</span> +<span class="o">}</span> +</pre></div> +<p>To run it:</p> +<div class="highlight"><pre><span></span>$ javac -cp dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar src/demo/de/l3s/boilerpipe/demo/Oneliner.java +$ java -cp src/demo:dist/boilerpipe-1.1-dev.jar:lib/nekohtml-1.9.13.jar:lib/xerces-2.9.1.jar de.l3s.boilerpipe.demo.Oneliner +</pre></div> +<p>Yes, this is kind of ugly, sorry for your eyes. +Let's try something similar, but from python</p> +<div class="highlight"><pre><span></span><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="k">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> +</pre></div> +<p>And you get what you want.</p> +<p>I must say I didn'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, nice!</p> +</div> +How are you handling your shared expenses?2011-10-15T00:00:00+02:002011-10-15T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-15:/how-are-you-handling-your-shared-expenses.html<p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 …</p><p><strong>TL;DR:</strong> We're kick-starting a new application to manage your shared +expenses. Have a look at <a class="reference external" 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 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 come.</p> +<p>I said yes and gave it some more thoughts: We probably aren'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, boooh!).</p> +<p>I then discussed with a friend of mine, who was excited about it and wanted to learn +python. Great! That'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 class="reference external" href="http://www.sneakernet.fr/">Arnaud</a> and Quentin!)</p> +<p>Since that, the project now support multiple languages and provides a REST API +(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's it (this was inspired by +doodle)!</p> +<img alt="Capture d'écran du site." src="images/ihatemoney.png" /> +<p>You can try the project at <a class="reference external" href="http://ihatemoney.notmyidea.org">http://ihatemoney.notmyidea.org</a> for now, and the +code lives at <a class="reference external" href="https://github.com/spiral-project/ihatemoney/">https://github.com/spiral-project/ihatemoney/</a>.</p> +<div class="section" id="features"> +<h2>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 once.</p> +<p>No, I don'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 way.</p> +<div class="section" id="no-user-registration"> +<h3>No user registration</h3> +<p>You don'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 you).</p> +</div> +<div class="section" id="keeping-things-simple"> +<h3>Keeping things simple</h3> +<p>&quot;Keep It Simple, Stupid&quot; 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're back from the +farmer's market on raw paper.</p> +</div> +<div class="section" id="no-categories"> +<h3>No categories</h3> +<p>Some people like to organise their stuff into different &quot;categories&quot;: +leisure, work, eating, etc. That's not something I want (at least to begin +with).</p> +<p>I want things to be simple. Got that? Great. Just add your bills!</p> +</div> +<div class="section" id="balance"> +<h3>Balance</h3> +<p>One of the most useful thing is to know what's your &quot;balance&quot; compared to +others. In other words, if you're negative, you owe money, if you'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 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 balance.</p> +</div> +<div class="section" id="api"> +<h3>API</h3> +<p>All of what's possible to do with the standard web interface is also available +through a REST API. I developed a simple REST toolkit for flask for this (and +I should release it!).</p> +</div> +</div> +<div class="section" id="interested"> +<h2>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't hesitate +a second! The project lives at <a class="reference external" href="http://github.com/spiral-project/ihatemoney/">http://github.com/spiral-project/ihatemoney/</a></p> +</div> +Using dbpedia to get languages influences2011-08-16T00:00:00+02:002011-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-08-16:/using-dbpedia-to-get-languages-influences.html<p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 …</p><p>While browsing the Python's wikipedia page, I found information about the languages +influenced by python, and the languages that influenced python itself.</p> +<p>Well, that'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 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 technologies.</p> +<p>Well, you may have guessed it, the project in question in dbpedia, and exposes +information in the form of RDF triples, which are way more easy to work with +than simple HTML.</p> +<p>For instance, let's take the page about python: +<a class="reference external" 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 &quot;Influenced&quot; and &quot;InfluencedBy&quot;, 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 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 &quot;( +programming language)&quot;, which is the case for python.</p> +<p>So I've built <a class="reference external" 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 graphviz.</p> +<p>After a nice:</p> +<pre class="literal-block"> +$ python get_influences.py python dot | dot -Tpng &gt; influences.png +</pre> +<p>The result is the following graph (<a class="reference external" href="http://files.lolnet.org/alexis/influences.png">see it directly here</a>)</p> +<img alt="Graph des influances des langages les uns sur les autres." src="http://files.lolnet.org/alexis/influences.png" style="width: 800px;" /> +<p>While reading this diagram, keep in mind that it is a) not listing all the +languages and b) keeping a python 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 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 readable.</p> +<p>You can find the script <a class="reference external" href="https://github.com/ametaireau/experiments">on my github account</a>. Feel free to adapt it for +whatever you want if you feel hackish.</p> +Pelican, 9 months later2011-07-25T00:00:00+02:002011-07-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-25:/pelican-9-months-later.html<p>Back in October, I released <a class="reference external" 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 class="reference external" 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 github.</p> +<p>And people started contributing. I wasn'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 requests.</p> +<p><strong>Which is clearly 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 fun.</p> +<p>Thank you, guys, you're why I like open source so much.</p> +Introducing Cornice2011-07-12T00:00:00+02:002011-07-12T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-07-12:/introducing-cornice.html<p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of …</p><p>Wow, already my third working day at Mozilla. Since Monday, I've been working with +<a class="reference external" href="http://ziade.org">Tarek Ziadé</a>, on a pyramid REST-ish toolkit named <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>.</p> +<p>Its goal is to take care for you of what you're usually missing so you can +focus on what's important. Cornice provides you facilities +for validation of any kind.</p> +<p>The goal is to simplify your work, but we don't want to reinvent the wheel, so +it is easily pluggable with validations frameworks, such as <a class="reference external" href="http://docs.pylonsproject.org/projects/colander/en/latest/">Colander</a>.</p> +<div class="section" id="handling-errors-and-validation"> +<h2>Handling errors and validation</h2> +<p>Here is how it works:</p> +<div class="highlight"><pre><span></span><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.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> +</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 future)</p> +<p>As you might have seen, <cite>request.errors.add</cite> 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 &quot;body&quot;, +&quot;query&quot;, &quot;headers&quot; or &quot;path&quot;. <strong>name</strong> is the name of the variable causing +problem, if any, and <strong>description</strong> contains a more detailed message.</p> +<p>Let's run this simple service and send some queries to it:</p> +<pre class="literal-block"> +$ curl -v http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: */* +&gt; +* HTTP 1.0, assume close after body +&lt; HTTP/1.0 400 Bad Request +&lt; Content-Type: application/json; charset=UTF-8 +[{&quot;location&quot;: &quot;query&quot;, &quot;name&quot;: &quot;awesome&quot;, &quot;description&quot;: &quot;You lack awesomeness!&quot;} +</pre> +<p>I've removed the extra clutter from the curl's output, but you got the general idea.</p> +<p>The content returned is in JSON, and I know exactly what I have to do: add an +&quot;awesome&quot; parameter in my query. Let's do it again:</p> +<pre class="literal-block"> +$ curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;yay!&quot;} +</pre> +<p>Validators can also convert parts of the request and store the converted value +in <cite>request.validated</cite>. It is a standard dict automatically attached to the +requests.</p> +<p>For instance, in our validator, we can chose to validate the parameter passed +and use it in the body of the webservice:</p> +<div class="highlight"><pre><span></span><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.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> +</pre></div> +<p>The output would look like this:</p> +<pre class="literal-block"> +curl http://127.0.0.1:5000/service?awesome=yeah +{&quot;test&quot;: &quot;awesome yeah&quot;} +</pre> +</div> +<div class="section" id="dealing-with-accept-headers"> +<h2>Dealing with &quot;Accept&quot; headers</h2> +<p>The HTTP spec defines a <strong>Accept</strong> header the client can send so the response +is encoded the right way. A resource, available at an URL, can be available in +different formats. This is especially true for web services.</p> +<p>Cornice can help you dealing with this. The services you define can tell which +<cite>Content-Type</cite> values they can deal with and this will be checked against the +<strong>Accept</strong> headers sent by the client.</p> +<p>Let's refine a bit our previous example, by specifying which content-types are +supported, using the <cite>accept</cite> parameter:</p> +<div class="highlight"><pre><span></span><span class="nd">@service.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> +</pre></div> +<p>Now, if you specifically ask for XML, Cornice will throw a 406 with the list of +accepted <cite>Content-Type</cite> values:</p> +<pre class="literal-block"> +$ curl -vH &quot;Accept: application/xml&quot; http://127.0.0.1:5000/service +&gt; GET /service HTTP/1.1 +&gt; Host: 127.0.0.1:5000 +&gt; Accept: application/xml +&gt; +&lt; HTTP/1.0 406 Not Acceptable +&lt; Content-Type: application/json; charset=UTF-8 +&lt; Content-Length: 33 +&lt; +[&quot;application/json&quot;, &quot;text/json&quot;] +</pre> +</div> +<div class="section" id="building-your-documentation-automatically"> +<h2>Building your documentation 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 API in your docs.</p> +<div class="highlight"><pre><span></span><span class="p">..</span> <span class="ow">services</span><span class="p">::</span> + <span class="nc">:package:</span> <span class="nf">coolapp</span> + <span class="nc">:service:</span> <span class="nf">quote</span> +</pre></div> +<p>Here is an example of what a generated page looks like: <a class="reference external" href="http://packages.python.org/cornice/exampledoc.html">http://packages.python.org/cornice/exampledoc.html</a></p> +</div> +<div class="section" id="yay-how-can-i-get-it"> +<h2>Yay! How can I get it?</h2> +<p>We just cut a 0.4 release, so it's available at <a class="reference external" href="http://pypi.python.org/pypi/cornice">http://pypi.python.org/pypi/cornice</a> +You can install it easily using <cite>pip</cite>, for instance:</p> +<pre class="literal-block"> +$ pip install cornice +</pre> +<p>You can also have a look at the documentation at +<a class="reference external" href="http://packages.python.org/cornice/">http://packages.python.org/cornice/</a></p> +</div> +<div class="section" id="what-s-next"> +<h2>What's 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 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 class="reference external" href="https://github.com/mozilla-services/cornice">go grab them on github</a> +, commit and send us a pull request!</p> +</div> +Un coup de main pour mon mémoire!2011-05-25T00:00:00+02:002011-05-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-25:/un-coup-de-main-pour-mon-memoire-fr.html<p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de main.</p> +<p>Mon mémoire porte sur les systèmes de recommandation. Pour ceux qui connaissent +last.fm, je …</p><p>Ça y est, bientôt la fin. LA FIN. La fin des études, et le début du reste. +En attendant je bosse sur mon mémoire de fin d'études et j'aurais besoin d'un petit +coup de 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'avis des personnes qui +ont des profils similaires au votre.</p> +<p>Le projet est loin d'ê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 &quot;tournée +générale&quot;).</p> +<p>J'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'enverra des +information sur les sites que vous visitez (si vous avez l'habitude d'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'un simple clic si vous souhaitez garder votre vie privée privée ;-)</p> +<p>Le site est par là: <a class="reference external" 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'est 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 correctement.</p> +<p>Merci pour votre aide !</p> +Analyse users' browsing context to build up a web recommender2011-04-01T00:00:00+02:002011-04-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-04-01:/analyse-users-browsing-context-to-build-up-a-web-recommender.html<p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full …</p><p>No, this is not an april's fool ;)</p> +<p>Wow, it'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'll be working full time on my dissertation topic.</p> +<p>When I learned we'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's the good time to learn.</p> +<p>Since a long time, I'm being impressed by the <a class="reference external" href="http://last.fm">last.fm</a> +recommender system. They're <em>scrobbling</em> the music I listen to since something +like 5 years now and the recommendations they're doing are really nice and +accurate (I discovered <strong>a lot</strong> of great artists listening to the +&quot;neighbour radio&quot;.) (by the way, <a class="reference external" href="http://lastfm.com/user/akounet/">here is</a> +my lastfm account)</p> +<p>So I decided to work on recommender systems, to better understand what is it +about.</p> +<p>Recommender systems are usually used to increase the sales of products +(like Amazon.com does) which is not really what I'm looking for (The one who +know me a bit know I'm kind of sick about all this consumerism going on).</p> +<p>Actually, the most simple thing I thought of was the web: I'm browsing it quite +every day and each time new content appears. I've stopped to follow <a class="reference external" 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 class="reference external" href="http://twitter.com/ametaireau/">on +twitter</a>.</p> +<p>Too much information kills the 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're probably not interested by the same topics at different +times of the day, or depending on the computer you're using. We can also +probably make good use of the way you browse to create groups into the content +you're browsing (or even use the great firefox4 tab group feature).</p> +<p>There is a large part of concerns to have about user's privacy as well.</p> +<p>Here is my proposal (copy/pasted from the one I had to do for my master)</p> +<div class="section" id="introduction-and-rationale"> +<h2>Introduction and 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 articles.</p> +<p>A lot of people share the same interest to various topics, and the quantity of +information is such than it'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 perspective.</p> +<p>Machine learning is a branch of Artificial Intelligence (AI) 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 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'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 else.</p> +<p>Page contents are also interesting to analyse, because that'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 etc.)</p> +<p>The goal of this dissertation is to create a recommender system for web links, +including this context 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 system.</p> +</div> +<div class="section" id="background-review"> +<h2>Background 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 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's +browsers.</p> +<div class="section" id="data-preparation-and-extraction"> +<h3>Data preparation and 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 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, 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, 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 HTML pages so there is a need of tools to recognise 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 &quot;liked&quot; a resource, and +determine a mark for it, which can be used by information filtering a later +step (T. Segaran, 2007).</p> +<p>At this stage, structuring the data is required. Storing this kind of +information in RDBMS 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 querying.</p> +</div> +<div class="section" id="information-filtering"> +<h3>Information filtering</h3> +<p>To filter the information, three techniques can be used (Balabanovic et +Al, 1997):</p> +<ul class="simple"> +<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's about +establishing a profile for the user and compare new items against 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 to.</li> +<li>the hybrid approach, which appeared recently combine both of the previous +approaches, giving recommendations when items score high regarding user's +profile, or if a similar user already liked 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, 2007).</p> +<p>References:</p> +<ul class="simple"> +<li>Balabanović, M., &amp; Shoham, Y. (1997). Fab: content-based, collaborative +recommendation. Communications of the ACM, 40(3), 66–72. ACM. +Retrieved March 1, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp">http://portal.acm.org/citation.cfm?id=245108.245124&amp;amp</a>;.</li> +<li>Berners-Lee, T., Hendler, J., &amp; Lassila, O. (2001). +The semantic web: Scientific american. Scientific American, 284(5), 34–43. +Retrieved November 21, 2010, from <a class="reference external" href="http://www.citeulike.org/group/222/article/1176986">http://www.citeulike.org/group/222/article/1176986</a>.</li> +<li>Castellano, G., Fanelli, A., &amp; Torsello, M. (2007). +LODAP: a LOg DAta Preprocessor for mining Web browsing patterns. Proceedings of the 6th Conference on 6th WSEAS Int. Conf. on Artificial Intelligence, Knowledge Engineering and Data Bases-Volume 6 (p. 12–17). World Scientific and Engineering Academy and Society (WSEAS). Retrieved March 8, 2011, from <a class="reference external" 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., &amp; Nejdl, W. (2010). Boilerplate detection using shallow text features. Proceedings of the third ACM international conference on Web search and data mining (p. 441–450). ACM. Retrieved March 8, 2011, from <a class="reference external" href="http://portal.acm.org/citation.cfm?id=1718542">http://portal.acm.org/citation.cfm?id=1718542</a>.</li> +<li>Myatt, G. J. (2007). Making Sense of Data: A Practical Guide to Exploratory +Data Analysis and Data Mining.</li> +<li>Segaran, T. (2007). Collective Intelligence.</li> +</ul> +</div> +</div> +<div class="section" id="privacy"> +<h2>Privacy</h2> +<p>The first thing that's come to people minds when it comes to process their +browsing data is privacy. People don't want to be stalked. That's perfectly +right, and I don't either.</p> +<p>But such a system don't have to deal with people identities. It's completely +possible to process completely anonymous data, and that's probably what I'm +gonna 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 !</p> +</div> +<div class="section" id="what-s-the-plan"> +<h2>What's the plan ?</h2> +<p>There is a lot of different things to explore, especially because I'm +a complete novice in that field.</p> +<ul class="simple"> +<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 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 db?</li> +<li>Process the data using well known recommendation algorithms. Compare the +results and criticize their value.</li> +</ul> +<p>There is plenty of stuff I want to try during this experimentation:</p> +<ul class="simple"> +<li>I want to try using Geshi to visualize the connexion between the links, +and the contexts</li> +<li>Try using graph databases such as Neo4j</li> +<li>Having a deeper look at tools such as scikit.learn (a machine learning +toolkit in python)</li> +<li>Analyse web pages in order to categorize them. Processing their +contents as well, to do some keyword based classification will be done.</li> +</ul> +<p>Lot of work on its way, yay !</p> +</div> +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:00Alexis Métaireautag: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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time …</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'm not on my computer.</p> +<p>Since I use vim to code, and spend most of my time in a console while +developing, it's possible to work via ssh, from everywhere.</p> +<p>The only problem is the synchronisation of the source code, config files etc. +from my machine to the server.</p> +<p>Unison provides an interesting way to synchronise two folders, even over +a network. So let's do it !</p> +<div class="section" id="creating-the-jail"> +<h2>Creating the jail</h2> +<p>In case you don't use FreeBSD, you can skip this section.</p> +<div class="highlight"><pre><span></span><span class="c1"># I have a flavour jail named default</span> +$ ezjail-admin -f default workspace.notmyidea.org <span class="m">172</span>.19.1.6 +$ ezjail-admin start workspace.notmyidea.org +</pre></div> +<p>In my case, because the &quot;default&quot; flavour contains already a lot of interesting +things, my jail come already setup with ssh, bash and vim for instance, but +maybe you'll need it in your 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 <cite>/etc/pf.conf</cite>:</p> +<pre class="literal-block"> +workspace_jail=&quot;172.19.1.6&quot; +rdr on $ext_if proto tcp from any to $ext_ip port 20006 -&gt; $workspace_jail port 22 +</pre> +<p>Reload packet filter rules</p> +<div class="highlight"><pre><span></span>$ /etc/rc.d/pf reload +</pre></div> +</div> +<div class="section" id="working-with-unison"> +<h2>Working with unison</h2> +<p>Now that we'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 it</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> +$ make -C /usr/ports/net/unison-nox11 config-recursive +$ make -C /usr/ports/net/unison-nox11 package-recursive +</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 2.32.52.</p> +<p>Check that unison is installed and reachable via ssh from your machine</p> +<div class="highlight"><pre><span></span>$ ssh notmyidea.org -p <span class="m">20006</span> unison -version +unison version <span class="m">2</span>.27.157 +$ unison -version +unison version <span class="m">2</span>.27.57 +</pre></div> +</div> +<div class="section" id="let-sync-our-folders"> +<h2>Let sync our folders</h2> +<p>The first thing I want to sync is my vim configuration. Well, it's already <a class="reference external" href="http://github.com/ametaireau/dotfiles/">in +a git repository</a> but let's try to use +unison for it right now.</p> +<p>I have two machines then: <cite>workspace</cite>, the jail, and <cite>ecureuil</cite> my laptop.</p> +<div class="highlight"><pre><span></span>unison .vim ssh://notmyidea.org:20006/.vim +unison .vimrc ssh://notmyidea.org:20006/.vimrc +</pre></div> +<p>It is also possible to put all the informations in a config file, and then to +only run <cite>unison</cite>. (fire up <cite>vim ~/.unison/default.prf</cite>.</p> +<p>Here is my config:</p> +<pre class="literal-block"> +root = /home/alexis +root = ssh://notmyidea.org:20006 + +path = .vimrc +path = dotfiles +path = dev + +follow = Name * +</pre> +<p>My vimrc is in fact a symbolic link on my laptop, but I don't want to specify +each of the links to unison. That's why the <cite>follow = Name *</cite> is 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 2GB in 20mn ;)</p> +</div> +<div class="section" id="run-the-script-frequently"> +<h2>Run the script 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've wrote a tiny script to get some +feedback from the sync:</p> +<div class="highlight"><pre><span></span><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="bp">True</span> + <span class="n">error</span> <span class="o">=</span> <span class="bp">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; {0}&#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="bp">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 {0}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 {2} &quot;{0}&quot; &quot;{1}&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> +</pre></div> +<p>This is probably perfectible, but that does the job.</p> +<p>Last step is to tell you machine to run that frequently. That's what <cite>crontab</cite> +is made for, so let's <cite>crontab -e</cite>:</p> +<pre class="literal-block"> +$ * */3 * * * . ~/.Xdbus; /usr/bin/python /home/alexis/dev/python/unison-syncer/sync.py +</pre> +<p>The <cite>~/.Xdbus</cite> allows cron to communicate with your X11 session. Here is its +content.</p> +<div class="highlight"><pre><span></span><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 -u <span class="nv">$LOGNAME</span> -n 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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$nautilus_pid</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">exit</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="k">$(</span>tr <span class="s1">&#39;\0&#39;</span> <span class="s1">&#39;\n&#39;</span> &lt; /proc/<span class="nv">$nautilus_pid</span>/environ <span class="p">|</span> grep <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="o">[</span> -z <span class="s2">&quot;</span><span class="nv">$DBUS_SESSION_BUS_ADDRESS</span><span class="s2">&quot;</span> <span class="o">]</span><span class="p">;</span> <span class="k">then</span> +<span class="nb">echo</span> <span class="s2">&quot;Failed to find bus address&quot;</span> &gt;<span class="p">&amp;</span><span class="m">2</span> +<span class="nb">exit</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> DBUS_SESSION_BUS_ADDRESS +</pre></div> +<p>And it comes from <a class="reference external" 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 developments.</p> +</div> +Wrap up of the distutils2 paris' sprint2011-02-08T00:00:00+01:002011-02-08T00:00:00+01:00Alexis Métaireautag: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've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what …</p><p>Finally, thanks to a bunch of people that helped me to pay my train and bus +tickets, I've made it to paris for the distutils2 sprint.</p> +<p>They have been a bit more than 10 people to come during the sprint, and it was +very productive. Here's a taste of what we've been working on:</p> +<ul class="simple"> +<li>the <cite>datafiles</cite>, a way to specify and to handle the installation of files which +are not python-related (pictures, manpages and so on).</li> +<li><cite>mkgcfg</cite>, a tool to help you to create a setup.cfg in minutes (and with funny +examples)</li> +<li>converters from setup.py scripts. We do now have a piece of code which +reads your current <cite>setup.py</cite> file and fill in some fields in the <cite>setup.cfg</cite> +for you.</li> +<li>a compatibility layer for distutils1, so it can read the <cite>setup.cfg</cite> you will +wrote for distutils2 :-)</li> +<li>the uninstaller, so it's now possible to uninstall what have been installed +by distutils2 (see PEP 376)</li> +<li>the installer, and the setuptools compatibility layer, which will allow you +to rely on setuptools' based distributions (and there are plenty of them!)</li> +<li>The compilers, so they are more flexible than they were. Since that'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 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 use.</p> +<p>I'm really pleased to see how newcomers went trough the code, and started +hacking so fast. I must say it wasn't the case when we started to work on +distutils1 so that's a very good point: people now can hack the code quicker +than they could 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 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 +bears^Wbeers.</p> +<p>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 :-)</p> +PyPI on CouchDB2011-01-20T00:00:00+01:002011-01-20T00:00:00+01:00Alexis Métaireautag: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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +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 &quot;simple&quot; API. The simple +API is not so simple to use as the name suggest, and have several existing +drawbacks.</p> +<p>Basically, if you want to use informations coming from the simple API, you will +have to parse web pages manually, to extract informations using some black +vodoo magic. Badly, magic have a price, and it's sometimes impossible to get +exactly the informations you want to get from this index. That's the technique +currently being used by distutils2, setuptools and pip.</p> +<p>On the other side, while XML/RPC is working fine, it'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's important to point out that, even if +PyPI have a mirroring infrastructure, it's only for the so-called <em>simple</em> API, +and not for the XML/RPC.</p> +<div class="section" id="couchdb"> +<h2>CouchDB</h2> +<p>Here comes CouchDB. CouchDB is a document oriented database, that +knows how to speak REST and JSON. It's easy to use, and provides out of the box +a replication mechanism.</p> +</div> +<div class="section" id="so-what"> +<h2>So, what ?</h2> +<p>Hmm, I'm sure you got it. I'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 HTTP request on the CouchDB server. You can also access the informations +from the index directly using a REST API, speaking json. Handy.</p> +<p>So PyPIonCouch is using the PyPI XML/RPC API to get data from PyPI, and +generate records in the CouchDB instance.</p> +<p>The final goal is to avoid to rely on this &quot;simple&quot; API, and rely on a REST +insterface instead. I have set up a couchdb server on my server, which is +available at <a class="reference external" 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've done the first import from PyPI yesterday and all +went fine: it's possible to access the metadata of all PyPI projects via a REST +interface. Next step is to write a client for this REST interface in +distutils2.</p> +</div> +<div class="section" id="example"> +<h2>Example</h2> +<p>For now, you can use pypioncouch via the command line, or via the python API.</p> +<div class="section" id="using-the-command-line"> +<h3>Using the command line</h3> +<p>You can do something like that for a full import. This <strong>will</strong> take long, +because it's fetching all the projects at pypi and importing their metadata:</p> +<pre class="literal-block"> +$ pypioncouch --fullimport http://your.couchdb.instance/ +</pre> +<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 http://couchdb.notmyidea.org/pypi/</strong>, to avoid +the duplication of nodes:</p> +<pre class="literal-block"> +$ pypioncouch --update http://your.couchdb.instance/ +</pre> +<p>The principal node is updated once a day by now, I'll try to see if it's +enough, and ajust with the time.</p> +</div> +<div class="section" id="using-the-python-api"> +<h3>Using the python API</h3> +<p>You can also use the python API to interact with pypioncouch:</p> +<pre class="literal-block"> +&gt;&gt;&gt; from pypioncouch import XmlRpcImporter, import_all, update +&gt;&gt;&gt; full_import() +&gt;&gt;&gt; update() +</pre> +</div> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I want to make a couchapp, in order to navigate PyPI easily. Here are some of +the features I want to propose:</p> +<ul class="simple"> +<li>List all the available projects</li> +<li>List all the projects, filtered by specifiers</li> +<li>List all the projects by author/maintainer</li> +<li>List all the projects by keywords</li> +<li>Page for each project.</li> +<li>Provide a PyPI &quot;Simple&quot; API 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 replication</li> +</ul> +<p>I also still need to polish the import mechanism, so I can directly store in +couchdb:</p> +<ul class="simple"> +<li>The OPML files for each project</li> +<li>The upload_time as couchdb friendly format (list of int)</li> +<li>The tags as lists (currently it's only a string separated by spaces</li> +</ul> +<p>The work I've done by now is available on +<a class="reference external" href="https://bitbucket.org/ametaireau/pypioncouch/">https://bitbucket.org/ametaireau/pypioncouch/</a>. Keep in mind that it's still +a work in progress, and everything can break at any time. However, any feedback +will be appreciated !</p> +</div> +Help me to go to the distutils2 paris' sprint2011-01-15T00:00:00+01:002011-01-15T00:00:00+01:00Alexis Métaireautag: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 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 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 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 event.</p> +<p>You can find more informations about the sprint on the wiki page of the event +(<a class="reference external" 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'm unfortunately blocked in UK for money reasons. +The cheapest two ways I've found is about £80, which I can't afford. +Following some advices on #distutils, I'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 way.</p> +<p>I'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't make it to paris, I'll hang around on IRC to give some help +while needed.</p> +<p>If you want to contribute some money to help me go there, feel free to use this +chipin page: <a class="reference external" href="http://ametaireau.chipin.com/distutils2-sprint-in-paris">http://ametaireau.chipin.com/distutils2-sprint-in-paris</a></p> +<p>Thanks for your support !</p> +How to reboot your bebox using the CLI2010-10-21T00:00:00+02:002010-10-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-21:/how-to-reboot-your-bebox-using-the-cli.html<p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using …</p></div><p>I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.</p> +<div class="section" id="edit-using-grep"> +<h2>EDIT : Using grep</h2> +<p>After a bit of reflexion, that's also really easy to do using directly the +command line tools curl, grep and tail (but really harder to read).</p> +<div class="highlight"><pre><span></span>curl -X POST -u joel:joel 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 -d <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="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> +</pre></div> +</div> +<div class="section" id="the-python-version"> +<h2>The Python version</h2> +<p>Well, that's not the optimal solution, that's a bit &quot;gruik&quot;, but it works.</p> +<div class="highlight"><pre><span></span><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="bp">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> +</pre></div> +</div> +Dynamically change your gnome desktop wallpaper2010-10-11T00:00:00+02:002010-10-11T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-11:/dynamically-change-your-gnome-desktop-wallpaper.html<p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some …</p><p>In gnome, you can can use a XML file to have a dynamic wallpaper. +It's not so easy, and you can't just tell: use the pictures in this folder to do +so.</p> +<p>You can have a look to the git repository if you want: <a class="reference external" href="http://github.com/ametaireau/gnome-background-generator">http://github.com/ametaireau/gnome-background-generator</a></p> +<p>Some time ago, I've made a little python script to ease that, and you can now +use it too. It's named &quot;gnome-background-generator&quot;, and you can install it via +pip for instance.</p> +<div class="highlight"><pre><span></span>$ pip install gnome-background-generator +</pre></div> +<p>Then, you have just to use it this way:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator -p ~/Images/walls -s +/home/alexis/Images/walls/dynamic-wallpaper.xml generated +</pre></div> +<p>Here is a extract of the <cite>--help</cite>:</p> +<div class="highlight"><pre><span></span>$ gnome-background-generator --help +usage: gnome-background-generator <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-p PATH<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> + <span class="o">[</span>-t TRANSITION_TIME<span class="o">]</span> <span class="o">[</span>-d DISPLAY_TIME<span class="o">]</span> <span class="o">[</span>-s<span class="o">]</span> + <span class="o">[</span>-b<span class="o">]</span> + +A simple <span class="nb">command</span> line tool to generate an XML file to use <span class="k">for</span> gnome +wallpapers, to have dynamic walls + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -p PATH, --path PATH Path to look <span class="k">for</span> the pictures. If no output is + specified, will be used too <span class="k">for</span> outputing the dynamic- + wallpaper.xml file. Default value is the current + directory <span class="o">(</span>.<span class="o">)</span> + -o OUTPUT, --output OUTPUT + Output filename. If no filename is specified, a + dynamic-wallpaper.xml file will be generated in the + path containing the pictures. You can also use <span class="s2">&quot;-&quot;</span> to + display the xml in the stdout. + -t TRANSITION_TIME, --transition-time TRANSITION_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> transitions must last <span class="o">(</span>default value + is <span class="m">2</span> seconds<span class="o">)</span> + -d DISPLAY_TIME, --display-time DISPLAY_TIME + Time <span class="o">(</span>in seconds<span class="o">)</span> a picture must be displayed. Default + value is <span class="m">900</span> <span class="o">(</span>15mn<span class="o">)</span> + -s, --set-background <span class="s1">&#39;&#39;</span><span class="err">&#39;</span>try to <span class="nb">set</span> the background using gnome-appearance- + properties + -b, --debug +</pre></div> +How to install NGINX + PHP 5.3 on FreeBSD.2010-10-10T00:00:00+02:002010-10-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-10:/how-to-install-nginx-php-53-on-freebsd.html<p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr …</pre><p>I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !</p> +<pre class="literal-block"> +# update the ports +$ portsnap fetch update + +# install php5 port +$ make config-recursive -C /usr/ports/lang/php5-extensions +$ make package-recursive -C /usr/ports/lang/php5-extensions + +# install nginx +$ make config-recursive -C /usr/ports/www/nginx-devel +$ make package-recursive -C /usr/ports/www/nginx-devel +</pre> +<p>Now we have all the dependencies installed, we need to configure a bit the +server.</p> +<p>That's a simple thing in fact, but it could be good to have something that will +work without effort over time.</p> +<p>Here's a sample of my configuration:</p> +<pre class="literal-block"> +server { + server_name ndd; + set $path /path/to/your/files; + root $path; + + location / { + index index.php; + } + + location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ { + access_log off; + expires 30d; + } + + location ~ .php$ { + fastcgi_param SCRIPT_FILENAME $path$fastcgi_script_name; + fastcgi_pass backend; + include fastcgi_params; + } +} + +upstream backend { + server 127.0.0.1:9000; +} +</pre> +<p>And that's it !</p> +Pelican, a simple static blog generator in python2010-10-06T00:00:00+02:002010-10-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-10-06:/pelican-a-simple-static-blog-generator-in-python.html<p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" href="http://docs.getpelican.com">Pelican</a> (for calepin) is just a simple tool to generate your …</p><p>Those days, I've wrote a little python application to fit my blogging needs. +I'm an occasional blogger, a vim lover, I like restructured text and DVCSes, so +I've made a little tool that makes good use of all that.</p> +<p><a class="reference external" 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's easy to extend, +and has a template support (via jinja2).</p> +<p>I'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's needs.</p> +<p>Need an example ? You're looking at it ! This weblog is using pelican to be +generated, also for the atom feeds.</p> +<p>I've released it under AGPL, since I want all the modifications to be profitable +to all the users.</p> +<p>You can find a repository to fork at <a class="reference external" href="https://github.com/getpelican/pelican/">https://github.com/getpelican/pelican/</a>. +feel free to hack it !</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 (<cite>pelican --help</cite>)</p> +<div class="highlight"><pre><span></span>$ pip install pelican +</pre></div> +<div class="section" id="usage"> +<h2>Usage</h2> +<p>Here's a sample usage of pelican</p> +<div class="highlight"><pre><span></span>$ pelican . +writing /home/alexis/projets/notmyidea.org/output/index.html +writing /home/alexis/projets/notmyidea.org/output/tags.html +writing /home/alexis/projets/notmyidea.org/output/categories.html +writing /home/alexis/projets/notmyidea.org/output/archives.html +writing /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 ! +</pre></div> +<p>You also can use the <cite>--help</cite> option for the command line to get more +informations</p> +<div class="highlight"><pre><span></span><span class="nv">$pelican</span> --help +usage: pelican <span class="o">[</span>-h<span class="o">]</span> <span class="o">[</span>-t TEMPLATES<span class="o">]</span> <span class="o">[</span>-o OUTPUT<span class="o">]</span> <span class="o">[</span>-m MARKUP<span class="o">]</span> <span class="o">[</span>-s SETTINGS<span class="o">]</span> <span class="o">[</span>-b<span class="o">]</span> + path + +A tool to generate a static blog, with restructured text input files. + +positional arguments: + path Path where to find the content files <span class="o">(</span>default is + <span class="s2">&quot;content&quot;</span><span class="o">)</span>. + +optional arguments: + -h, --help show this <span class="nb">help</span> message and <span class="nb">exit</span> + -t TEMPLATES, --templates-path TEMPLATES + Path where to find the templates. If not specified, + will uses the ones included with pelican. + -o OUTPUT, --output OUTPUT + Where to output the generated files. If not specified, + a directory will be created, named <span class="s2">&quot;output&quot;</span> in the + current path. + -m MARKUP, --markup MARKUP + the markup language to use. Currently only + ReSTreucturedtext is available. + -s SETTINGS, --settings SETTINGS + the settings of the application. Default to None. + -b, --debug +</pre></div> +<p>Enjoy :)</p> +</div> +An amazing summer of code working on distutils22010-08-16T00:00:00+02:002010-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-08-16:/an-amazing-summer-of-code-working-on-distutils2.html<p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the …</p><p>The <a class="reference external" href="http://code.google.com/soc/">Google Summer of Code</a> I've +spent working on <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> +is over. It was a really amazing experience, for many reasons.</p> +<p>First of all, we had a very good team, we were 5 students working +on distutils2: <a class="reference external" href="http://zubin71.wordpress.com">Zubin</a>, +<a class="reference external" href="http://wokslog.wordpress.com/">Éric</a>, +<a class="reference external" href="http://gsoc.djolonga.com/">Josip</a>, +<a class="reference external" href="http://konryd.blogspot.com/">Konrad</a> and me. In addition, +<a class="reference external" href="http://mouadino.blogspot.com/">Mouad</a> have worked on the PyPI +testing infrastructure. You could find what each person have done +on +<a class="reference external" 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 shape.</p> +<p>Then, I'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've been introducing myself to +python in the late 2009.</p> +<p>I'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've traveled +since I wrote it.</p> +<p>This summer was awesome because I've learned about python good +practices, now having some strong +<a class="reference external" href="http://mercurial.selenic.com/">mercurial</a> knowledge, and I've +seen a little how the python community works.</p> +<p>Then, I would like to say a big thanks to all the mentors that have +hanged around while needed, on IRC or via mail, and especially my +mentor for this summer, <a class="reference external" 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 work!</p> +<div class="section" id="why"> +<h2>Why ?</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 way.</p> +<p>Now, we have PEPs that describes some format we agreed on (see PEP +345), and we wanted to have a tool on which users can base their +code on, that's <a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>.</p> +</div> +<div class="section" id="my-job"> +<h2>My job</h2> +<p>I had to provide a way to crawl the PyPI indexes in a simple way, +and do some installation / uninstallation scripts.</p> +<p>All the work done is available in +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket repository</a>.</p> +<div class="section" id="crawling-the-pypi-indexes"> +<h3>Crawling the PyPI indexes</h3> +<p>There are two ways of requesting informations from the indexes: +using the &quot;simple&quot; index, that is a kind of REST index, and using +XML-RPC.</p> +<p>I've done the two implementations, and a high level API to query +those twos. Basically, this supports the mirroring infrastructure +defined in PEP 381. So far, the work I've done is gonna be used in +pip (they've basically copy/paste the code, but this will change as +soon as we get something completely stable for distutils2), and +that's a good news, as it was the main reason for what I've done +that.</p> +<p>I've tried to have an unified API for the clients, to switch from +one to another implementation easily. I'm already thinking of +adding others crawlers to this stuff, and it was made to be +extensible.</p> +<p>If you want to get more informations about the crawlers/PyPI +clients, please refer to the distutils2 documentation, especially +<a class="reference external" 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 class="reference external" href="http://hg.python.org/distutils2/">distutils2</a> source code .</p> +</div> +<div class="section" id="installation-uninstallation-scripts"> +<h3>Installation / Uninstallation scripts</h3> +<p>Next step was to think about an installation script, and an +uninstaller. I've not done the uninstaller part, and it's a smart +part, as it's basically removing some files from the system, so +I'll probably do it in a near future.</p> +<p><a class="reference external" 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 +METADATA (1.2) (See, the PEP 345), but I'm working on a +compatibility layer for the old metadata, and for the informations +provided via PIP requires.txt, for instance.</p> +</div> +<div class="section" id="extra-work"> +<h3>Extra work</h3> +<p>Also, I've done some extra work. this includes:</p> +<ul class="simple"> +<li>working on the PEP 345, and having some discussion about it +(about the names of some fields).</li> +<li>writing a PyPI server mock, useful for tests. you can find more +information about it on the +<a class="reference external" href="http://distutils.notmyidea.org">documentation</a>.</li> +</ul> +</div> +</div> +<div class="section" id="futures-plans"> +<h2>Futures plans</h2> +<p>As I said, I've enjoyed working on distutils2, and the people I'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 usable.</p> +<p>I'm not plainly satisfied by the work I've done, so I'll probably +tweak it a bit: the installer part is not yet completely finished, +and I want to add support for a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +index in the future.</p> +<p>We'll talk again of this in the next months, probably, but we +definitely need a real +<a class="reference external" href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> +API for <a class="reference external" href="http://pypi.python.org">PyPI</a>, as the &quot;simple&quot; index +<em>is</em> an ugly hack, in my opinion. I'll work on a serious +proposition about this, maybe involving +<a class="reference external" href="http://couchdb.org">CouchDB</a>, as it seems to be a good option +for what we want here.</p> +</div> +<div class="section" id="issues"> +<h2>Issues</h2> +<p>I've encountered some issues during this summer. The main one is +that'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 emails.</p> +<p>I've finally managed to work in an office, so good point for +home/office separation.</p> +<p>I'd not planned there will be so a high number of emails to read, +in order to follow what'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 !).</p> +</div> +<div class="section" id="thanks"> +<h2>Thanks !</h2> +<p>A big thanks to <a class="reference external" href="http://www.graine-libre.fr/">Graine Libre</a> and +<a class="reference external" 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're a student, if you're +interested about FOSS, dont hesitate any second, it's a really good +opportunity to work on interesting projects!</p> +</div> +Introducing the distutils2 index crawlers2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/introducing-the-distutils2-index-crawlers.html<p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my …</p><p>I'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 on)</p> +<p>I'll try do sum-up my general feelings here, and the work I've made +so far. You can also find, if you're interested, my weekly +summaries in +<a class="reference external" href="http://wiki.notmyidea.org/distutils2_schedule">a dedicated wiki page</a>.</p> +<div class="section" id="general-feelings"> +<h2>General feelings</h2> +<p>First, and it's a really important point, the GSoC is going very +well, for me as for other students, at least from my perspective. +It's a pleasure to work with such enthusiast people, as this make +the global atmosphere very pleasant to live.</p> +<p>First of all, I've spent time to read the existing codebase, and to +understand what we're going to do, and what's the rationale to do +so.</p> +<p>It's really clear for me now: what we'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 PEP about packaging.</p> +<p>With distutils2, it will be simpler to make &quot;things&quot; 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 so.</p> +</div> +<div class="section" id="tasks"> +<h2>Tasks</h2> +<p>My main task while working on distutils2 is to provide an +installation and an un-installation command, as described in PEP +376. For this, I first need to get informations about the existing +distributions (what's their version, name, metadata, dependencies, +etc.)</p> +<p>The main index, you probably know and use, is PyPI. You can access +it at <a class="reference external" href="http://pypi.python.org">http://pypi.python.org</a>.</p> +</div> +<div class="section" id="pypi-index-crawling"> +<h2>PyPI index crawling</h2> +<p>There is two ways to get these informations from PyPI: using the +simple API, or via xml-rpc calls.</p> +<p>A goal was to use the version specifiers defined +in`PEP 345 &lt;<a class="reference external" href="http://www.python.org/dev/peps/pep-0345/">http://www.python.org/dev/peps/pep-0345/</a>&gt;`_ and to +provides a way to sort the grabbed distributions depending our +needs, to pick the version we want/need.</p> +<div class="section" id="using-the-simple-api"> +<h3>Using the simple API</h3> +<p>The simple API is composed of HTML pages you can access at +<a class="reference external" 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's why I've preferred to pick up +the good ideas, and some implementation details, plus re-thinking +the global architecture.</p> +<p>The rules are simple: each project have a dedicated page, which +allows us to get informations about:</p> +<ul class="simple"> +<li>the distribution download locations (for some versions)</li> +<li>homepage links</li> +<li>some other useful informations, as the bugtracker address, for +instance.</li> +</ul> +<p>If you want to find all the distributions of the &quot;EggsAndSpam&quot; +project, you could do the following (do not take so attention to +the names here, as the API will probably change a bit):</p> +<div class="highlight"><pre><span></span><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> +</pre></div> +<p>We also could use version specifiers:</p> +<div class="highlight"><pre><span></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 (&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> +</pre></div> +<p>Internally, what's done here is the following:</p> +<ul class="simple"> +<li>it process the +<a class="reference external" href="http://pypi.python.org/simple/FooBar/">http://pypi.python.org/simple/FooBar/</a> +page, searching for download URLs.</li> +<li>for each found distribution download URL, it creates an object, +containing informations about the project name, the version and the +URL where the archive 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 &quot;final&quot; distribution (rather +than beta, alpha etc. ones)</li> +</ul> +<p>So, nothing hard or difficult 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're curious, please browse the +<a class="reference external" href="http://distutils2.notmyidea.org/">distutils2 documentation</a>.</p> +</div> +<div class="section" id="using-xml-rpc"> +<h3>Using xml-rpc</h3> +<p>We also can make some xmlrpc calls to retreive informations from +PyPI. It's a really more reliable way to get informations from from +the index (as it's just the index that provides the informations), +but cost processes on the PyPI distant server.</p> +<p>For now, this way of querying the xmlrpc client is not available on +Distutils2, as I'm working on it. The main pieces are already +present (I'll reuse some work I've made from the SimpleIndex +querying, and +<a class="reference external" 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's on what I'm actually working on.</p> +</div> +</div> +<div class="section" id="processes"> +<h2>Processes</h2> +<p>For now, I'm trying to follow the &quot;documentation, then test, then +code&quot; path, and that seems to be really needed while working with a +community. Code is hard to read/understand, compared to +documentation, and it's easier to change.</p> +<p>While writing the simple index crawling work, I must have done this +to avoid some changes on the API, and some loss of time.</p> +<p>Also, I've set up +<a class="reference external" 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 +...)</p> +</div> +Sprinting on distutils2 in Tours2010-07-06T00:00:00+02:002010-07-06T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-07-06:/sprinting-on-distutils2-in-tours.html<p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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 …</p><p>Yesterday, as I was traveling to Tours, I've took some time to +visit Éric, another student who'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'd really enjoyed this +time, because Éric knows a lot of things about mercurial and python +good practices, and I'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 had.</p> +<div class="section" id="documentation"> +<h2>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'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 those:</p> +<ul class="simple"> +<li><strong>Packagers</strong> who want to distribute their softwares.</li> +<li><strong>End users</strong> who need to understand how to use end user +commands, like the installer/uninstaller</li> +<li><strong>packaging coders</strong> who <em>use</em> distutils2, as a base for +building a package 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 API +description ? etc. That's maybe seems to be not so important, but I +guess the readers would appreciate to have the same structure all +along distutils2 documentation.</p> +</div> +<div class="section" id="mercurial"> +<h2>Mercurial</h2> +<p>I'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'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've not used them so far, so consider this as +a personal note.</p> +<ul class="simple"> +<li>hg histedit, to edit the history</li> +<li>hg crecord, to select the changes to 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 class="reference external" 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 ... Great. I'm a powerful merger now !</p> +</div> +<div class="section" id="on-using-tools"> +<h2>On using 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've +discovered vimdiff and hgtk, which will completely change the way I +navigate into the mercurial history. We aren't &quot;power users&quot;, so we +have learned from each other about vim tips. You can find +<a class="reference external" href="http://github.com/ametaireau/dotfiles">my dotfiles on github</a>, +if it could help. They're not perfect, and not intended to be, +because changing all the time, as I learn. Don't hesitate to have a +look, and to propose enhancements if you have !</p> +</div> +<div class="section" id="on-being-pythonic"> +<h2>On being 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 class="reference external" 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 do.</p> +</div> +<div class="section" id="conclusion"> +<h2>Conclusion</h2> +<p>It was really great. Next time, we'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'll probably do +another sprint in a few weeks, stay tuned !</p> +</div> +Use Restructured Text (ReST) to power your presentations2010-06-25T00:00:00+02:002010-06-25T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-25:/use-restructured-text-rest-to-power-your-presentations.html<p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 …</p><p>Wednesday, we give a presentation, with some friends, about the +CouchDB Database, to +<a class="reference external" href="http://www.toulibre.org">the Toulouse local LUG</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 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 class="reference external" href="http://docutils.sourceforge.net/rst.html">restructured text</a>, so +I've wrote a simple file containing our different bullet points. In +fact, there is quite nothing to do then, to have a working +presentation.</p> +<p>So far, I've used +<a class="reference external" href="http://code.google.com/p/rst2pdf/">the rst2pdf program</a>, and a +simple template, to generate output. It's probably simple to have +similar results using latex + beamer, I'll try this next time, but +as I'm not familiar with latex syntax, restructured text was a +great option.</p> +<p>Here are +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.pdf">the final PDF output</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/couchdb/couchdb.rst">Rhe ReST source</a>, +<a class="reference external" href="http://files.lolnet.org/alexis/rst-presentations/slides.style">the theme used</a>, +and the command line to generate the PDF:</p> +<pre class="literal-block"> +rst2pdf couchdb.rst -b1 -s ../slides.style +</pre> +first week working on distutils22010-06-04T00:00:00+02:002010-06-04T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-06-04:/first-week-working-on-distutils2.html<p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I've not worked as much as I +wanted, and this will continues until the end of …</p><p>As I've been working on +<a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a> during the past +week, taking part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">GSOC</a> program, here is a +short summary of what I've done so far.</p> +<p>As my courses are not over yet, I'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 class="reference external" 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 class="reference external" href="http://pypi.python.org/">PyPI</a>), and there is at +least two ways to retreive informations from here: XML-RPC and the +&quot;simple&quot; API.</p> +<p>So, I've been working on porting some +<a class="reference external" href="http://bitbucket.org/tarek/distribute/">Distribute</a> related +stuff to <a class="reference external" href="http://hg.python.org/distutils2/">Distutils2</a>, cutting +off all non distutils' things, as we do not want to depend from +Distribute's internals. My main work has been about reading the +whole code, writing tests about this and making those tests +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've taken some time to improve the work +<a class="reference external" href="http://bitbucket.org/konrad">Konrad</a> makes about this mock.</p> +<div class="section" id="a-pypi-server-mock"> +<h2>A PyPI Server 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 class="reference external" href="http://wsgi.org">WSGI</a> and +<a class="reference external" 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 class="reference external" 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 +Distutils2).</p> +<p>So, we switched to +<a class="reference external" href="http://docs.python.org/library/basehttpserver.html">BaseHTTPServer</a> +and +<a class="reference external" href="http://docs.python.org/library/simplehttpserver.html">SimpleHTTPServer</a>, +and updated our tests accordingly. It's been an opportunity to +realize that <a class="reference external" href="http://wsgi.org">WSGI</a> has been a great step +forward for making HTTP servers, and expose a really simplest way +to discuss with HTTP !</p> +<p>You can find +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/changesets">the modifications I made</a>, +and the +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/src/tip/docs/source/test_framework.rst">related docs</a> +about this on +<a class="reference external" href="http://bitbucket.org/ametaireau/distutils2/">my bitbucket distutils2 clone</a>.</p> +</div> +<div class="section" id="the-pypi-simple-api"> +<h2>The PyPI Simple API</h2> +<p>So, back to the main problematic: make a python library to access +and request information stored on PyPI, via the simple API. As I +said, I've just grabbed the work made from +<a class="reference external" 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 tests.</p> +</div> +<div class="section" id="the-work-to-come"> +<h2>The work to come</h2> +<p>So, once all use cases covered with tests, I'll rewrite a bit the +grabbed code, and do some software design work (to not expose all +things as privates methods, have a clear API, and other things like +this), then update the tests accordingly and write a documentation +to make this clear.</p> +<p>Next step is to a little client, as I've +<a class="reference external" href="http://github.com/ametaireau/pypiclient">already started here</a> +I'll take you updated !</p> +</div> +A Distutils2 GSoC2010-05-01T00:00:00+02:002010-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2010-05-01:/a-distutils2-gsoc.html<p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python …</blockquote><p>WOW. I've been accepted to be a part of the +<a class="reference external" href="http://code.google.com/intl/fr/soc/">Google Summer Of Code</a> +program, and will work on <a class="reference external" href="http://python.org/">python</a> +<a class="reference external" href="http://hg.python.org/distutils2/">distutils2</a>, with +<a class="reference external" href="http://pygsoc.wordpress.com/">a</a> +<a class="reference external" href="http://konryd.blogspot.com/">lot</a> <a class="reference external" href="http://ziade.org/">of</a> +(intersting!) <a class="reference external" href="http://zubin71.wordpress.com/">people</a>.</p> +<blockquote> +So, it's about building the successor of Distutils2, ie. &quot;the +python package manager&quot;. Today, there is too&nbsp;many ways to package a +python application (pip, setuptools, distribute, distutils, etc.) +so&nbsp;there is a huge effort to make in order to make all this +packaging stuff interoperable, as pointed out by +the&nbsp;<a class="reference external" href="http://www.python.org/dev/peps/pep-0376/">PEP 376</a>.</blockquote> +<p>In more details, I'm going to work on the Installer / Uninstaller +features of Distutils2, and on a PyPI XML-RPC client for distutils2. +Here are the already defined tasks:</p> +<ul class="simple"> +<li>Implement Distutils2 APIs described in PEP 376.</li> +<li>Add the uninstall command.</li> +<li>think about a basic installer / uninstaller script. (with deps) +-- similar to pip/easy_install</li> +<li>in a pypi subpackage;</li> +<li>Integrate a module similar to setuptools' package_index'</li> +<li>PyPI XML-RPC client for distutils 2: +<a class="reference external" href="http://bugs.python.org/issue8190">http://bugs.python.org/issue8190</a></li> +</ul> +<p>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.</p> +Python ? go !2009-12-17T00:00:00+01:002009-12-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-12-17:/python-go-fr.html<p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à …</p><p>Cela fait maintenant un peu plus d'un mois que je travaille sur un +projet en <a class="reference external" href="http://www.djangoproject.org">django</a>, et que, +nécessairement, je me forme à <a class="reference external" href="http://python.org/">Python</a>. Je +prends un plaisir non dissimulé à découvrir ce langage (et à +l'utiliser), qui ne cesse de me surprendre. Les premiers mots qui +me viennent à l'esprit à propos de Python, sont &quot;logique&quot; et +&quot;simple&quot;. Et pourtant puissant pour autant. Je ne manque d'ailleurs +pas une occasion pour faire un peu d'<em>évangélisation</em> auprès des +quelques personnes qui veulent bien m'écouter.</p> +<div class="section" id="the-zen-of-python"> +<h2>The Zen of Python</h2> +<p>Avant toute autre chose, je pense utile de citer Tim Peters, et +<a class="reference external" href="http://www.python.org/dev/peps/pep-0020/">le PEP20</a>, qui +constituent une très bonne introduction au langage, qui prends la +forme d'un <em>easter egg</em> présent dans python</p> +<div class="highlight"><pre><span></span>&gt;&gt;&gt; import this +The Zen of Python, by Tim Peters + +Beautiful is better than ugly. +Explicit is better than implicit. +Simple is better than complex. +Complex is better than complicated. +Flat is better than nested. +Sparse is better than dense. +Readability counts. +Special cases 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 Dutch. +Now is better than never. +Although never is often better than *right* now. +If the implementation is hard to explain, 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="k">do</span> more of those! +</pre></div> +<p>J'ai la vague impression que c'est ce que j'ai toujours cherché à +faire en PHP, et particulièrement dans +<a class="reference external" href="http://www.spiral-project.org">le framework Spiral</a>, mais en +ajoutant ces concepts dans une sur-couche au langage. Ici, c'est +directement de <em>l'esprit</em> de python qu'il s'agit, ce qui signifie +que la plupart des bibliothèques python suivent ces concepts. Elle +est pas belle la vie ?</p> +</div> +<div class="section" id="comment-commencer-et-par-ou"> +<h2>Comment commencer, et par ou ?</h2> +<p>Pour ma part, j'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'est bien évidemment pas exhaustive et vos +commentaires sont les bienvenus) :</p> +<ul class="simple"> +<li><a class="reference external" href="http://diveintopython.adrahon.org/">Dive into python</a></li> +<li><a class="reference external" href="http://www.swaroopch.com/notes/Python_fr:Table_des_Matières">A byte of python</a></li> +<li><a class="reference external" href="http://www.amazon.fr/Python-Petit-guide-lusage-développeur/dp/2100508830">Python: petit guide à l'usage du développeur agile</a> +de <a class="reference external" href="http://tarekziade.wordpress.com/">Tarek Ziadé</a></li> +<li><a class="reference external" href="http://docs.python.org/index.html">La documentation officielle python</a>, +bien sûr !</li> +<li><a class="reference external" 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 :)</li> +</ul> +<p>J'essaye par ailleurs de partager au maximum les ressources que je +trouve de temps à autres, que ce soit +<a class="reference external" href="http://www.twitter.com/ametaireau">via twitter</a> ou +<a class="reference external" href="http://delicious.com/ametaireau">via mon compte delicious</a>. +Allez jeter un œil +<a class="reference external" href="http://delicious.com/ametaireau/python">au tag python</a> sur mon +profil, peut être que vous trouverez des choses intéressantes, qui +sait!</p> +</div> +<div class="section" id="un-python-sexy"> +<h2>Un python sexy</h2> +<p>Quelques fonctionnalités qui devraient vous mettre l'eau à la +bouche:</p> +<ul class="simple"> +<li><a class="reference external" 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 condition)</li> +<li>Assignation de valeurs multiples (il est possible de faire a,b,c += 1,2,3 par exemple)</li> +<li><a class="reference external" href="http://docs.python.org/tutorial/datastructures.html">Les listes</a> +sont simples à manipuler !</li> +<li>Les <a class="reference external" 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 simple.</li> +<li>Les +<a class="reference external" 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 exemples.</li> +<li>Les +<a class="reference external" 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 construisent</li> +<li>Python est +<a class="reference external" 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'est ce qui m'agaçait avec PHP qui est un langage à typage faible +dynamique.</li> +</ul> +<p>Cous pouvez également aller regarder +<a class="reference external" href="http://video.pycon.fr/videos/free/53/">l'atelier donné par Victor Stinner durant le Pyconfr 09</a>. +Have fun !</p> +</div> + \ No newline at end of file diff --git a/feeds/thoughts.atom.xml b/feeds/thoughts.atom.xml new file mode 100644 index 0000000..bbfa230 --- /dev/null +++ b/feeds/thoughts.atom.xml @@ -0,0 +1,1767 @@ + +Carnets Web - thoughtshttps://blog.notmyidea.org/2018-02-19T00:00:00+01:00Faire moins2018-02-19T00:00:00+01:002018-02-19T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2018-02-19:/faire-moins.html<p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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 …</p><p>L'an dernier, j'ai décidé de faire moins de choses, ou plus exactement d'arrêter de faire de nouvelles choses. Choix assez difficile: j'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'occasion de contribuer à éviter notre société d'experts.</p> +<p>Le hic, c'est que trop, c'est trop. J'ai donc décidé d'arrêter, tout simplement, de faire de nouvelles choses, et puis avec le temps j'ai même arreté de faire des choses que j'avais commencé à faire (par exemple de l'escalade), me libérant du temps.</p> +<p>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.</p> +<p>Et surtout, c'est se retrouver à contrôler son engagement.</p>Brasserie du Vieux Singe — Installation en cours.2017-06-26T00:00:00+02:002017-06-26T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2017-06-26:/brasserie-du-vieux-singe-installation-en-cours.html<p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour …</p><p>Ça fait maintenant quelques mois que j'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'envie de créer, et je renoue avec mes rêves, ceux-la mêmes que je croyaient trop fous pour être à portée de main.</p> +<p>La chose la plus frappante, c'est la vitesse à laquelle passent les journées: j'ai <em>vraiment</em> l'impression d'avoir quitté Mozilla hier. Si les collègues me +manquent, je ne ferais machine arrière pour rien au monde: je trouve finalement ce sens qui me manquait cruellement.</p> +<p>Après quelques hésitations au départ, j'ai décidé de mettre de côté mes activités liées à l'informatique: difficile à assumer quand on croise les copin.e.s avec qui on avait l'habitude de discuter énormement de ces sujets, mais ça permet de laisser plus de place pour l'humain. Plus de place pour les «Au fait, comment ça va toi ?» quand j'ai l'occasion de les recroiser, ce qui n'est pas plus désagréable :)</p> +<p>Les journées sont donc organisées autour de la brasserie: beaucoup plus de planification que ce que j'imaginais au départ. Peut-être que c'est aussi du au fait que nous soyons tous les deux des ex-informaticiens un peu perfectionnistes sur les bords. On se voit très souvent pour avancer sur des sujets de fond tout comme sur du pratico-pratique. Pour vous donner un ordre d'idée des questionnements: Quelle taille d'entreprise ? Quelles valeurs communes ? Quelles bières ? Quelle image donner ? Quelle place donner au confort ? Comment éviter la compétitivité ? Comment réussir à impacter les producteurs (houblon / malt) de manière positive ? Quels salaires se donner ?</p> +<p>Un peu de production quand même (pour les amis) mais on se garde la grosse partie pour le lancement.</p> +<h2>Apprentissage</h2> +<p>Je profite de ces quelques mois pour apprendre: autour de la fabrication et de la dégustation de bière bien sûr (encore un milieu en constante évolution !), mais pas que. J'ai maintenant quelques bases de gestion d'entreprise, en comptabilité, en biologie et en chimie. J'ai bien dit quelques <em>bases</em>, mais qu'est-ce que c'est agréable !</p> +<p>C'est assez agréable de se remettre dans une posture d'apprenant, et d'avoir le temps pour cet apprentissage.</p> +<h2>Questionner la posture de «Chef d'entreprise» et son rapport au temps</h2> +<p>Décider de créer sa boîte, c'est aussi se poser la question de comment organiser son temps: combien de temps travailler ? Quel temps donner aux loisirs ?</p> +<p>Je trouve rassurant de voir ces interrogations abordées avant-même le démarrage de l'entreprise. La plupart des personnes qui nous suivent et nous guident partent du postulat qu'il faudra bosser énormement, là ou nous essayons de trouver un modèle qui soit viable dans le temps, notre souhait est de bosser à 80% (4 jours par semaine).</p> +<p>Certes, il faut travailler pour que ça tourne, mais il faut aussi s'accorder des temps de respiration pour être d'autant plus efficace quand on bosse. C'est d'autant plus intéressant de prévoir ces aspects lors de la phase de <em>design</em> de l'activité: on organise le temps autrement ! Ceux qui me lisent de temps à autre savent que c'est une constante de mes réflexions, on verra si ça fonctionne dans les faits.</p> +<h2>Les projets collectifs</h2> +<p>Un autre point important est la place que le <em>collectif</em> prends dans cette nouvelle expérience. Au départ, quand j'imaginais le projet sur le court-terme, je mettais la composante collective au second plan dans l'immédiat (au delà des intéractions avec Fred, mon associé). L'occasion de travailler à la construction d'un espace collectif s'est présentée, et on y travaille actuellement.</p> +<p>C'est à la fois riche (en partage de points de vue, en entre-aide) et à la fois difficile (beaucoup d'heures de réunions, il faut apprendre à communiquer de manière efficace, il faut parfois faire face à des conflits). Dans l'ensemble, je ne regrette pas ce choix même si il est important de ne pas perdre de vue les objectifs de la brasserie dans l'histoire.</p> +<p>Et puis la collaboration ne s'arrête pas qu'au collectif d'activité: le milieu brassicole est en mutation, et les valeurs de partage font bel et bien partie du lot de changements. Les rencontre avec les brasseurs du coin de Rennes le montrent bien: l'esprit est plus à l'entraide qu'à la concurrence, au vu de la demande qui est toujours croissante. Tant mieux, on a autre chose à faire qu'à se tirer dans les pâtes ;)</p> +<h2>Besoin de concret</h2> +<p>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…</p> +<p>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 ?</p>Cloisonnement des activités ?2016-05-29T00:00:00+02:002016-05-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2016-05-29:/cloisonnement-des-activites.html<p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en …</p><p>Je vous écris depuis un train, en rentrant de Bordeaux où j'ai passé quelques +jours à l'occasion de <a href="http://sudweb.fr/">SudWeb</a>. Si vous ne connaissez pas +cette conférence, il s'agit d'un moment avec des gens chouettes qui se posent +des questions sur leur metier, comment le vivre et comment continuer à en faire +un plaisir. Oh, et des fois on parle un peu de technique aussi.</p> +<h1>Alors, brasserie ou code ?</h1> +<p>Ces quelques jours ont été fort inspirants. Alors que je suis en train de +changer de métier (vers celui de brasseur) c'était un moyen de me rendre compte +que bien que je ne souhaite plus faire du Web mon métier <em>la, tout de suite, +maintenant</em>, je reste un passionné par la chose.</p> +<p>En partant de Rennes, je ne savais pas trop quoi penser de cette situation. +Prendre un week-end pour échanger avec les gens sur quelque chose dont je +m'éloigne ? C'est pas une perte de temps ?</p> +<p>Si je passe du temps à écrire des bouts de code, des logiciels, à reflechir +à comment solutionner certains problemes, ce n'est pas parce que je suis payé +pour le faire, mais bel et bien parce que je me sens bien lorsque je le fais, +parce que j'y trouve un équilibre et une utilité.</p> +<p>Alors que je ne trouvais plus cet équilibre dans mon travail, j'ai choisi d'en +changer, mais il n'empèche que je continue à avoir des rèves d'un +monde meilleur, dans lequel l'informatique a sa place. Juste à voir les +discussions (ux, sécurité informatique, décentralisation, architecture +logicielle) que j'ai pu avoir ce weekend, il n'y a pas l'ombre d'un doute !</p> +<p>Jusqu'ici je me suis dit que je devais choisir. J'ai pensé naivement +que je ne pouvais pas être <em>et</em> un brasseur <em>et</em> un developpeur, mais la +réalité c'est que c'est exactement ce que je suis: les deux.</p> +<p>Je ne suis pas pour autant dupe sur le temps necessaire à lancer une activité +brassicole, il va falloir fournir de l'énergie et avancer sur le projet, mais +il n'empèche que même si je décide de faire de la bière mon metier, mes +passions pour le reste sont bien vivantes.</p> +<p>Bref, merci sudweb pour m'avoir accompagné dans ces reflexions, à l'année +prochaine, je ramène des futs ?</p>Focusing on what matters2016-03-17T00:00:00+01:002016-03-17T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-17:/focusing-on-what-matters.html<p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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><p>I do have a problem with information.</p> +<p>You know. I <strong>have</strong> to check my emails, irc, twitter, my feed reader etc. +I need 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, away from news and +agitation.</p> +<p>Working remotely is sometimes hard. Hard because you need to at the same time +be in the discussions channels and work on the interesting projects. A real +myth.</p> +<p>In practice, I'm really bad at multi-tasking. I tried a few times the <em>Pomodoro</em> +technique, which forces me to focus on a task for 25mn, but this split of my day +into slices of 25mn breaks my natural flow.</p> +<p>So, what do I need? I tried to change my tools, it helped a bit. Still, I'm not +focused like I would like to be.</p> +<p>Maybe that's just me who needs some more persuasion over myself, but the best +way I found to work is to unplug the cable. Literally. At work, at some point I +was using a RJ45 cable to connect to the Internet. When I wanted to work on +something, I could just unplug this cable.</p> +<p>And that's amazing how you find yourself in the process to &quot;check&quot; +something on the web. Mails, irc… well, you got the idea. You're litterally, +without even noticing, switching to your browser an opening a new tab…</p> +<p>Of course, that Web isn't filled only with lolcats and twitter messages +(even if I would <strong>love</strong> to see a pie chart with the repartition of lolcats +VS the rest of the web's content), so sometimes you need some precious bit of +information that's there. Fair enough. plug the cable, do what you <strong>need</strong> to +do, and unplug. Alexis, unplug!</p> +<p>It also helps to have some fair bit of documentation available directly on my +machine (I used to have the python docs, I should get it back!)</p> +<p>I'm feeling adventurous, so I'll try something new starting tomorrow, and I'll +report back in here my findings. Here's the challenge:</p> +<ul class="simple"> +<li><strong>Check emails only once a day</strong>. Do <strong>not</strong> do it in the morning, before +working, to keep my mind clear. I would say at 2pm (after lunch). +(This doesn't mean I will not send mails tho)</li> +<li>Stay away from the Internet during the morning. I'll not connect if I don't +need to.</li> +</ul> +<p>Let's see how it goes :)</p> +L'horizon2016-03-02T00:00:00+01:002016-03-02T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2016-03-02:/lhorizon.html<blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont …</p><blockquote class="epigraph"> +L'Utopie, c'est l'horizon. C'est ce qui permet d'avoir une direction, de +mettre un pied devant l'autre, de savoir vers où marcher.</blockquote> +<p>Il y a presque 4 ans et demi, je commençais à travailler, en décembre, pour +Mozilla. Je me rappelle bien de ces premiers instants un peu magiques, qui ont +eu lieu juste avant une descente de cave en Bourgogne avec Tarek pour +y déguster quelques saveurs de vins différentes.</p> +<p>Quatre ans plus tard, je me retrouve à coder sur Daybed, mon petit projet +perso, devenu <a class="reference external" href="http://kinto.readthedocs.org/">Kinto</a> avec une équipe de +personnes plus talentueuses et sympathiques les unes que les autres (Niko, +Rémy, Mat, si vous me lisez…).</p> +<p>Mozilla a bien évolué en quelques années: les petits bureaux ou j'avais atterri +se sont transformés en palace où il est possible d'accueillir des membres de la +communauté du logiciel libre de manière quotidienne.</p> +<p>De 14 personnes dans les bureaux Parisiens, nous sommes passés à une 40aine (et +de ~500 salariés à 1100 dans le monde).</p> +<p>Grandir autant en si peu de temps est un challenge difficile à tenir, qui +nécessite des réorganisations et bien souvent dans une structure de cette +taille, de la hiérarchisation. En 4 ans j'ai eu au moins 5 changements de +supérieurs, pour finalement arriver à une situation plutôt convenable (mais +quand même !)</p> +<p>J'ai choisi de rejoindre Mozilla parce que j'ai besoin de causes à défendre, +qui me saisissent et qui me guident. Aujourd'hui, une des visions qui m'anime, +c'est celle que d'autres ont déjà ouverte: celle de données et de vie privée +qui sont rendues à leurs utilisateurs.</p> +<p>Et je veux faire en sorte de réaliser ces «rêves d'un monde meilleur», ce qui +veut dire pour moi qu'il est temps de partir vers des horizons plus propices +à cette vision.</p> +<p>Lesquels ? Cela reste à construire (mais je vous le dis, y'a du Kinto dedans !)</p> +<div class="section" id="la-suite"> +<h2>La suite ?</h2> +<p>Sans m'étaler, je veux prendre du temps pour quelques projets autour du +stockage de données (via Kinto), de l'auto défense numérique (via des +formations) et de la fabrication de bière artisanale (parce que bon, on se +refait pas !)</p> +<p>Évidemment, plein d'envies diverses et variées, envie de me balader un peu et +d'expérimenter des choses collectivement...</p> +<p>On se recroisera surement :)</p> +</div> +Rôles2015-06-29T00:00:00+02:002015-06-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-06-29:/roles.html<blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de …</p></blockquote><blockquote class="epigraph"> +<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 leur pente « naturelle ».</p> +<p>Pour ce faire, le groupe prendra du temps pour identifier les types de +positions qu’adoptent ses protagonistes et les affects qui y sont liés, +imaginer ensuite des questions à résoudre ou des propositions à travailler +qui soient susceptibles d’enrichir la palette, les couleurs de la fonction +de chacun dans le groupe et les manières qui sont les siennes d’intervenir +et de faire évoluer l’histoire.</p> +<p class="attribution">&mdash;David Vercauteren, <a class="reference external" href="http://micropolitiques.collectifs.net/Role">Micropolitiques des groupes</a></p> +</blockquote> +<p>Réussir la transformation d'un espace compétitif vers un groupe soudé demande +de réaliser quels sont les points forts de chacun au sein d'un groupe.</p> +<p>Une solution évoquée par <a class="reference external" href="http://www.starhawk.org/about/">StarHawk</a>, reprise +par <em>David Vercauteren</em> repose sur l'existence de rôles informels au sein des +groupes et la nécessité de les faire tourner (ainsi que les responsabilités +attachées).</p> +<p>Parmi les rôles principaux, quelques autres citations:</p> +<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">l'emphase est de mon fait, et je retravaillé très legèrement certains +passages afin d'avoir une lecture plus fluide. Je vous invite à suivre +les liens pour voir les &quot;questions que chaque rôle fait exister&quot;, et +poursuivre la lecture du livre, qui est entièrement disponible en +ligne.</p> +</div> +<div class="section" id="id1"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_0">Les corbeaux</a></h2> +<blockquote class="epigraph"> +<p>Les Corbeaux sont visionnaires […] Ils voient à long terme, et gardent en +ligne de mire les objectifs du groupe. Ils suggèrent de nouvelles directions, +dressent des plans, développent des stratégies et anticipent les problèmes et +les besoins.</p> +<p>Les Corbeaux ont souvent beaucoup d’influence sur le groupe. Si une ou deux +personnes pensent à des plans au long-terme, les autres acquiesceront, +simplement parce qu’ils n’ont pas amené d’autres propositions. <strong>Le groupe +aurait intérêt à considérer ensemble les questions du Corbeau</strong></p> +</blockquote> +</div> +<div class="section" id="id2"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_1">Les graces</a></h2> +<blockquote class="epigraph"> +<p>Les Grâces sont toujours attentives à l’énergie du groupe, prêtes à la +renforcer au moment où elle faiblit, à la diriger et à la canaliser quand +elle est forte.</p> +<p>Elles apportent au groupe […] enthousiasme, énergie, capacité +à s’agrandir. <strong>Elles font en sorte que les gens se sentent bien</strong>, génèrent de +l’enthousiasme pour le groupe, accueillent les nouveaux venus, amènent de +nouvelles personnes. Elles offrent au groupe l’inspiration et génèrent de +nouvelles idées.</p> +</blockquote> +</div> +<div class="section" id="id3"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_2">Les dragons</a></h2> +<blockquote class="epigraph"> +<p>Le dragon permet au groupe de rester connecté à […] l’aspect pratique et +réaliste des choses. […] Le dragon veille aux ressources du groupe, à ses +frontières et donne voix à ses limites.</p> +<p>Questions que fait exister le dragon:</p> +<ul class="simple"> +<li>Notre manière de travailler est-elle viable ?</li> +<li>Nos ressources sont-elles renouvelées ?</li> +<li>Les gens s’épuisent-ils ? Pourquoi ?</li> +<li>Pouvons-nous vraiment nous lancer dans ce projet et le mener à bien +convenablement ?</li> +<li>De quelles frontières avec l’extérieur avons-nous besoin et voulons-nous +?</li> +<li>Comment établissons-nous ces frontières ? Comment nous protégeons-nous +des intrusions ? Invasions ? Distractions ? De ce qui épuise nos énergies +?</li> +</ul> +<p><strong>Les Dragons établissent des frontières qui donnent au groupe un sentiment +de sécurité et des limites qui le rendent viable dans le temps</strong>. Ils peuvent +être perçus comme des rabat-joie, mais ils peuvent gagner l’estime de ceux +qui, dans le groupe, se sentent dépassés et ne peuvent partager l’énergie +des Corbeaux et des Grâces.</p> +<p>Nourrir les Dragons peut permettre au groupe de se maintenir dans le temps. +Mais une fois encore, si ce rôle ne tourne pas, même les Dragons risquent +de s’épuiser.</p> +</blockquote> +</div> +<div class="section" id="id4"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_3">Les araignées</a></h2> +<blockquote class="epigraph"> +<p>Le centre d’un groupe peut consister en un « cœur spirituel », <strong>un but ou une +vision commune</strong>, ou peut se manifester à travers une personne. Dans les modes +de pensée hiérarchique, le professeur ou le gourou occupe le centre du +réseau. […]</p> +<p>Dans les groupes non-hiérarchiques, certaines personnes peuvent être perçues +comme centrales : en disposant des informations dont les autres ont besoin, +en étant le point de contact pour les autres.</p> +<p>Une Araignée est toutefois plus efficace en ne monopolisant pas la +communication et les informations mais en posant les questions susceptibles +de créer et de renforcer un véritable réseau d’interactions complexes.</p> +</blockquote> +</div> +<div class="section" id="id5"> +<h2><a class="reference external" href="http://micropolitiques.collectifs.net/Role?artpage=2-5#outil_sommaire_4">Les serpents</a></h2> +<blockquote class="epigraph"> +<p>Les serpents cultivent une attention particulière à la manière dont les gens +se sentent. […]</p> +<p>Les serpents sont au courant de ce qui se murmure dans les couloirs, des +conflits naissants, et les mettent sur la place publique, là où ils +pourraient aider à une médiation, à une résolution du problème. […]</p> +<p>Les serpents transgressent les lois du Censeur, <strong>parlent des non-dits, mettent +en évidence ce que d’autres ne voient pas ou préfèrent garder caché</strong>. […]</p> +<p>Les serpents peuvent diminuer l’antipathie dont ils font l’objet s’ils +prennent la peine de poser des questions au groupe et non d’apporter des +analyses.</p> +</blockquote> +<p>Ainsi, il est possible de se rendre compte de la complexité et de l'importance +d'une position ou d'une autre, et de les faire évoluer ensemble, en prenant en +compte leur impact positif sur le groupe.</p> +<p>Il est par exemple possible, après avoir expérimenté des rôles, de questionner +leur pertinence et d'établir des pistes d'amélioration en enlevant une part +importante d'affect personnel qui parfois empêche des discussions +constructives.</p> +<p>Je n'ai pour l'instant pas pu expérimenter l'évolution des rôles au sein d'un +groupe donné, mais je peux d'ores et déjà me rendre compte que selon les +groupes et selon les moments je n'ai pas le même rôle (tour à tour dragon, +araignée et grace, parfois corbeau, rarement serpent)</p> +<p>Aussi, il semble que le groupe doive souhaiter l'établissement d'un +environnement <em>horizontal</em>, avec une considération partagée de la direction que +le groupe souhaite prendre pour qu'un tel dispositif ait du sens.</p> +</div> +Travail et créativité2015-05-21T00:00:00+02:002015-05-21T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-21:/travail-et-creativite.html<blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui …</p><blockquote class="epigraph"> +<p>Low-risk, low-pressure, and love: The 3 rules of side projects.</p> +<p class="attribution">&mdash;<a class="reference external" href="https://open.bufferapp.com/side-projects-creative-hobbies/">The science of side projects</a></p> +</blockquote> +<p>Je ne m'étais jamais fais la remarque, mais les projets dont je suis le plus +fier sont effectivement des <em>side projects</em>. Des projets que j'ai commencé +parce que j'en avais l'envie et le temps, qui n'étaient bien souvent que des +envies passagères.</p> +<p>Il est arrivé que quelqu'un m'ait demandé de le faire, et que j'y prenne du +plaisir, ou que je le fasse simplement pour moi et que d'autres y trouvent leur +compte, mais il s'agit nécessairement de projets non <em>commandités</em> par l'extérieur.</p> +<p>Encore un signal dans la direction du travailler moins, cette fois ci pour +être plus créatif.</p> +<img alt="Soupa'Soups." src="https://blog.notmyidea.org/images/soupasoups.jpg" /> +Chiffrement2015-05-08T00:00:00+02:002015-05-08T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-08:/chiffrement.html<blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise …</strong></li></ul></blockquote><blockquote class="epigraph"> +<p>En france, depuis le 5 Mai 2015, il est possible au Premier Ministre de +surveiller massivement et sans contrôle la population française.</p> +<p>le projet de loi n'a pas été significativement amendé en séance mi-avril, +et ses dispositions dangereuses ont été conservées :</p> +<ul class="simple"> +<li>Élargissement des finalités du renseignement, permettant une <strong>potentielle +mise sous surveillance de pans entiers de la vie politique, syndicale, +militante</strong>, mais aussi économique, scientifique, etc. ;</li> +<li>Légalisation massive de pratiques illégales des services de +renseignement et <strong>introduction de techniques de surveillance de masse +des communications électroniques</strong> ;</li> +<li><strong>Absence de contrôle réel et indépendant</strong> a priori par la future +CNCTR, et recours des citoyens illusoires ;</li> +</ul> +<p class="attribution">&mdash;<a class="reference external" href="https://www.laquadrature.net/fr/lassemblee-nationale-vote-la-surveillance-de-masse-des-citoyens-francais">La Quadrature du Net - L'Assemblée nationale vote la surveillance de +masse des citoyens français !</a></p> +</blockquote> +<p>Je m'étonne que <a class="reference external" href="https://fr.wikipedia.org/wiki/R%C3%A9v%C3%A9lations_d%27Edward_Snowden">les révélations d'Edward Snowden</a> — qui +ont démontré que la plupart des communications électroniques et téléphoniques +pouvaient être scrutés par la NSA, l'agence de sécurité Américaine) — ne +fassent pas plus de remous que ça.</p> +<p>À peine deux années après ces révélations, la France fait passer une loi qui +légitime cette surveillance de masse, à plus de 77% des voies. Pour moi c'est +un signal fort de la perte de valeurs de notre démocratie, et à fortiori de ma +perte de foi en notre forme de démocratie.</p> +<p>Notre liberté d'expression se voit bien évidemment amputée de par la +surveillance généralisée. Sans avoir nécessairement à cacher mes échanges, ce +qui est de la sphère privée devrait pouvoir le rester.</p> +<p>De toute manière, l'email comme on l'utilise traditionnellement est une +hérésie: toutes les parties qui traitent le message peuvent le lire, +(destinataire, auteur et corps du message entre autres). Il est grand temps de +rendre les outils de chiffrement plus simples et ergonomiques.</p> +<p>Je compte donc:</p> +<ul class="simple"> +<li>Organiser des ateliers de sensibilisation aux outils de communication, envers +mes proches;</li> +<li>Utiliser la communication chiffrée le plus souvent possible, au moins pour +rendre le déchiffrement des messages plus longue, &quot;noyer le poisson&quot;.</li> +</ul> +<p>Si vous êtes intéressé(e)s, faites moi signe, je me ferais un plaisir de vous +expliquer ce qui n'est pas si complexe et vise à laisser dans la sphère privée +ce qui devrait l'être à priori.</p> +<p>Une manière simple de se protéger est d'installer Thunderbird avec Enigmail et +de le configurer correctement. Ce n'est pas très compliqué et permet d'avoir +des échanges chiffrés. <a class="reference external" href="https://emailselfdefense.fsf.org/fr/">Référez vous à ce guide</a> pour des instructions pas à pas.</p> +<p>La clé publique pour me contacter est <a class="reference external" href="/static/alexis.notmyidea.org.asc">0x078805D867F56F12</a>. Et +vous ?</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 autour (<a class="reference external" href="https://supporters.eff.org/donate">Electronic +Fronteer Fondation</a>, <a class="reference external" href="https://tails.boum.org/contribute/how/donate/index.fr.html">Tails</a>, <a class="reference external" href="https://support.laquadrature.net/">La quadrature +du net</a> en france ou d'autres…)</p> +<link href="http://vjs.zencdn.net/4.12/video-js.css" rel="stylesheet"> +<script src="http://vjs.zencdn.net/4.12/video.js"></script> +<video id="MY_VIDEO_1" class="video-js vjs-default-skin" controls + preload="auto" width="640" height="264" poster="MY_VIDEO_POSTER.jpg" + data-setup="{}"> + <source src="https://citizenfour.thecthulhu.com/citizenfour.mp4" type='video/mp4'> + <p class="vjs-no-js">To view this video please enable JavaScript, and + consider upgrading to a web browser that <a + href="http://videojs.com/html5-video-support/" target="_blank">supports + HTML5 video</a></p> +</video>Language2015-05-01T00:00:00+02:002015-05-01T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2015-05-01:/language.html<blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux …</p></blockquote><blockquote class="epigraph"> +<p>Nous savons tous que le fait d'obliger les fonctionnaires internationaux, +diplomates ou ministres à s'exprimer dans une langue qui n'est pas la leur +équivaut à les placer en situation d'infériorité. <strong>Cela les prive de la +capacité de nuance et de raffinement</strong>, ce qui revient à faire des +concessions à ceux dont c'est la langue maternelle.</p> +<p>Aussi nous savons tous que les concepts qui paraissent similaires sont +souvent différents d'une civilisation à l'autre. Les mots expriment une +culture, une façon de penser et une vision du monde.</p> +<p class="attribution">&mdash;M. Boutros Boutros-Ghali, ancien secrétaire général des Nations Unies</p> +</blockquote> +<p>Je me surprends à préférer le français pour m'exprimer au lieu de l'anglais, +notamment au niveau des articles non techniques.</p> +<p>Il y a quelques années, alors que je terminais mes études en Angleterre et que +je commençais à travailler pour Mozilla, on me proposait de venir aux +États-Unis, ce que j'ai refusé parce qu'exprimer mes points de vue de manière +fine m'était trop difficile dans une langue qui n'était pas la mienne.</p> +<ul class="simple"> +<li>Cela me permet de pouvoir tenir des discours avec des positions et un +argumentaire &quot;fin&quot;, ce qui me serait beaucoup plus difficile dans une langue +que je maitrise moins;</li> +<li>Sans même parler d'argumentaire, les mots utilisés dans ma langue maternelle +me permettent de manœuvrer plus finement et de faire passer des idées de +manière plus efficace;</li> +<li>J'ai l'impression de pouvoir engager plus facilement avec les gens qui +m'entourent géographiquement, par exemple par rapport à la communauté +technophile / pythoniste francophone.</li> +<li>Même si mon niveau d'anglais à progressé, ce n'est pas nécessairement le cas +de mes interlocuteurs.</li> +</ul> +<p>Par contre, cela nuit clairement à engager avec d'autres personnes dont la +langue n'est pas la mienne, dans tels cas, traduire les contenus intéressants +vers l'anglais semble une solution (chronophage).</p> +Quel métier, quelle utilité ?2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/quel-metier-quelle-utilite.html<p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est …</p><p>Aujourd'hui, mon métier est d'être développeur d'applications. Imaginer des +solutions techniques pour faire marcher des logiciels, puis écrire les lignes +de code nécessaires.</p> +<p>Être Développeur n'est pas un métier qui a du sens en lui même (comme peut +l'être le métier d'instituteur/rice par exemple). Tout comme lorsque l'on est +écrivain il est important de se poser des questions sur les textes que l'on +produit, pour qui et dans quel but; il est important de se questionner sur +l'utilité du métier de développeur, et sur l'utilisation des contenus produits.</p> +<p>Je suis un développeur parce que je défends certaines valeurs. Les valeurs du +partage de connaissances, de la collaboration, et de l'émancipation.</p> +<p>Je suis aussi développeur parce qu'il me plait de créer des contenus à partir +de &quot;pas grand chose&quot;. La <em>magie</em> de la création logicielle m'anime, parce que j'ai +l'impression qu'il est possible de faire des choses géniales à partir de ce &quot;pas +grand chose&quot;. Donnez moi un ordinateur et je vous crée une application de +partage de semences paysannes. Un peu comme il est possible de donner une +feuille de papier à un dessinateur pour se retrouver avec un univers magnifique +couché sur papier.</p> +<p>Je me rends compte qu'au fur et à mesure des années, je me laisse ramollir, +absorber par le quotidien et me retrouve à ne plus me poser de questions +quant à l'utilité de mon métier. Pourquoi est-ce que je code ? À qui cela sert +il ? Quelle est ma motivation réelle ?</p> +<p>En travaillant pour Mozilla, on pourrait croire que ce problème est résolu de fait, +puisque après tout, Mozilla, c'est les &quot;protecteurs du web&quot;, des +gentils, et qu'on essaye nécessairement de faire les choses bien…</p> +<div class="section" id="l-omnipresence-technologique"> +<h2>L'omniprésence technologique</h2> +<p>Je ne suis pas convaincu qu'utiliser la technologie de la manière dont on le +fait actuellement est systématiquement une bonne chose:</p> +<p>Depuis 2 ans quasiment maintenant, Mozilla travaille sur un système +d'exploitation mobile, un remplaçant pour les iphones et androides, qui utilise +cette fois ci les technologies du web. Les avantages sont multiples, et le +principal intérêt est de faire un téléphone qui ne soit pas au service +des &quot;gros&quot; du Web mondial (Google et Apple).</p> +<p>Ces &quot;ordiphones&quot; à destination des pays dits &quot;émergents&quot; sont d'ailleurs +construits à faible coût — toujours de manière honteuse, pour la plupart en +chine, dans les mêmes chaines de production que les autres téléphones, mais +c'est un autre débat.</p> +<p>L'idée, assez intéressante d'un point de vue marché (les pays en question +n'ayant que peu de périphériques actuellement semblent un terrain propice à la +diffusion des &quot;ordiphones&quot;), est de donner accès à la technologie, au Web à ces +pays émergents.</p> +<p>L'accès à la technologie pour tous me semble relever de la chimère +productiviste: je conçois que la technologie puisse être un pas en avant assez +fou, notamment lorsque l'on connaît la richesse des contenus qu'on peut trouver +sur le web, mais cette richesse vient aussi avec un certain coût, que nous +avons actuellement du mal, en tant qu'utilisateurs, à contrôler et à mesurer. +Les gens sont beaucoup beaucoup trop connectés.</p> +<p>Je le suis par exemple bien plus souvent que ce que je voudrais l'admettre, que +ce soit pour regarder un film, lire mes emails, communiquer avec des amis, +faire de l'associatif, écrire du code, des billets sur ces carnets…</p> +<p>Cette technologie, omniprésente dans nos vies, je ne sais pas si c'est un +futur que je souhaite partager.</p> +<p>Pour prendre un autre exemple, les bienfaits de la technologie ne viennent pas +seuls. Les réseaux sociaux, qui constituent une bonne part de l'utilisation du +Web, relèvent du culte de la personnalité, de l'individualisme, et ce n'est pas +ce développement que je souhaite pour notre société.</p> +<p>L'idée de base du Web, le fait de faire une toile de connaissances ouverte et +partagée entre tous est en train, petit à petit, de glisser vers l'idée d'un +outil de relai de l'information, où tout va vite, où l'on ne prends guère +plus le temps de lire autre chose que les titres des quotidiens, ou des +&quot;tweets&quot; de cent vingt caractères…</p> +</div> +<div class="section" id="des-outils-utiles"> +<h2>Des outils utiles</h2> +<p>Bon an, mal an, je pense quand même que la technologie puisse être un vecteur +d'émancipation. Plus spécifiquement, je crois qu'il ne faut pas laisser +l'utilisation de la technologie aux &quot;gros&quot;, aux entreprises, aux états ou +&quot;spécialistes&quot;.</p> +<p>Il est important de ne pas laisser ceux que l'on combat s'emparer des &quot;outils +du pouvoir&quot;. La science, la technologie ou les médias sont autant de champs +qu'il est important de défendre, de conserver, de s'approprier.</p> +<p>Un des objectifs que je me fixe, pour les années à venir, ce que j'ai envie de +créer, c'est à la fois des outils utiles pour les organisations, mais aussi +éduquer à ces outils.</p> +<p>Parce que l'éducation populaire ne s'arrête pas aux frontières du numérique, +parce qu'il est important de se battre avec les mêmes outils que ce monde que +l'on cherche parfois à combattre.</p> +<p>Les outils sur lesquels j'ai envie d'être amené à travailler sont des outils +qui favorisent et questionnent la collaboration.</p> +<p>Des outils comme etherpad par exemple, révolutionnent la manière de prendre des +notes en commun, et il reste énormément à faire sur le web à ce propos.</p> +<p>Nombre d'associations me demandent de plus en plus souvent ce qu'il en est de +Daybed, et de quand est-ce qu'on va pouvoir utiliser un système de génération +de formulaires en ligne, qui ne soit pas centré sur les services de google…</p> +<p>Allez, au boulot !</p> +<p>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, <a class="reference external" href="https://blog.notmyidea.org/travailler-moins-pour-mieux-travailler-fr.html">sur le sens du travail et +de l'informatique</a>, ça fait du bien :)</p> +</div> +Retours sur deux ans à Mozilla2014-07-29T00:00:00+02:002014-07-29T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2014-07-29:/retours-sur-deux-ans-a-mozilla.html<div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud …</p><div class="admonition note"> +<p class="first admonition-title">Note</p> +<p class="last">Ça fait un bail que j'ai cet article en cours de rédaction, et je me dis que +je dois le poster maintenant, sinon je ne le ferais jamais (saloperie de +perfectionnisme ?)</p> +</div> +<p>Il y à deux ans et demi, en décembre, je commençais à travailler chez +Mozilla, dans l'équipe &quot;Cloud Services&quot;.</p> +<p>Depuis, énormément de choses ont évoluées, tant en ce qui concerne les +objectifs de Mozilla (avec l'arrivée de FirefoxOS) que le travail que +j'effectue au jour le jour. Pour autant, mes objectifs personnels restent +intacts.</p> +<p>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 <a class="reference external" href="ziade.org">Tarek</a> par exemple.</p> +<p>Ç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 !</p> +<div class="section" id="services"> +<h2>Services</h2> +<p>Le principal de mon travail a été de construire des outils. Je suis le +mainteneur de <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a>, un +utilitaire qui vient se greffer par dessus <a class="reference external" href="http://docs.pylonsproject.org/projects/pyramid/en/latest/">le framework python pyramid</a> pour +vous simplifier la vie et créer des services web; J'ai travaillé un peu +sur un outil de gestion des processus nommé <a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a>, et également sur un outil de +montée en charge dénommé <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a></p> +<p>Au tout début, j'ai travaillé sur un concept de <a class="reference external" href="https://github.com/mozilla-services/tokenserver">serveur de +tokens</a>. L'idée était de +désolidariser l'authentification des services web des services eux mêmes.</p> +<p>L'idée est (je pense) bonne mais le service n'a pas été utilisé durant plus de +deux ans. La raison étant principalement que Sync, pour lequel le serveur de +tokens a été écrit, a subi des changements majeurs (qui sont rentrés en +production il y a quelques semaines)</p> +<p>Circus est né de besoins découverts via le token server, et il m'a +personnellement beaucoup appris. Le token server est finalement utilisé dans la +nouvelle version de Sync qui est rentrée en production il y a peu.</p> +</div> +<div class="section" id="marketplace-chouette-on-va-casser-du-serveur"> +<h2>Marketplace (&quot;chouette, on va casser du serveur&quot;)</h2> +<p>Après 6 mois à travailler à Services, Tarek et moi avons commencé à rejoindre +l'équipe du Marketplace pour faire un travail d'&quot;audit de performance&quot;.</p> +<p>L'idée était de prêter main forte à l'équipe du marketplace, mais les détails +étaient alors assez flous. Le code est assez indigeste au premier abord, ce qui +m'avait alors pas mal refroidi. La raison principale étant que le code est +utilisé à la fois par <cite>addons.mozilla.org</cite> et par <cite>marketplace.firefox.com</cite>, +rendant les choses souvent un peu plus compliquées qu'il ne faudrait.</p> +<p>Cet &quot;audit&quot; a été l'occasion de travailler sur des outils de montée en charge +assez sympa, qui ont donné naissance à un projet qu'on utilise assez souvent +maintenant, <a class="reference external" href="https://github.com/mozilla-services/loads">Loads</a>.</p> +<p>Énormément d'efforts sont fait pour aller dans la bonne direction et faire en +sorte que le code soit plus facile à maintenir et que le projet soit plus +facile à aborder. D'ailleurs, pas mal de copains djangonautes français +travaillent dessus (salut <a class="reference external" href="http://virgule.net">Mathieu</a>, Yohan, <a class="reference external" href="http://larlet.fr">David</a> et <a class="reference external" href="http://mathieu.agopian.info">Mathieu Agopian</a>!)</p> +<p>Une partie de notre plan a été de sortir certaines fonctionnalités du code +actuel, pour en faire quelque chose de plus facile à maintenir et de moins +imbriqué.</p> +</div> +<div class="section" id="la-communaute"> +<h2>La Communauté</h2> +<p><a class="reference external" href="https://github.com/mozilla-services/circus">Circus</a> et <a class="reference external" href="https://github.com/mozilla-services/cornice">Cornice</a> sont +deux outils qui semblent utiles à la communauté. J'ai eu des retours très +positifs sur Cornice, et j'essaye de le faire évoluer dans la direction qui me +semble propice.</p> +<p>D'ailleurs, Cornice est utilisé (par <a class="reference external" href="http://blog.mathieu-leplatre.info/pages/about.html">Mathieu L.</a> +— encore un —, <a class="reference external" href="http://twitter.com/natim">Rémy</a> et moi) actuellement pour coder +<a class="reference external" href="https://github.com/spiral-project/daybed">Daybed</a> un service de validation +de formulaires, mais ça sera l'objet d'un futur billet.</p> +<p>Circus commence à recevoir des contributions de plus en plus intéressantes, et +à être utilisé en interne chez nous et chez d'autres, donc c'est une +extrêmement bonne nouvelle.</p> +</div> +<div class="section" id="talkilla-loop"> +<h2>Talkilla / Loop</h2> +<p>Après quelques temps, j'avais envie d'apprendre de nouveau. Python c'est génial +mais c'était devenu ma &quot;zone de confort&quot;. J'adore découvrir des choses, donc +c'était le moment de faire en sorte que ça continue!</p> +<p>C'était aussi l'occasion de travailler avec <a class="reference external" href="https://nicolas.perriault.net/">Nicolas</a> et <a class="reference external" href="http://monkeypatch.me/blog/">Romain</a>. +Je suivais le projet Talkilla de plus ou moins loin depuis quelques mois, +c'était donc l'occasion à ne pas manquer.</p> +<p>En rentrant dans cette équipe, je cherchais principalement à avoir un projet +visible pour les utilisateurs finaux. Refaire un peu de frontend, apprendre +à faire du JavaScript propre et découvrir de nouvelles personnes.</p> +<p>J'y ai aussi récupéré une équipe qui essaye de suivre les principes de +l'agilité et qui est sur mon fuseau horaire (pour la plupart). Le rêve.</p> +<p>L'idée derrière Talkilla est d'utiliser la technologie de communication pair +à pair dans les navigateurs (WebRTC) pour faire des appels audio / vidéo. En +d'autres termes, c'est un peu transformer votre firefox en téléphone, sauf que +personne ne peut espionner ce qui se passe entre vous et l'autre bout du fil.</p> +<p>A peine arrivé dans le projet (peut-être un mois et quelques après mon +débarquement) le choix a été fait de tout réécrire depuis zéro, dans un projet +qui se nomme actuellement &quot;Loop&quot;, qui veut proposer la même chose, mais inclus +directement dans Firefox.</p> +<p>C'est en bonne voie, on a quelque chose qui fonctionne dans nightly, et le code +du serveur fonctionne pas mal. Le code du serveur est ici: +<a class="reference external" href="https://github.com/mozilla-services/loop-server">https://github.com/mozilla-services/loop-server</a>.</p> +<p>Un client est en train d'être implémenté dans Firefox et un autre en tant +qu'application pour FirefoxOS. Le boulot ne s'arrête pas de pleuvoir, mais je +pense qu'on va dans une direction intéressante.</p> +<p>Pour être complètement terminé, il faudrait qu'on soit capable de se passer +complètement de notre provider, TokBox (que l'on utilise en tant que relai +média), pour que n'importe qui puisse choisir d'utiliser son propre serveur +STUN / TURN et installe son serveur loop chez lui.</p> +<div class="section" id="le-travail-a-distance"> +<h3>Le travail à distance</h3> +<p>Quand j'ai commencé à travailler à Mozilla, j'ai décidé de venir m'installer +à Paris. La plupart des personnes de mon entourage ont d'ailleurs fait des gros +yeux, parce qu'ils connaissaient mon avis sur la ville en question, mais casser +des préjugés n'est jamais une mauvaise chose.</p> +<p>Après deux ans passés à Paris, j'ai décidé de partir m'installer à Rennes, +puisque de toute manière, la plupart de mon travail s'effectue au jour le jour +à distance. En d'autres termes, la plupart de mon équipe n'est pas à coté de +moi quand je travaille, ce qui veut dire que je peux travailler depuis +n'importe où.</p> +<p>Ce qui fonctionne pour moi, c'est de ne quasiment jamais travailler depuis la +maison. J'utilise <a class="reference external" href="http://www.lacantine-rennes.net/">un espace de coworking</a> +qui est un moyen de garder ma vie perso séparée de ma vie privée et de +rencontrer des gens passionnés par ce qu'ils font.</p> +<p>Depuis que je suis arrivé à Rennes, Rémy a commencé à travailler avec moi, et +c'est un réel bonheur que de pouvoir partager des journées de travail. On +&quot;pair-prog&quot; énormément et j'ai l'impression d'avoir un boost dans ma +productivité quotidienne.</p> +</div> +<div class="section" id="enseignements"> +<h3>Enseignements</h3> +<p>Mozilla est ma première expérience professionnelle, et par conséquent, je +manque nécessairement de recul sur ce qui est acceptable et ce qui ne l'est +pas. D'une manière générale, avoir un environnement de travail basé sur la +confiance est réellement appréciable (La première réaction des gens quand je +dis que je peux travailler à distance, c'est de me demander comment ils font +pour être sur que je travaille. Et la réponse est… il n'y en a pas).</p> +<p>J'ai encore un peu de mal à savoir quels indicateurs utiliser pour savoir si je +suis &quot;productif&quot; ou non, mais j'ai globalement l'impression que je manque de +concentration et de discipline: beaucoup d'interruptions n'aident pas à se +concentrer.</p> +<p>La motivation fluctue aussi énormément: un jour on est super motivé, un autre +c'est juste impossible de la trouver. Après quelques expérimentations, le mieux +(pour moi) est d'avoir des horaires fixes, pour pouvoir séparer le travail du +reste, de ne pas hésiter à faire des pauses et d'écouter un peu ses envies et +son corps (si je suis crevé, ça ne sert à rien de se lever pour aller +travailler, il vaut mieux se reposer un peu pour être plus efficace ensuite, +par exemple).</p> +<p>J'ai essayé de tirer quelques enseignements de ces deux années:</p> +</div> +</div> +<div class="section" id="malheureusement-le-code-n-est-pas-propre"> +<h2>Malheureusement, le code n'est pas propre</h2> +<p>Je me rends compte que bien souvent je suis assez déçu de la qualité du code +que je regarde. Principalement parce que je ne suis pas capable de le +comprendre rapidement. Spécifiquement, ça m'est arrivé avec certaines parties +de <a class="reference external" href="https://github.com/mozilla/zamboni">Zamboni</a>, le code du <a class="reference external" href="http://marketplace.firefox.com">Marketplace</a> dont je parlais plus haut, avec certaines +parties de Talkilla ou alors le code de Firefox lui même.</p> +<p>C'était extrêmement frustrant pour moi de découvrir que le code écrit à Mozilla +n'était pas exemplaire. Tout le code qui est ajouté à l'heure actuelle est +revu, corrigé et validé par des pairs, mais un certain nombre de projets ont un +historique assez lourd qui rends leur structure complexe.</p> +<p>Je réalise donc que mon travail n'est pas uniquement de savoir écrire du code +propre, mais également de réussir à comprendre du code que je considère comme +&quot;sale&quot; (quitte à l'améliorer au passage !).</p> +<p>Et c'est pas du gâteau; je m'attendais à réussir à comprendre des projets +complexes facilement, mais aucun miracle de ce coté là. Il faut réussir +à rester concentré pendant suffisamment longtemps pour pouvoir tirer tous les +fils et commencer à démêler… Pas facile !</p> +</div> +<div class="section" id="apprendre-est-un-processus-actif"> +<h2>Apprendre est un processus actif</h2> +<p>Il est facile de passer à coté de l'apprentissage. Être entouré de gens +talentueux ne suffit pas pour continuer à apprendre.</p> +<p>Savoir reconnaitre un échec est nécessaire. Dire que l'on comprends pour éviter +de passer pour un idiot est un biais qui se prends assez rapidement, et qu'il +faut éviter à tout prix.</p> +<p>Surtout au début, c'était une erreur que je faisais énormément, une question +d'égo probablement.</p> +<p>Il y a une espèce de honte de ne pas savoir, alors que tout le monde autour +sait ou en tout cas semble savoir. Bien souvent, les gens autour ne savent pas +non plus, ce qui mène à des discussions de comptoir, sans trop savoir pourquoi.</p> +<p>Connaître ses limites techniques est un bon début pour pouvoir les surpasser. +Chercher à les rencontrer est un processus actif.</p> +<p>Le manque de temps m'empêche bien souvent de pouvoir prendre un livre technique +et de pouvoir l'apprécier. Je ne sais pas exactement pourquoi, peut être par +sur-dose, mais je n'ai ouvert que quelques rares livres techniques durant ces +deux années. Et j'aimerais bien que ça change !</p> +</div> +<div class="section" id="assez-bien-est-suffisant"> +<h2>&quot;Assez bien&quot; est suffisant</h2> +<p>La culture de l'excellence se mets parfois au milieu du chemin. On oublie +souvent que &quot;le mieux est l'ennemi du bien&quot;.</p> +<p>Rien ne sert de faire des commits parfaits tout le temps. Quand j'ai besoin de +&quot;hacker&quot; sur un projet, je ne voulais d'abord pas tout péter, par peur de ne +plus m'y retrouver.</p> +<p>Mon approche actuelle est bien différente: on mets les mains dans le cambouis +jusqu'à ce que ça marche, et ensuite on répare les dégâts. Enfin… dans une +certaine mesure hein !</p> +</div> +<div class="section" id="ecrire-des-boites-a-outils-et-non-pas-des-frameworks"> +<h2>Écrire des boites à outils et non pas des frameworks</h2> +<p>Écrire des frameworks force les utilisateurs à les utiliser, et à les connaitre +dans les moindres recoins. Heureusement, il existe déjà énormément de +frameworks qui pour la plupart font très bien leur travail. Ce qui nous manque +ce n'est pas plus de frameworks, mais bel et bien plus de boites à outils.</p> +<p>Une boite à outil prends un problème bien défini et propose une solution pour +ce problème. Une boite à outils est, en mon sens, ce qu'on appelle une +bibliothèque. Pas besoin de réécrire tout votre projet pour utiliser ma +nouvelle bibliothèque afin de profiter des fonctionnalités qu'elle apporte +(alors que c'est le cas avec un framework, justement).</p> +</div> +<div class="section" id="etre-le-moteur-de-son-propre-changement"> +<h2>Être le moteur de son propre changement</h2> +<p>Facile à dire, héhé ! D'une manière générale, je me rends compte qu'il est +facile de se plaindre sans pour autant être moteur du changement que l'on +souhaite voir arriver.</p> +<p>Ça vaut le coup de se donner la peine de faire changer les choses, surtout +à Mozilla, parce que le changement n'est pas seulement vu d'un mauvais œil.</p> +<p>Pour que les choses évoluent, il faut être force de proposition. Se plaindre +n'a jamais servi à rien si ce n'est pas suivi d'actes ;)</p> +<p>Je dis de temps en temps que Mozilla est une &quot;do-o-cratie&quot; (celui qui fait +à raison), et je le pense de plus en plus. Quand j'ai envie que quelque chose +soit fait, et bah… il faut le faire !</p> +</div> +<div class="section" id="ne-pas-chercher-a-avoir-raison"> +<h2>Ne pas chercher à avoir raison</h2> +<p>Peu importe qui a raison, l'important n'est pas de chercher à montrer que tu +sais, mais de trouver ce qui est juste. Ça parait peut être évident, mais bien +souvent on cherche à se mettre en avant, au détriment du projet… Allez, gardons +nos égos de coté ;)</p> +</div> +<div class="section" id="arreter-le-negativisme"> +<h2>Arrêter le négativisme</h2> +<p>Il est très facile de se laisser embarquer dans le négativisme. Il y a toujours +des choses qui ne vont pas, et probablement il y en aura toujours. Ce ne sont +pas des raisons suffisantes pour perdre le moral. Identifier les points faibles +est important est permet de savoir ce qu'il est nécessaire d'améliorer, mais +regarder les choses du coté positif (et il y en a nécessairement un !) est +indispensable !</p> +<p>À plusieurs reprises je me suis retrouvé dans des crises de négativisme, pour +un tas de raisons différentes. La meilleure manière de s'en sortir: en causer +et trouver des solutions, prendre le problème à bras le corps, et ne pas +considérer que c'est un problème sur lequel on a aucune prise possible.</p> +<div class="section" id="la-suite"> +<h3>La suite ?</h3> +<p>Je n'ai aucune idée d'à quoi va ressembler la suite, et c'est justement ce que +j'apprécie et qui m'effraie en même temps…</p> +<p>Je fais actuellement énormément de Javascript et je travaille sur des +projets qui semblent avoir plus de sens qu'avant (même si je vois déjà des +choses que je souhaiterais améliorer, mais chaque chose en son temps). Donc +techniquement j'apprends et dans ma quête de faire des produits qui touchent un +utilisateur.</p> +<p>Depuis quelques semaines, je peux travailler une journée par semaine sur un +projet qui me tiens vraiment à cœur: daybed (<a class="reference external" href="http://daybed.rtfd.org">http://daybed.rtfd.org</a>). +L'objectif est de faire en sorte que le projet avance et soit utilisé au sein +de mozilla.</p> +<p>Avant toute autre chose, il faudra faire des changements de &quot;pitch&quot; pour qu'il +soit plus simple d'expliquer ce que Daybed souhaite faire, mais… c'est une autre +histoire.</p> +</div> +</div> +Des carnets d'esquisse2013-08-16T00:00:00+02:002013-08-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-08-16:/des-carnets-desquisse-fr.html<p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir …</p><p>Je me rends compte que je n'écris pas si souvent que ça ici, principalement +parce que je me sens obligé d'y écrire en Anglais, mais aussi parce que je le +considère comme un espace ou les choses doivent êtres abouties et non pas +expérimentales.</p> +<p>Des fois j'ai cette envie d'ouvrir un &quot;carnet&quot; et d'y jeter juste quelques +notes. Pas grand chose: mes quelques pensées ou alors des liens 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.</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'accueil, mais vous pouvez les +trouver dans <a class="reference external" href="https://blog.notmyidea.org/category/notes.html">la section notes</a>.</p> +<p>Je ne sais pas encore si il s'agit du meilleur endroit pour ça, mais peu importe, +essayons. A bas la pudeur rédactionelle.</p> +<p>J'ai du au passage chambouler un peu vos agrégateurs, pardonnez moi :)</p> +<div class="section" id="le-retour-des-commentaires"> +<h2>Le retour des commentaires</h2> +<p>Au passage, je ne me rappelle plus quand exactement, mais j'avais décidé de +supprimer les commentaires de cet espace. Paf, apu. Comme ça, sans prévenir.</p> +<p>Les raisons en étaient à la fois techniques (je ne souhaitait pas avoir recours +à disqus qui est un silo propriétaire de plus) et parce que je considérais que +les commentaires n'avaient que peu d'intérêt. Ceci dit, le manque d'échange me +manque; j'aimerais bien savoir ce que vous pensez de ce que j'écris des fois, +et avoir des débats si nos opinions divergent.</p> +<p>Et puis bon, partager dans un seul sens, c'est un peu dommage !</p> +<p>Il est maintenant possible, avec <a class="reference external" href="http://talka.tv">talka.tv</a> d'héberger soi +même ses commentaires. J'ai dans l'idée d'héberger une instance de ce service +sur <cite>discus.notmyidea.org</cite>, 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 !)</p> +</div> +Des profils de confiance partout et pour tout ?2013-04-02T00:00:00+02:002013-04-02T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2013-04-02:/confiance-fr.html<p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site …</p><p>Depuis un petit moment déjà, le site covoiturage.fr est passé &quot;payant&quot;. Il est +désormais possible (et même obligatoire) de payer les trajets à l'avance, et en +ligne, laissant au passage quelques royalties au site en question.</p> +<p>Précédemment, il était possible de retrouver le numéro des conducteurs +sur le site et de les appeler soi même, chose maintenant automatisée.</p> +<p>Dès que cette décision à été prise, il y a eu des émules. Le site <a class="reference external" href="http://covoiturage-libre.fr">Covoiturage +Libre</a> à été d'ailleurs créé pour faire en sorte +de garder &quot;l'esprit&quot; du covoiturage. Bref ça jasait dans les chaumières.</p> +<p>Il y à peu, j'ai reçu un <em>couriel</em> contenant un lien vers une vidéo d'<a class="reference external" href="http://www.covoiturage.fr/blog/2013-confiance">une +conférence animée par le fondateur de covoiturage.fr</a>.</p> +<p>Ils semblent vouloir parler de confiance, alors ça m'intrigue, d'autant que la +présentation en question est donnée lors d'un évènement TEDx, auquel j'accorde +un certain crédit.</p> +<div class="section" id="un-capital-de-confiance"> +<h2>Un &quot;capital de confiance&quot;</h2> +<p>Cette vidéo parle entre autres du <em>capital de confiance</em> que nous pouvons +nous accorder les uns aux autres; et notamment du fait que ce capital de +confiance n'est malheureusement pas partagé au dela d'un cercle de +connaissances assez limité. Il reste dans notre cercle de connaissances proche, les +amis des amis.</p> +<p>C'est donc une chose regrettable, parce que ça nous fait perdre du temps (et +donc, <em>ohmygod</em> de l'argent) à tous pour construire cette confiance. Temps qui +pourrait être mieux employé.</p> +<p>La solution proposée, attention les yeux, est de faire appel un maximum aux +profils en ligne, une manière de &quot;prouver au monde&quot; que nous sommes des +personnes de confiance. Selon les termes de la présentation, nous pourrions +alors tous devenir des &quot;super héros du trust&quot;, des &quot;trustman&quot;.</p> +<p>Grâce à des profils en ligne ou monsieur et madame tout le monde pourraient +aller voter et donner leur avis sur les personnes qu'ils ont rencontré.</p> +</div> +<div class="section" id="l-avenement-du-paiement-en-ligne"> +<h2>L'avènement du paiement en ligne</h2> +<p>On nous dit maintenant que le paiement en ligne est une révolution, un moyen de +tracer le fait qu'il y à effectivement eu une transaction entre deux personnes; +et que donc il en deviendrait un outil pour vérifier que la confiance est bien +légitime, et non pas créée de toute pièce sur le profil de la personne en +question.</p> +<p>Plu</p> +<p>Plus exactement, ce qui est dit est que le paiement en ligne permet de +justifier qu'il y a bien eu transaction entre deux personnes, et que donc les +commentaires et &quot;notations&quot; effectuées sont donc légitimes.</p> +</div> +<div class="section" id="ce-n-est-pas-un-probleme-de-confiance"> +<h2>Ce n'est pas un problème de confiance !</h2> +<p>Bien que j'arrive à suivre le raisonnement, il soulève certaines questions :</p> +<p>Si j'accorde de la confiance à quelqu'un dans mon cercle de connaissances, +c'est justement parce qu'il fait partie de ce cercle de connaissances. Pas +parce qu'une personne que je ne connait pas me dit qu'il s'agit d'une personne +de confiance. En d'autres termes, <strong>pourquoi ne garderions nous pas ces +relations privilégiées de personne à personne ?</strong></p> +<p>Dans le cadre du covoiturage, j'arrive à comprendre le raisonnement du paiement +<em>à l'avance</em>, pour avoir souvent entendu parler de désistements à la dernière +minute de la part des voyageurs. Le paiement à l'avance permet d'éviter ce +genre de désagréments.</p> +<p>Mais cela n'as rien à voir avec la confiance, il s'agit d'engagement de la part +des deux parties.</p> +<p>Et c'est bien ce qui semble poser problème: lorsqu'on s'attend à partager le +prix d'un trajet avec quelqu'un, c'est bien d'avoir quelque chose qui nous +y engage. J'aime beaucoup l'idée de payer une fois dans la voiture, de garder +cette transaction manuelle; et de laisser peu de place au paiements en ligne +dans cette histoire, mais je n'ai pas d'autre solution miracle.</p> +<p>En tout cas, la question n'est pas la question de savoir avec qui on embarque, +mais bel et bien la question de l'engagement des deux parties.</p> +<p>Nous sommes malheureusement dans une société qui est dirigée par la peur. On +à peur de se faire agresser par le gars qui tends le pouce sur le bord de la +route, peur de se faire envoyer un produit qui ne fonctionne pas via Amazon, +etc.</p> +<p>En poussant l'idée dans ses retranchements, j'aurais bientôt peur de mes +voisins alors je ne leur parlerais plus, parce qu'ils n'ont pas leur profil +disponible en ligne ou parce que quelqu'un à eu une mauvaise expérience avec +eux ?</p> +<p>Exposer des choses qui relèvent de ma vie privée en ligne de la sorte me +pose des problèmes éthiques: d'abord parce que je ne veux pas juger les gens +a priori, ensuite parce que l'expérience d'une personne n'est peut-être pas +représentative, tout simplement.</p> +<p>Donc non, ce n'est pas un problème de confiance, il s'agit d'un problème +d'engagement, dans le cadre du covoiturage, et les profils en ligne n'ont rien +à faire la dedans. Le principe du paiement à l'avance me semble intéressant, +mais il n'est à mon avis pas lié au profils en ligne.</p> +<p>La vidéo termine sur un &quot;libérez la valeur de la confiance&quot;. Oui, mais la +libérer pour qui ? Quels sont les problèmes liés à cette confiance rendue +nécessaire partout et pour tout ? Cela ne nous ferait-il pas évoluer uniquement +dans des cercles fermés ? Quelle place laisser à l'inconnu, à la surprise ?</p> +<p>Cette volonté de &quot;confiance partout&quot; semble découler tout droit des délires +sécuritaires que l'on nous sert à toutes les sauces. Et maintenant cela +serait rendu accessible à tous grâce à &quot;l'intelligence collective&quot;; gommant au +passage les différences de valeur; Préférant éviter de rencontrer les inconnus +aux profils &quot;légers&quot;.</p> +<p>Je sais pas vous, mais elle me fait peur cette idée.</p> +</div> +Lifestyle2012-11-05T00:00:00+01:002012-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-11-05:/lifestyle-fr.html<p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre …</p><p>Eh beh, c'est pas aussi simple qu'il y parait de trouver un environnement qui +permette autant de travailler correctement et de ne pas s'enfermer dans le +boulot.</p> +<p>Surtout si comme moi vous cherchez à limiter vos déplacement, que vous aimez +vivre avec peu et cherchez à trouver un équilibre entre une vie connectée et +une vie <em>réelle</em> (oui, celle avec des vrais gens qui ont d'autres +préoccupations que l'informatique !). Comment réussir à trouver un juste +milieu entre le geek inconditionnel et le bon vivant, qui à du temps à +consacrer à autre chose qu'à son travail ?</p> +<div class="section" id="voyages"> +<h2>Voyages</h2> +<p>Un des premiers trucs que j'ai trouvé surprennant en arrivant à Mozilla, c'est +la fréquence des voyages que l'on peut être amené à avoir. Ah, c'est pour la +bonne cause, c'est tellement plus sympa d'avoir les collègues à coté pour +bosser, plutôt qu'à l'autre bout du monde. Mais quand même, si je le voulais, +entre les semaines de travail et les conférences, je pourrais être tous les +deux mois aux États-Unis !</p> +<p>Une aubaine, penserons certains. Voyager, c'est <em>cool</em> ! Bon, si on mets de +coté le cout écologique d'un voyage (nécessairement en avion), la chose qui me +dérange le plus c'est cette impression de venir pour repartir. Voyager, c'est +sympa, mais avoir le temps de prendre un rythme de vie différent, de rencontrer +des gens, de construire quelque chose, ça me manque.</p> +<p>Donc je décline quand je n'en ai pas l'envie, tout simplement. Je loupe des +choses intéressantes (<a class="reference external" href="http://pycon.us">PyCon</a> à Santa Clara avait vraiment l'air +chouette !), mais ça me permet également d'avoir plus de temps pour vivre là ou +j'habite, pour construire quelque chose localement. Et puis des évènements, il +y en à tellement en France et en Europe auquel je n'assiste pas que ça me fait +mal au cœur d'aller à l'autre bout du monde pour faire la même chose !</p> +<p>Bien sur, je serais amené à voyager. Et autant que faire se peut je le +ferais avec plaisir et je tenterais de rester un peu plus avant et après sur +place (plus question de faire un aller/retour en une semaine !), question de me +faire à l'atmosphère ! <a class="reference external" href="http://ziade.org">Tarek</a> est par exemple resté un mois à San Francisco +en janvier pour son dernier séjour, alors pourquoi ne pas prendre exemple ? +Tout de suite ça me parles plus.</p> +</div> +<div class="section" id="et-quand-est-ce-qu-on-arrete"> +<h2>Et quand-est-ce qu'on arrête ?</h2> +<p>Une autre chose assez difficile à gérer, c'est le temps.</p> +<p>J'ai vraiment une chance monstrueuse, celle de faire un travail qui me plait, +éthiquement et techniquement. Je pourrais y passer mes journées et mes nuits +que je n'aimerais pas moins ça (même si il m'arrive bien sur de saturer !).</p> +<p>Mais j'ai aussi d'autres envies, qui signifient aussi passer du temps +hors-ligne, parce que bizarrement, c'est là que j'ai l'impression de réfléchir +le plus. Loin de ce surplus d'informations…</p> +<p>Facile à dire.</p> +<p>D'autant que quand il est possible de travailler depuis n'importe où, +la séparation physique entre le lieu de travail et le lieu de vie tends à +disparaitre assez facilement. Et sans séparation physique, il faut une sacré +motivation pour savoir quand commencer et quand s'arrêter.</p> +<p>J'essaye de me donner une règle simple: point trop n'en faut. Aucun intérêt à +rester travailler des heures durant sans s'arrêter, ou en tout cas pas +d'intérêt à le faire de manière trop régulière. Une journée qui commence tôt +(~9h) me permet de me concentrer le matin (les collègues californiens dorment) +et d'avoir un rythme assez &quot;normal&quot;. Et puis, avec ce soleil qui commence à +inonder les terrasses, autant faire autre chose que de rester enfermé à coder +en fin d'après midi !</p> +</div> +<div class="section" id="surplus"> +<h2>Surplus</h2> +<p>Tiens, je parlais de surplus, nous y sommes. Que ça soit le surplus +d'informations ou le surplus d'objets, ça m'encombre ! Une journée, pour ma +part est faite de communications diverses, de code et de lectures (se tenir au +courant de ce qui se passe dans le monde du logiciel n'est pas une tâche des +plus facile, et qui peut facilement prendre énormément de temps).</p> +<p>Je me demande si je ne devrais pas aspirer à la frugalité de ce coté là +également. Je reçois des mails toute la journée, et mon aggrégateur rss/atom se +remplit également très vite. Mais je n'ai aucunement besoin d'avoir toutes ces +informations dans l'heure, et de les vérifier de manière fréquente. De la même +manière, j'ai simplement arrêté de lire mes flux rss.</p> +<p>Quelques (longues) fois dans la semaine semblent suffire et me permettent de +réussir à rester concentrer.</p> +</div> +<div class="section" id="resolutions"> +<h2>Résolutions</h2> +<p>Soyons fous, tentons quelque chose de nouveau, c'est le printemps ! Pas de +communication dans la matinée, je n'en ai probablement pas besoin, sauf cas +extrêmes. Le matin, c'est pour se concentrer sur le travail à faire.</p> +<p>Une fois les mails du matin dépilés (à 9h30), pas la peine de garder un œil +sur ma boite mail, j'irais y faire un tour en début et en fin d'après midi.</p> +<p>Je pense même à débrancher internet, pour éviter les interactions et pour me +concentrer, mais j'ai comme l'impression que c'est un peu trop abrupt comme +approche.</p> +<p>Aussi, définir en début de journée la liste des choses prévues, et revenir +dessus jour après jour me permettra surement d'avoir un aperçu un peu plus +global du travail accompli.</p> +<p>L'avenir dira si tout ça fonctionne :-)</p> +</div> +Pourquoi Mozilla?2012-07-16T00:00:00+02:002012-07-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-07-16:/pourquoi-mozilla-fr.html<p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi …</p><p>Depuis que j'ai commencé à bosser chez Mozilla, je me retrouve assez souvent à +expliquer ce que j'y fais. J'aime bien raconter l'histoire de Mozilla, la +mission, et comment je m'y rattache.</p> +<p>Je prends bien sur un malin plaisir à expliquer à chaque fois les tenants et +les aboutissants, aussi je me suis dit que ça pouvait avoir du sens de l'écrire +quelque part.</p> +<p>Ça parle bien sur de logiciel libre, de protection de la vie privée et de +contre-pouvoirs.</p> +<p>Je ne m'adresse pas ici aux afficionados du logiciel libre et du non contrôle +du web, mais aux potentiels intéressés, qui souhaitent comprendre ce qu'on fait +à Mozilla, pourquoi et comment, et plus particulièrement quel est le rôle que +je joue la dedans.</p> +<div class="section" id="logiciel-libre"> +<h2>Logiciel libre</h2> +<p>Une des premières choses qui vient à l'esprit des gens quand on parle de +Mozilla, et par extension de Firefox, c'est qu'il s'agit d'un logiciel gratuit. +D'un logiciel soit disant &quot;libre&quot;. Avouez que le concept est de prime abord +curieux. Un logiciel qui serait libéré, mais libéré de quoi ?</p> +<p>Je ne vais pas refaire la génèse du logiciel et du logiciel libre, mais pour +résumer et expliquer ça très grossièrement, le logiciel libre c'est pour moi +l'idée de la collaboration. &quot;Plutôt que de travailler chacun dans son coin, +construisons ensemble quelque chose qui nous sera utile à tous&quot;. Ça marche dans +le domaine de l'informatique parce qu'on est exposé à un bien commun non +matériel. Ce n'est pas parce que je te donne un logiciel que je ne l'ai plus. +La duplication est possible et elle rend la collaboration plus facile.</p> +<div class="section" id="euh-oui-mais"> +<h3>Euh, oui mais…</h3> +<p>Ok, ok. Et comment on coopère ? Derrière un logiciel, il faut écrire des lignes +de code, il faut décrire comment doit se comporter le logiciel dans l'ensemble +des cas qu'il peut rencontrer. Mais pas seulement. Beaucoup de personnes +travaillent pour faire en sorte que Firefox soit disponible dans près de 100 +langues et dialectes par exemple.</p> +<p>J'aime beaucoup penser que le logiciel libre réussit à réunir des personnes +avec des objectifs differents. Linux, qui est un logiciel libre, est par exemple +utilisé dans beaucoup de domaines très différents tels que la médecine, +l'automobile ou l'énergie.</p> +<p>Le logiciel libre est une valeur clé que nous défendons chez Mozilla.</p> +</div> +</div> +<div class="section" id="protection-de-la-vie-privee"> +<h2>Protection de la vie privée</h2> +<p>Mozilla en fait un peu sa devise. Nous ne sommes pas une entreprise, nous +n'avons aucun intérêt à enfermer les utilisateurs chez nous, et surtout nous +n'exploitons et n'exploiterons pas les données utilisateurs à des fins +commerciales. Jamais.</p> +<div class="section" id="stockage-des-donnees"> +<h3>Stockage des données</h3> +<p>Un exemple qui est frappant est celui de <a class="reference external" href="https://www.mozilla.org/en-US/mobile/sync/">Sync</a>, l'outil qui permet de +synchroniser les données de navigation entre plusieurs périphériques (Cela peut +être utile pour avoir votre historique de navigation partagé entre votre +ordinateur de bureau et un téléphone portable par exemple)</p> +<p>Les données qui sont stockées dans un service tel que sync sont cruciales: vos +mots de passe et votre historique de navigation par exemple. Imaginez ce que +des annonceurs publicitaires pourraient faire avec ces données. Il est assez +facile de connaître votre profil et donc d'ensuite faire de la publicité +ciblée à partir de ces informations. Voire pire. Donner ces données à qui fait +suffisemment pression sur vous pour les récupérer.</p> +<p>Heureusement, les données qui sont stockées sur les serveurs Sync sont +chifrées, et seul l'utilisateur a accès a la clé de chiffrement et de +déchiffrement. En d'autres termes, en ayant accès aux serveurs de Mozilla, même +de l'intérieur, je pourrais avoir accès à vos données mais je ne pourrais rien +en faire car celles-ci me sont impossibles à déchiffrer.</p> +<p>Mozilla essaye de mettre le doigt là où ça fait mal dans l'innovation web&nbsp;: la +publicité et le respect de la vie privée des utilisateurs. Facebook, Google, +Twitter sont autant d'entreprises qui gagnent de l'argent grâce à leurs +utilisateurs et à leurs données privées.</p> +<p>Cela n'est pas <em>nécessairement</em> un mal mais il me semble important d'informer +les utilisateurs d'Internet la dessus, et de leur proposer des méthodes qui +leur permettent de protéger leur vie privée.</p> +</div> +<div class="section" id="decentralisation"> +<h3>Décentralisation</h3> +<p>Un autre aspect important est le fait que vous n'avez pas besoin de dépendre des +serveurs de Mozilla si vous ne souhaitez pas en dépendre. Bien que nous +fassions tout ce qui est en notre pouvoir pour avoir des serveurs très réactifs +et capables de tenir la charge, nous ne sommes pas à l'abri de pannes. Auquel +cas il vous faudra simplement vous armer de patience.</p> +<p>Mais il est possible pour vous de maintenir votre propre serveur et de ne pas +dépendre de Mozilla pour stocker vos données privées. J'ai parlé de Sync mais +Mozilla (j'en parle un peu plus bas) travaille aussi sur un système +d'exploitation pour téléphone portable, nommé Firefox OS (anciennement Boot 2 +Gecko), et sur l'écosystème qui va avec.</p> +<p>Actuellement, si vous souhaitez synchroniser vos contacts par exemple, vous +dépendez quasiment toujours d'une autorité à qui vous ne faites peut être pas +confiance: Apple, Microsoft ou bien Google.</p> +<p>On ne vous propose pas simplement de nous faire confiance, on vous propose la +possibilité de ne faire confiance qu'à ceux à qui vous souhaitez accorder votre +confiance, et ça peut être vous si vous le souhaitez.</p> +<p>La décentralisation à ceci de bon qu'elle vous laisse le choix d'où vous +souhaitez stocker vos données.</p> +</div> +</div> +<div class="section" id="innovation-et-standardisation"> +<h2>Innovation et standardisation</h2> +<p>Mozilla, dès ses débuts, a été un laboratoire. Firefox (si je ne me trompe pas) +a été le premier navigateur à avoir des onglets. Le web, c'est cool parce que +ça bouge tout le temps ! (Edit: en fait, <a class="reference external" href="http://en.wikipedia.org/wiki/Tabbed_document_interface">ce n'était pas le premier</a>, mais l'idée est là)</p> +<p>La dernière innovation en date est Firefox OS: utilisons les technologies du +web pour créer un téléphone: utilisons le web comme plateforme, et profitons de +tout l'écosystème qui existe déjà autour de celui-ci.</p> +<p>C'est bien que ça bouge mais il faut qu'on se mette d'accord sur comment on +veut faire bouger les choses. La guerre des navigateurs a eu lieu. Ne pas +reproduire ça est parfois un challenge. La standardisation, tout le monde s'y +met.</p> +<p>On a gagné une guerre: aux utilisateurs de choisir les outils qu'ils souhaitent +et non pas aux développeurs d'imposer leurs choix.</p> +</div> +<div class="section" id="et-moi-qu-est-ce-que-je-fais-la-dedans"> +<h2>Et moi, qu'est-ce que je fais la dedans ?</h2> +<p>Je travaille dans l'équipe nommée Services. On travaille à la mise en +place de services web qui sont capables de tenir la charge, de fonctionner de +manière décentralisée.</p> +<p>Ce travail a plusieurs objectifs:</p> +<ul class="simple"> +<li>Mettre à disposition des outils pour les développeurs, leur permettant de +créer des services de bonne qualité rapidement;</li> +<li>Permettre aux utilisateurs d'héberger eux mêmes leurs propres serveurs s'ils +le souhaitent, réduisant leur dépendance a des services externes.</li> +<li>Écrire les services en question de telle manière que les utilisateurs (vous +!) puissent les utiliser sans avoir trop de tracas :)</li> +</ul> +<p>Ça semble peu, mais j'aime ce boulot. Éthiquement et techniquement. C'est ça, +pour moi, la mission de Mozilla. Si vous avez des suggestions sur ce qui +pourrait être amélioré dans les services de Mozilla en termes de protection de +la vie privée, de décentralisation et de haute disponibilité, vous savez vers +qui vous tourner !</p> +<p>La liste des projets sur lesquels je travaille ou j'ai travaillé à Mozilla pour +l'instant:</p> +<ul class="simple"> +<li><a class="reference external" href="https://github.com/mozilla-services/tokenserver">https://github.com/mozilla-services/tokenserver</a></li> +<li><a class="reference external" href="http://circus.io/">http://circus.io/</a></li> +<li><a class="reference external" href="http://powerhose.rtfd.org/">http://powerhose.rtfd.org/</a></li> +<li><a class="reference external" href="https://github.com/mozilla-services/server-aitc">https://github.com/mozilla-services/server-aitc</a></li> +<li><a class="reference external" href="http://cornice.readthedocs.org/en/latest/index.html">http://cornice.readthedocs.org/en/latest/index.html</a></li> +<li><a class="reference external" href="https://github.com/mozilla/PyBrowserID/">https://github.com/mozilla/PyBrowserID/</a></li> +<li><a class="reference external" href="http://chaussette.readthedocs.org/en/0.3/index.html">http://chaussette.readthedocs.org/en/0.3/index.html</a></li> +</ul> +</div> +Bidouille2012-04-30T00:00:00+02:002012-04-30T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-30:/bidouille-fr.html<p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de …</p><p>Bidouille bidouille bidouille.</p> +<p>Je pense que je suis un bidouilleur logiciel: j'aime bien aller farfouiller +dans le code pour comprendre comment tel ou tel programme fonctionne (ou +trop souvent comment il ne fonctionne pas !), faire des petites modifications, +tester, modifier, re-tester, tout casser, réparer …</p> +<p>Et cette bidouille, cette envie de comprendre comment les choses fonctionnent, +et depuis peu cette envie de mettre en pratique ces connaissances dépasse la +bidouille logicielle. J'ai passé une grosse partie de mon week-end à Main +d'Œuvre, où l'association <a class="reference external" href="http://www.underconstruction.fr">Under Construction</a> faisait se rencontrer le milieu de +l'éducation populaire et le milieu de la bidouille.</p> +<p>Forcement, ni une ni deux, je saute dans le bateau en marche et, n'étant ni un +très grand bidouilleur ni un très grand animateur, j'en ressort enrichi de +toutes ces rencontres, de tous ces préjugés qui tombent, et de quelques +découvertes bluffantes, des idées plein la tête.</p> +<p>J'avais entendu parler des &quot;<a class="reference external" href="http://www.reprap.org">rep-raps</a>&quot;, des +imprimantes en 3 dimensions capables de produire des pièces en plastique +mais je n'avais jamais eu l'occasion de voir le bousin en vrai. Et +c'est impressionnant. Vraiment. (&quot;Bienvenue dans le 21ème siècle !&quot;)</p> +<p>Ça laisse énormément à penser autour des questions d'émancipation +technologique, et de non dépendance envers les constructeurs, dans le milieu de +l'électro-ménager, par exemple. &quot;Ah tiens, cette pièce est cassée, je vais +aller utiliser la rep-rap du coin pour me la fabriquer&quot;. Et hop, on mets fin à +tout un cycle d'obsolescence programmée…</p> +<p>Mais au delà du défi technique et technologique, j'ai pu refaire un petit peu +d'électronique, et découvrir que j'y prends vraiment gout rapidement. Il y a +bien évidemment un coté très ludique (la led s'allume quand on la branche), +mais il y a surtout cette notion de DIY (Do It Yourself) sous jacente: une fois +que je sais comment ça fonctionne, je peux vraiment faire des choses utiles de +mes 10 doigts, réparer des petits objets, bidouiller ceux existants etc.</p> +<p>De la récupération de composants on essaye de voir ce qu'on peut faire, on a +terminé par faire un &quot;vibro-bot&quot;, un vibreur de téléphone portable monté sur +une tête de brosse à dents, faisant donc avancer cette dernière.</p> +<p>C'est pour s'amuser, c'est pas sérieux ! Pour autant, les concepts de +l'électricité sont appris et je me retrouve avec cette envie de comprendre un +peu plus ce monde de l'électronique qui, je m'en rends compte, m'échappe encore +complètement. De l'éducation à la bidouille !</p> +<p>Allez, demain c'est fer à souder, piles, leds, interrupteurs, potars et c'est +parti !</p> +Djangocong 20122012-04-16T00:00:00+02:002012-04-16T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-16:/djangocong-2012-fr.html<p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une …</p><p>Ce week-end, c'était <a class="reference external" href="http://rencontres.django-fr.org">djangocong</a>, une conférence autour de <a class="reference external" href="http://djangoproject.org">django</a>, +de <a class="reference external" href="http://python.org">python</a> et du web, qui avait lieu dans le sud, à Carnon-plage, à quelques +kilomètres de Montpellier la belle.</p> +<p>J'ai vraiment apprécié les trois jours passés avec cette bande de geeks. Je +m'attendais à des <em>nerds</em>, j'y ai trouvé une qualité d'é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 :)</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'ai eu l'occasion de discuter de projets tournant autour de +l'entraide, que ça soit pour mettre en lien des associations d'économie sociale +et solidaire (ESS) ou simplement pour que les populations <em>non tech</em> <a class="reference external" href="http://blog.notmyidea.org/quels-usages-pour-linformatique-fr.html">puissent +utiliser toute la puissance de l'outil qu'est le web</a>.</p> +<p>Au niveau du format des conférences, je ne savais pas trop à quoi m'attendre, +au vu des échos de l'an dernier, mais c'était adapté: des mini-confs de 12mn le +samedi matin + début d'aprem, en mode no-wifi pour récupérer une qualité +d'écoute. Et contrairement à mes attentes, ce n'est pas trop court. Pas mal de +retours d'expérience pour le coup, et une matinée pas vraiment techniques, mais +ça pose le décor et permet de savoir qui fait quoi.</p> +<p>Parmi l'ensemble des conférences du matin, je retiens principalement +celle de Mathieu Leplatre, &quot;des cartes d'un autre monde&quot;, qui m'a réellement +bluffée quand à la facilité de créer des cartes avec <a class="reference external" href="http://mapbox.com/tilemill/">TileMill</a>, et qui me pousse à reconsidérer le fait que &quot;la +carto, c'est compliqué&quot;. <a class="reference external" href="https://www.youtube.com/watch?v=7NPQo54NbJ8">La vidéo est (déja !) disponible en ligne</a>, je vous invite à la regarder +(c'est une 15aine de minutes) pour vous faire un avis ;)</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 &quot;notre&quot; projet <a class="reference external" href="http://blog.notmyidea.org/carto-forms-fr.html">&quot;carto +forms&quot;</a>, qui à finalement pu se +redéfinir un peu plus et donner naissance à un <a class="reference external" href="https://github.com/spiral-project/daybed/blob/master/README.rst">README</a>. On en +à profité pour lui choisir un nouveau nom: &quot;daybed&quot;, en référence à couchdb.</p> +<p>Ça devrait se transformer en code d'ici peu. La curiosité aidant, on a pu +discuter du projet avec d'autres personnes et affiner les attentes de chacun +pour finalement arriver à quelque chose d'assez sympathique.</p> +<p>J'ai aussi pu me rendre compte que pas mal de monde utilise <a class="reference external" href="http://pelican.notmyidea.org">pelican</a>, le bout de code que j'ai codé pour générer ce +blog, et avoir des retours utiles ! Probablement des réflexions à venir +sur comment éviter qu'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 contributeurs.</p> +<p>Bien évidemment, c'était aussi l'occaz de rencontrer des gens qu'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 chouette.</p> +<p>Entres autres faits notoires, JMad a perdu au baby-foot face à Exirel, même +en m'ayant à ses cotés pour le déconcentrer (et je suis un joueur d'un autre +monde - en d'autres termes, je suis nul), David`bgk ne s'est pas levé pour +aller courir le dimanche matin (il avait dit 5 heures!), Les suisses ont essayé +de me convertir à coup d'abricotine, j'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'ils mentent avec leur soit disant +soleil).</p> +<p>Et c'est sans parler de <a class="reference external" href="http://jehaisleprintemps.net/blog/fr/2012/04/15/j-ecris-ton-nom/">la brasucade</a> …</p> +<p>Bref, vivement la prochaine (et allez, cette fois ci je ferais une présentation +!)</p> +Motivation, bénévolat et participation2012-04-10T00:00:00+02:002012-04-10T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2012-04-10:/motivation-benevolat-et-participation-fr.html<p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux …</p><p>Des luttes, dieu (même si on peut à juste titre se demander ce qu'il vient +faire là) sait qu'il y en a. Principalement pour pointer du doigt les hérésies +du système actuel. Ça s'applique à l'informatique et à son système de brevets, +au <a class="reference external" href="http://zad.nadir.org/">bétonnage de nos campagnes</a> ou encore aux luttes +contre l'oligarchie et les profits d'une minorité aux dépends du reste du monde, +et à encore bien d'autres choses.</p> +<p>Pendant un bout de temps, j'ai parlé d'entraide, de collaboration, j'ai essayé +de sensibiliser autour de la question environnementale et aux alternatives +sociales. C'est d'ailleurs de cette manière que je me suis moi-même le plus +sensibilisé à ces questions qui me préoccupaient.</p> +<p>J'ai tenté de le faire sans tomber dans la critique des choix des uns et des +autres. Je respecte profondément la diversité des points de vues <strong>mais</strong> je +souhaite également que ces choix soient faits en connaissance de cause.</p> +<p>Une des choses difficile à supporter (pour les autres) quand on fait de la +sensibilisation, c'est le syndrôme du jeune con, du donneur de leçons.</p> +<p>On dirait qu'on parle de sauver le monde. &quot;Nous qui avons tout compris, on peut +vous aider à aller dans la <em>bonne direction</em>&quot;, mais c'est en oubliant que +la bonne direction pour l'un ne l'est pas nécessairement pour les autres…</p> +<div class="section" id="just-do-it"> +<h2>Just do it !</h2> +<p>Se battre <em>contre quelque chose</em> permet de facilement trouver des personnes qui +partagent les même craintes alors que se battre <em>pour</em> permet d'engager des +discussions avec des personnes qui partagent une vision commune.</p> +<p>Proposer des choses, trouver des personnes qui partagent des points de vue est +un bon point de départ pour le changer ce monde, a notre échelle. Le récent +documentaire <a class="reference external" href="http://justdoitfilm.com/">&quot;Just do it&quot;</a> porte un message assez +clair: toute initiative compte, aussi petite et insignifiante qu'elle puisse +sembler.</p> +<p>Des initiatives locales, il y en a, plein. Et si ce que nous avons dans notre +quotidien nous pèse (aller au supermarché, subir la sur-médiatisation +télévisuelle, ne pas parler à nos voisins de quartier…), qu'est-ce qui nous +empêche d'y substituer des modèles alternatifs ?</p> +<p>Monter une <a class="reference external" href="https://fr.wikipedia.org/wiki/AMAP">AMAP</a> (Association Pour le Maintien d'une Agriculture Paysanne) +n'est pas aussi compliqué qu'il y parait. Pour avoir fait l'expérience par deux +fois, j'ai été très agréablement surpris par la facilité des choses, pour peu +qu'on ne cherche pas à s'encombrer de l'inutile (tiens encore une fois on +parle de frugalité !): il est facile de vouloir faire trop, de recréer les +processus complexes auxquels nous sommes souvent confrontés.</p> +<p>Vous souhaitez partager des connaissances (cuisine, musique, danse, bricolage, +écriture), il suffit de le faire. En fait, pour la plupart des choses, il +suffit de tenter l'expérience, c'est rarement décevant. Surtout quand on +s'embarque dans des choses saugrenues ou personnellement inédites.</p> +<p>Pour moi, la frugalité, la simplicité volontaire, la sobriété heureuse, appelez-ça +comme vous le voulez, représente ce qui me convient et me permet d'être en +ligne avec les idées que je défends.</p> +</div> +<div class="section" id="faciliter-la-participation"> +<h2>Faciliter la participation</h2> +<p>Beaucoup de personnes sont à même de participer à des projets locaux, pour peu +qu'ils soient au courant mais pour autant peu franchissent le pas, et encore +moins persévèrent, pourquoi ?</p> +<p>Et pourquoi pas laisser les présents, les motivés, s'investir par eux-mêmes ? +Avoir des responsabilités est souvent pour ma part un frein à la réalisation +d'un projet lorsque je suis bénévole.</p> +<p>Décider à l'avance des choses qui semblent utiles et/ou importantes est parfois +indispensable, mais ne pas trop en faire permet de laisser libre court +à l'imagination (souvent débordante) des participants.</p> +<p>J'aime beaucoup l'idée de faire des camps de quelques jours, où rien n'est +réellement décidé à l'avance, mise à part un thème et quelques temps de +plénière ou il est possible à chacun de s'exprimer sur les projets qui +pourraient êtres réalisés.</p> +<p>Pas besoin de tant de formalisation: mettez une équipe de bidouilleurs ensemble +durant une semaine sans objectif commun à priori et sans distractions, vous +verrez bien ce qui en ressortira !</p> +</div> +Les dangers du livre numérique2012-01-23T00:00:00+01:002012-01-23T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-23:/les-dangers-du-livre-numerique-fr.html<p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable …</p><p>Le framablog vient de publier <a class="reference external" href="http://www.framablog.org/index.php/post/2012/01/22/stallman-ebook-livre-electronique">une traduction de l'article de RMS à propos des dangers du livre électronique</a>. Intéressant, même si il faut faire attention à ne pas confondre livre électronique et risques liés au format de distribution.</p> +<p>Si on passe sur le fait qu'un livre electronique est moins agréable à lire que sa version papier, il reste quand même quelques problèmes, la plupart liés au format de distribution de l’œuvre.</p> +<p>J'avoue ne pas trop savoir quoi penser de tout ça. D'un coté le livre électronique permet de franchir les frontières plus facilement, et semble avoir un tas d'avantage (notamment le fait que se trimbaler avec l'ensemble de sa collection de bouquins est désormais possible).</p> +<p>A mon avis, ce qui pose vraiment problème, ce sont les formats sous lesquels ces livres sont mis à disposition, non pas les livres eux même. Encore une question de DRMs donc…</p> +<p>Encore une problématique liée au copyright et au fait que le copie privée pose des problèmes à l'industrie en place. Ça renvoie à des questions plus profondes, et principalement à la mise en perspective du producteur de contenu et du consomateur de ce même contenu. Exactement ce qu'on essaye de résoudre dans le milieu agricole par le biais des AMAPs.</p> +<p>Sauf qu'ici, on est face au simple problème de la dématérialisation. Est-ce qu'une responsabilisation des consommateurs ne pourrait pas résoudre ce problème de publication ?</p> +<p>Recemment, j'ai récupéré une version piratée d'un livre technique, simplement parce que je ne trouvais pas une version de ce livre en numérique qui me permette de faire une copie privée de celui ci. Un Epub, par exemple. J'ai fait en me disant que c'était un acte militant. Sauf que non, ce n'est pas une solution soutenable, et j'en viens maintenant presque à le regretter. On en discutait rapidement avec <a class="reference external" href="http://ziade.org">Tarek</a> il y à quelques jours et il pointait du doigt que ceux qui en patissent sont les auteurs des livres, non pas les éditeurs (qu'il ne faut pas non plus diaboliser selon moi, ils cherchent à trouver des manières de garder leur coeur de métier).</p> +<p>Or, avoir des auteurs, des personnes qui sont prêtes à partager leur savoir à de larges audiences me semble primordial pour que la répartition du savoir continue à se répendre. Certes, le blogging permet cela dans une faible mesure, mais de manière bien moins construite, et surtout, est fait de manière bénévole (à moins que certains bloggeurs aient trouvé des moyens de rémunération dont j'ignore l'existance ?), donc il est plus difficile pour les auteurs de se dégager du temps pour travailler sur de gros ouvrages (ceci est bien évidemment une généralisation).</p> +<p>Quelles sont nos solutions, donc ? Peut être se tourner vers des solution de publication alternatives, couplées à une résponsabilisation des lecteurs. Je ne pense pas necessairement aux plateformes alternatives comme <a class="reference external" href="http://framabook.org">framabook</a>, parce que je me demande toujours si cela est une solution viable pour les auteurs, du moins dans les premières années, mais au moins des éditeurs qui ne font pas le choix du grand verrou numérique.</p> +<p>On demande pas grand chose, pourtant… Peut être même que de telles initiatives existent déjà ?</p> +<p>Et vous, vous les achetez ou vos livres ?</p> +2012, first months2012-01-21T00:00:00+01:002012-01-21T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2012-01-21:/2012-first-months.html<p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services …</p><p>A lot of changes in these last months. First of all, I've started to +work for <a class="reference external" href="http://mozilla.org">Mozilla</a>, on the Services team, where I am working on +web services and scalability. Basically, what we are trying to do at services +is to provide a way for developers to make web services able to scale out of +the box.</p> +<p>Our most visible and known project, so far, is Firefox Sync, which allows to synchronize +browsing data (tabs, passwords, history, etc.) among different instances of +Firefox. We are also building other things, such as a way to get metrics +easily, a web service based queue, etc. Our primary consumers are +people inside Mozilla, and we want to help them having a simple way to create, +deploy and scale their apps. The project is named &quot;sagrada&quot;, and you +can find some more information about it on <a class="reference external" href="https://wiki.mozilla.org/Services/Sagrada">our public wiki</a></p> +<p>All of what we do, we do it in the open. So you can have a look at <a class="reference external" href="http://github.com/mozilla-services">the +different pieces of code we wrote</a> +and use them / contribute if you want to.</p> +<p>I will not dig in to all the details of what I have been doing, but so far, this have been +a pretty amazing experience. Part of this is explainable by the fact that the +team is made of amazing folks, all with a strong experience in different +topics, so I'm learning things™.</p> +<p>I am currently practicing a bit my C++ to do crypto related things (I may or +may not talk about this later on this web-logs) and it's great (well, it +remembers me why I love python for so many things, but it makes me think closer +to the metal ;)). I love this job.</p> +<p>Second, I moved to Paris. Yes, Paris. Some of you who know me a bit may find +it unexpected, and that's the case. I'm usually not a big fan of big cities and +am a fairly strong defender of having and creating activities in the country side, +to face the rural exodus problem, into other thingS.</p> +<p>I didn't changed my opinion about that. However, I don't want to <em>start</em> by +working remote, especially when working with a remote team. Having offices kind +of help me to have a differentiation between my working place and home, which I +find to be important.</p> +<p>And, to be honest, I don't like Paris for unknown reasons: I +haven't been there, so it's a big over-generalisation to say that it's not +good for me. The reality is that I have no idea of what Paris is, and if I'll +like it or not.</p> +<p>I found a really nice house (yeah, a house!) in Paris and am sharing it with 3 +other persons. We have room, all like good food and… +they are not geeks, which is a big win for me: work is work and home is home.</p> +<p>So far, Paris had been really nice. A lot of things are going on in here, and I +kind of like the way it is possible to find alternative related things in here. +I found a <a class="reference external" href="http://en.wikipedia.org/wiki/Community-supported_agriculture">CSA</a>, +some people interested by agriculture related problems and I like where things +seems to be going.</p> +<p>So, new job, new house, new city, things are going forward and that's great.</p> +<p>Oh, and I will try to post some more technical articles soon, +I'm missing them :)</p> +La simplicité volontaire contre le mythe de l'abondance2011-10-14T00:00:00+02:002011-10-14T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-10-14:/la-simplicite-volontaire-contre-le-mythe-de-labondance-fr.html<p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car …</blockquote><p>Paul Ariès dans la préface de &quot;<a class="reference external" href="http://www.editionsladecouverte.fr/catalogue/index.php?ean13=9782707169747">La simplicité volontaire contre le mythe de +l'abondance</a>&quot;</p> +<blockquote> +Je sais aussi qu'à force d'être seulement contre, nous finissons par être +&quot;tout contre&quot;, tout contre le système, ses débats pourris, ses pratiques +immondes, ses pervertions mentales. Cessons de porter notre adversaire sur +notre dos, car il finira par nous poignarder, au moment ou nous pensions +justement pouvoir le vaincre… Entendons-nous bien, il ne s'agit pas +d'apprendre à &quot;positiver&quot; sous prétexte que l'on pourrait &quot;moraliser&quot; ou +repeindre en vert le capitalisme, il s'agit, bien au contraire, d'être aussi +intraitables lorsque nous créons cet autre monde, que lorsque nous étions +ces militants purs mais un peu durs à jouir, il s'agit d'être aussi +indomptables mais sans oublier que le capitalisme ne pourra être arrété que +par du non-capitaliste… c'est-à-dire en multipliant les expérimentations +sociales, en acceptant de faire au maximum sécession, en inventant +(réinventant?) une gauche buissonière et maquisarde, en faisant, au +quotidien, la part belle à la dérive, à des modes de comportement +expérimentaux. 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.</blockquote> +Travailler moins pour mieux travailler ?2011-05-19T00:00:00+02:002011-05-19T00:00:00+02:00Alexis Métaireautag:blog.notmyidea.org,2011-05-19:/travailler-moins-pour-mieux-travailler-fr.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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un …</p><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 &quot;easter break&quot; et j'en ai profité pour donner un coup aux travaux de la +maison (et pour me reposer un brin!).</p> +<p>Bosser en extérieur est un réel plaisir et faire quelque chose de manuel +également. Je n'ai pas pour habitude de bricoler autre chose que du logiciel et +c'est vraiment quelque chose que j'apprécie.</p> +<p>J'avoue, je mens un peu quand je dis que j'étais complètement déconnecté: +j'ai vérifié mes mails assez régulièrement en utilisant mon téléphone +(merci Arnaud pour le prêt du gadget!) et j'ai limité ma présence web au strict +minimum. Je veux dire par là pas de twitter, pas d'IRC et autres mailing-lists.</p> +<p>Quand je dis hors-ligne, je ne dis pas que je n'ai pas travaillé sur mon +ordinateur. J'ai à fournir beaucoup plus de travail que ce que je ne pensait en +premier lieu pour la rédaction de mon mémoire et j'ai passé quelques heures par +ci par là à lire des articles et livres sur le sujet ainsi que rédigé une bonne +partie de mon mémoire durant ces 10 jours. Résultat ? Les heures que j'ai passées à travailler ont +été étonnement plus productives que celles que j'ai l'habitude de passer derrière +un écran. Je ne parles pas uniquement du fait de procrastiner; évidemment c'est +une des causes principales de ma perte de productivité, mais je pense également +au fait de laisser le cerveau reposer, au moins en ce qui concerne la partie +informatique. Bricoler demande de la concentration et de la réflexion mais +permet également de laisser son esprit vagabonder. J'ai pu donc avancer mes +sur certaines parties de mon mémoire alors que j'étais en train de poser le +bardage sur la garage par exemple.</p> +<p>Passer du temps sur autre chose (qui demandait également de la concentration +par ailleurs) m'a permis d'être réellement plus efficace lors de mes phases de +rédaction et de lecture.</p> +<p>Je me demande depuis quelques temps quel sera mon futur travail et quelle forme +il prendra. Éééh oui, la fin des études arrive pour la fin de l'année, c'est +pas une blague. Et je me pose sérieusement la question du travail aux 3/4 +temps. La raison principale étant que je ne souhaites pas passer la majeure +partie de mon temps à travailler derrière un écran et que la formation que j'ai +m'y rattache beaucoup. Ne me comprenez pas de travers: j'aime ce que je fais; +mais j'aime aussi ce que je fais à coté de l'informatique: associatif, projets +alternatifs, permaculture et autres.</p> +<p>Viens s'ajouter à ça le fait d'avoir une qualité de vie qui me semble pouvoir +passer par le fait de travailler moins (&quot;il est marant ce gamin, il à pas encore commencé +à travailler qu'il veut bosser moins, regarde moi cette feignasse!&quot;) et +travailler plus efficacement. Bien sur, on n'est jamais 100% productif et c'est +d'autant plus vrai pour moi, alors si gagner en productivité peut passer par +travailler moins, pourquoi pas s'y essayer !</p> +<p>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 ?</p> +Quels usages pour l'informatique ?2011-01-12T00:00:00+01:002011-01-12T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2011-01-12:/usages-informatique-fr.html<p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas …</p><p>Quand on termine ses études, on s'en pose un tas, des questions. Sur le métier +que l'on veut faire, sur ce que ça signifie, sur le sens et la valeur du +travail. Et j'en suis arrivé à faire un constat simple: l'informatique, c'est +utile, tant que ça ne vient pas vous pourrir la vie. Oui, parce que de +l'informatique on en a partout, des &quot;geeks&quot; et des &quot;accros&quot; aussi, et que ça +vient s'immiscer dans nos vies même quand d'autres moyens ou médias sont plus +utiles ou pertinents.</p> +<p>Certes, l'informatique nous permet de communiquer et travailler plus efficacement, +Mais à quel prix ? Ce n'est pas parce qu'il est possible d'<a class="reference external" href="http://retourdactu.fr/2011/11/07/la-non-communication-nouveau-modele-de-societe/">industrialiser +l'éducation</a> +(ou l'agriculture !), que l'on doit le faire. Oui, ça me dérange d'être une des +nombreuses personnes à l'œuvre derrière cette soit disant &quot;révolution&quot;, qui +n'est pas toujours pour le meilleur. Attention, je ne remets pas l'informatique +et son intérêt en cause: je me pose des questions quand à la place que je veux +lui donner et la place que je souhaites occuper dans son évolution. Ce n'est +pas parce qu'on peut tuer avec un marteau (avec un peu de volonté) qu'il s'agit +d'un mauvais outil, mais si tout le monde se met à tuer avec des marteaux (y a +des malades partout, hein), alors se poser la question de son rôle, en tant que +fabricant de marteaux me semble nécessaire (oui, je vous l'accorde, on aura vu +des comparaisons plus perspicaces).</p> +<p>Donc: à partir de quel moment l'informatique cesse d'être un outil utile pour +transformer nos modes de vies d'une manière qui me dérange ? Peut être avec son +arrivée sur des périphériques mobiles ? Peut être quand elle se fait +l'instrument du consumérisme et de l'individualisme.</p> +<div class="section" id="et-alors-on-fait-quoi"> +<h2>Et alors, on fait quoi ?</h2> +<p>Mais si je continue à faire de l'informatique, il y a bien des raison. J'ai +d'ailleurs trouvé mon intérêt de par le coté collaboratif qui est permis et +développé par l'outil informatique, et notamment par le réseau des réseaux +(internet). Faisons ensemble, mes amis. Prouvons que la collaboration a de +meilleurs jours à vivre que la compétition. Le web, notamment, est une avancée +majeure en ce qui concerne la liberté d'expression et le partage de +connaissances (oui, kipédia). Je vous conseille d'ailleurs à ce propos +<a class="reference external" href="http://owni.fr/2011/11/30/vers-une-economie-de-la-contribution/">l'excellent discours tenu par Bernard Stiegler</a> paru +récemment sur <a class="reference external" href="http://www.owni.fr">owni</a>.</p> +<p>Et c'est cet avenir qu'il me plait de défendre: l'ouverture d'esprit, la +possibilité que chacun puisse contribuer et participer à une base de savoir +commune, en apprenant des autres. Mais par pitié, n'imposons pas la +technologie là où elle n'est pas nécessaire, et utilisons la avec tact quand +elle peut nous être profitable.</p> +<p>Il me plait de repenser l'informatique comme outil et non plus comme mode de +vie. Faisons le l'outil de la collaboration. À l'école, apprenons à nos enfants +à collaborer, à susciter le partage, pas uniquement avec l'outil informatique, +mais aussi avec celui ci, tout en leurs apprenant à avoir un regard critique +sur les informations qu'ils reçoivent.</p> +<p>En bref, questionner le rôle que l'on souhaite avoir dans notre société par le +biais de l'informatique est nécessaire. Comme d'autres, je suis arrivé +à l'informatique par le biais du premier ordinateur familial, il y a de ça une +bonne quinzaine d'années. Ça intrigue, on touche un peu à tout (on en fait des +conneries !) et on finit par apprendre/comprendre comment ça marche, petit +à petit. Cette curiosité n'est d'ailleurs pas le propre de l'informatique +puisqu'on la retrouve dans la cuisine, dans le bricolage et dans un tas de +domaines de notre vie quotidienne.</p> +<p>Finalement, c'est aimer bidouiller, et comprendre comment ça fonctionne, quitte +à sortir les compétences de leur domaine de prédilection (qui a dit que +l'informatique ne pouvait être artistique ?) Le mouvement hacker (bidouilleurs) +aime à sortir l'informatique de son carcan et l'appliquer ailleurs.</p> +<p>C'est de cette manière que j'ai envie de considérer mon métier, qui avant tout +est une passion. Je suis un bidouilleur, j'aime découvrir comment les choses +fonctionnent et avoir une panoplie d'outils qui me permettent de répondre à des +besoins réels.</p> +</div> +<div class="section" id="favoriser-la-collaboration"> +<h2>Favoriser la collaboration</h2> +<p>Et donc, en tant qu'individu, pourquoi faire de l'informatique ? Qu'est-ce qui +m'attire dans cet outil ?</p> +<p>Ce qu'on pourrait qualifier de &quot;recherche fondamentale&quot;, l'écriture de +bibliothèques logicielles, est important mais n'est pas tout. Ce qui importe ce +sont les usages qui en découlent. Je souhaite <strong>savoir écrire des outils qui +sont utiles</strong>, <strong>qui favorisent la collaboration et participent à l'ouverture +des esprits</strong>.</p> +<p>Je choisis de faire de l'informatique pour créer les outils qui répondent à des +problématiques réelles, pour trouver de meilleures manières de communiquer et +de travailler ensemble. Mais, comme me le disait David, d'<a class="reference external" href="http://outils-reseaux.org/PresentationProjet">Outils-Réseaux</a>, on ne crée pas de la +coopération: rien ne sert d'essayer de faire coopérer des gens qui ne veulent +pas. On peut, cependant, la faciliter, en utilisant les bons outils et en +formant les gens à leur utilisation, ainsi qu'aux pratiques collaboratives +(qui, je le répète, ne s'arrêtent pas du tout aux frontières informatique).</p> +<p>Le logiciel libre, avant d'être une force pour le marché logiciel, est une +application du partage. Une démonstration qu'il est possible de travailler +ensemble pour fabriquer quelque chose de fonctionnel et d'utile pour tous. Une +sorte d'antithèse de ce modèle capitaliste incarné par les brevets logiciel.</p> +<p>A plusieurs reprises, j'ai été bluffé par la réalité du logiciel libre. Oui, il +est facile de collaborer lorsqu'on crée un logiciel, pour peu qu'on explique +les tenants et les aboutissants aux participants. Les contributeurs sortent +d'on ne sait où, pour peu que le projet leur soit utile. Je ne parle pas +d'outils &quot;corpo compliant&quot; (bien que ça soit probablement aussi le cas), mais +d'outils que j'ai pu développer pour mon propre usage, et sur lesquels il a été +possible de collaborer avec d'autres.</p> +<p>Parce que l'informatique est utile dans bien des milieux, parce qu'elle peut +être (et elle l'est) un vecteur de participation et de collaboration, défendons +les valeurs qui nous sont chères (logiciels libres et ouverts!) et construisons +des ponts entre les initiatives qui nous parlent (fermes autogérées, +initiatives d'éducation populaire) et l'informatique.</p> +<p>Faisons en sorte de rendre l'informatique accessible et utile dans les milieux +ou elle peut apporter quelque chose !</p> +</div> +Fork you ! or how the social coding can help you2010-11-05T00:00:00+01:002010-11-05T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-11-05:/fork-you-or-how-the-social-coding-can-help-you.html<p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to …</p><p>With <a class="reference external" href="http://github.com">github</a> and <a class="reference external" href="http://www.bitbucket.org">bitbucket</a> coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.</p> +<p>Eeach time I see people helping others, I'm amazed by how we like to share +our knowledge.</p> +<p>I say github, because it seems to be the more mainstream, but I think it's +something strongly related to the <a class="reference external" href="http://en.wikipedia.org/wiki/Distributed_revision_control">DVCS</a> principles: the &quot;only&quot; thing github have +made is to turn that into a social network, and to reveal the awesomeness of the +DVCSes to the masses.</p> +<p>What is really interesting is to see how this platform is addictive: it's +automatically updating a webpages with the more accurate informations about the +projects you're involved in, and add a bit of magic to that using webhooks, +allowing you to update your website each time you push to you repository, for +instance.</p> +<p>Quite nothing, indeed, but, I don't know why, I find this fascinating.</p> +<p>I haven't had the privilege to see my projects forked from github by strangers, +but I've forked others repository to give an hand some times, when I wanted to, +and the main reason is &quot;because it's <strong>fun</strong>&quot; to do so.</p> +<p>Yeah, you're probably right, you have to be a nerd to find fun to fork others. +The good point is that geeks are a kind of nerds, and some geeks are coders :)</p> +<div class="section" id="new-ways-to-contribute"> +<h2>New ways to contribute</h2> +<p>In addition, it seems that he community, or the communities, are there, on those +new social networks for coders. It's really handy to drop an eye on interesting +projects, to report bugs, propose new features, and check what new projects this +or this person have made.</p> +<p>Well, &quot;it's not new&quot;, you may think. That's true, because it's been a while that +SVN was there and even CVS before that. But, it was a bit messy to &quot;fork&quot; a +project, isn't it ? And I'm not talking about all the hell SVN involved with it +(who have not had issues with those messy .svn folders raises an hand !).</p> +<p>It have not been so easy to share code and thoughts about code, to propose +changes on existing code, than now. You think it's better to implement this or +that in a different way ? Clone it (fork it), make your changes and publish +them, and then ask projects owners about it. For sure you'll have answers.</p> +<p>Even if they don't want it, you can easily keep your changes, and keep getting +their updates!</p> +<p>Also, lot of <em>fashionables</em> projects tend to move on DVCS. +Personally, if I know I can fork on a DVCS instead of from a &quot;simple&quot; VCS, +I'll probably be quicker to fork/clone, and to publish changes on my own copy, +than if I had to do so on the upstream repository (and I'll likely dont have +the rights to push to it), because I will not be afraid to break things.</p> +<p>DVCSes makes the contribution easier.</p> +</div> +<div class="section" id="release-early-release-often"> +<h2>Release early, release often</h2> +<p>Maybe have you read <a class="reference external" href="http://www.catb.org/~esr/writings/cathedral-bazaar/">The cathedral and the bazaar</a>, by Eric Steven Raymond ? +(If not, consider doing so, it's a really interesting reading)</p> +<p>Among a lot of others interesting things, one hint he gives is <em>release early, +release often</em>.</p> +<p>I understand it as: if you want to get contributors, release your code early, +even if it's not perfect, and don't be afraid to publish your changes each +time it's needed.</p> +<p>Without notifying it, that's basically what I was doing for my own projects. +I guess that's because Social coding platforms encourages those practices, +partially cause of the possible impact publishing each of your changes can have +on your final solution.</p> +<p>If you have considered publishing your projects, code snippets, or whatever +(code related) but did not done it, considering them not yet ready, maybe +should you think about it twice: you can get feedback and probably start some +interesting discussions about it, if you write code that's readable, of course!</p> +</div> +<div class="section" id="a-step-further-for-open-source-softwares"> +<h2>A step further for open source softwares</h2> +<p>Well, DVCSes are a honking great idea, and they're starting to be really +powerful when applied to free softwares. I mean: if you can't see a project, +it will be hard to contribute to it. And, I don't think anyone wants to +contribute to something closed/proprietary, <em>just for fun</em>. Or maybe am I +missing something.</p> +<p>Maybe it's a kind of revolution, about free and open source softwares (<a class="reference external" href="http://en.wikipedia.org/wiki/Free_and_open_source_software">FOSS</a>), +that is going on. I really like to know I have my word to say about the changes +in the tools I use, and to know that I can make them evolve.</p> +<p>Let's take an example. Imagine I'm using a web framework on daily basis, as a +part of my job as a web developer. I do like using an open source software +because I know how it's working, and because I know that I can interact with the +authors of the framework while they're doing the changes on it.</p> +<p>That's communication, nothing more, and of course I can do that with an internal +proprietary solution, but it will cost me <strong>a lot</strong> more time, for a dead-simple +reason: a company is not as big and powerful as a community can be: it will cost +time to work on this framework, resources to maintain it, fix bugs etc.</p> +<p>Well, I'm starting advocating here about Free and Open Source Softwares use on +companies, what is a bit beyond the scope of this article, so let's back to +our DVCSes and new social related tools.</p> +<p>If I find a bug in this framework, while working, I have the possibility to +go and talk with the creators of the framework, to open a ticket, and even to +make a fix for it, because I've access to the source code. If I want to create a +new feature, I just have to fork it, hack it, and then publish my code to have +feedback of the community.</p> +<p>My fix/work will benefit to all the people (and maybe others companies) working +with this framework, and it's a way to prove the community that my company is +enough skilled to make code-fixes to the framework, so that's all good !</p> +</div> +<div class="section" id="what-s-next"> +<h2>What's next ?</h2> +<p>I hope those social coding platforms are only the begining of a new area. I hope +they will make people realize what the power of the community is, and how easily +they can becomes part of it.</p> +<p>If you're not using them right now, maybe you should do so: have a +look 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 !</p> +</div> +Le temps des grâces, courrez-y !2010-03-28T00:00:00+01:002010-03-28T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-03-28:/le-temps-des-graces-courrez-y-fr.html<p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un …</p><p>Ouf, notre +<a class="reference external" href="http://www.reseaugrappe.org">semaine de l'environnement</a> s'est +terminée, après un peu de neige et un brin de soleil quand il en +fallait.</p> +<p>Ce fut l'occasion de rencontrer beaucoup de gens biens, et +de regarder d'un peu plus près toutes ces problématiques qui +mériteraient à elles seules, chacune un billet. Après un répis +d'une semaine, pour récupérer des folies organisatrices (c'est ça +qui fait du bien, ceci dit -- les folies, pas le repos), je me +retrouve de nouveau sur ces mêms réflexions, grâce aux journées +organisées par +<a class="reference external" href="http://www.fne.asso.fr/">France Nature Environnement</a>, qui +proposaient ce jeudi soir une projection de &quot;Le temps des grâces&quot;, +un documentaire sur l'agriculture.</p> +<p>Parce que depuis 60 ans, il est pratiqué le remembrement des +parcelles à gogo, parce que nos sols deviennent completement morts +à cause des tonnes d'intrants qu'on leur fait absorber, et parce +que les exploitations s'agrandissent sans en finir pour tenter de +réagir façe à un marché financier toujours plus insaisissable, mené +de très loin par la PAC, il fallait un film pour en parler. C'est +ce que fait &quot;le temps des grâçes&quot;, avec un bon sens et une facilité +à faire passer des messages, qu'on ne peut qu'applaudir.</p> +<p>Malheureusement il s'agissait de la dernière diffusion à +<a class="reference external" href="http://www.cinemas-utopia.org/toulouse/">L'Utopia de Toulouse</a>... +Si vous en avez l'occasion, sautez dessus et profitez le temps de +ces 2 heures, ou vous pourrez écouter à la fois des discours +d'agronomes, d'agriculteurs, de chercheurs et bien d'autres, qui +dressent un constat pas si brillant de notre agriculture. On n'est +pas sorti de l'auberge, enfin, c'est l'expression.</p> +<p>Je vous laisse avec le synopsis et une bande annonce.</p> +<blockquote> +Une enquête documentaire sur +le monde agricole français aujourd'hui à travers de nombreux récits +: agriculteurs, chercheurs, agronomes, écrivains... Un monde qui +parvient à résister aux bouleversements qui le frappent - +économiques, scientifiques, sociaux - et qui, bon gré mal gré, +continue d'entretenir les liens entre générations. Un monde au +centre d'interrogations majeures sur l'avenir.</blockquote> +<p>Ainsi qu'un commentaire que je ne peux m'empécher de relayer, +trouvé sur allocine.fr (oui, vous savez, ce site rempli de pubs).</p> +<blockquote> +Le temps des grâces c'est je pense le plus grand film traitant de +l'écologie en tant que documentaire ou en sujet principal, on y +apprend une multitude de choses, on en ressort en colère contre le +système, le film propose différents points de vues, ici on a pas de +voix off moralisatrice à deux balles avec des gros titres bien +surlignés pour que même les beaufs matant TF1 puissent comprendre, +ici même si ça reste accessible au citoyen lambda, le film ne fait +pas de compromis avec le monde agroalimentaire, il ose dénoncer les +filière d'agronomie qui apprennent pas les bonnes choses à leurs +étudiants, aux lobbys de cette agro-industrie qui n'en fait qu'à sa +tête pour amasser de l'argent, cette tendance à tout uniformiser et +détruire… Franchement j'ai trouvé ça génial de bout en bout, +captivant, on explore cette campagne française, on comprend les +dilemmes des paysants. Le film n'étant pas opposé à la modernité, +ni même réactionnaire, il propose juste un constat alarmant du +monde agricole français, tout en proposant des alternatives qui +pourraient être utilisée, si les pouvoirs publics lâchaient un peu +la main des lobbys. Passionnant, vraiment.</blockquote> +<p>Courrez-y, je vous dis.</p> +Semaine de l’environnement: La consommation étudiante2010-02-24T00:00:00+01:002010-02-24T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2010-02-24:/semaine-de-lenvironnement-la-consommation-etudiante-fr.html<p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres …</p><p>Les acteurs associatifs sont bien souvent moteurs des critiques de nos sociétés. Je pense à <a class="reference external" href="http://www.framasoft.net/">Framasoft</a>, à <a class="reference external" href="http://www.laquadrature.net/">la Quadrature du net</a> ou à <a class="reference external" href="http://www.arsindustrialis.org/">Ars Industrialis</a> (dans le domaine de la science et de l'informatique), mais aussi <a class="reference external" href="http://www.amisdelaterre.org/">aux Amis de la Terre</a>, à <a class="reference external" href="http://www.attac.org/">ATTAC</a> (dans le domaine de l'environnement entres autres), et a tout un tas d'autres associations que je ne peux pas citer ici exhaustivement... Ce sont eux qui sont porteurs de messages alternatifs, et qui sont les initiateurs de débats publics, qui permettent de faire avancer des thématiques aussi importantes que le logiciel libre ou la protection de l'environnement.</p> +<p>Dans cette optique, depuis près de 3 ans (déjà !), au sein du +<a class="reference external" href="http://www.reseaugrappe.org">réseau GRAPPE</a>, on <em>essaye</em> +d'aborder des thématiques qui touchent de près ou de loin à +l'environnement, parce que c'est un sujet qui nous importe et nous +passionne. L'année dernière, c'était l'alimentation étudiante, ce +qui à abouti à la publication de +<a class="reference external" href="http://public.reseaugrappe.org/alimentation.pdf">la revue &quot;les étudiants se mettent à table&quot;</a>. +Cette année c'est la consommation étudiante qui est au programme.</p> +<div class="section" id="la-consommation-etudiante"> +<h2>La consommation étudiante ?</h2> +<p>L'idée principale de cette étude est de tenter de faire une analyse +de la &quot;société de consommation&quot;, souvent questionnée par les +étudiants et par d'autres, et de jeter un œil sur le rapport des +étudiants à cette société: Quoi et comment consomment-ils ? Les +universités et les écoles ne poussent-elles pas d’une certaine +manière les étudiants à la consommation ? Quelles sont les +alternatives face aux dérives de surconsommation ?</p> +<blockquote> +Analyse des pratiques, réflexions et mobilisations des étudiants en +termes de consommation seront réalisés pour comprendre leur modes +de vie, mais aussi leurs attentes, leurs propositions sur cette +thématique</blockquote> +</div> +<div class="section" id="la-semaine-de-l-environnement"> +<h2>La semaine de l'environnement !</h2> +<p>A travers l'ensemble des villes du réseau, +des projections de films et des débats auront donc lieu sur ce +thème, lors de la semaine de l'environnement 2010, qui se déroulera +d'ailleurs durant le mois de Mars +<a class="reference external" href="http://www.reseaugrappe.org/la-semaine-de-lenvironnement-programme/">partout en france</a>, +et <strong>du 6 au 14 Mars sur Toulouse</strong>. +<a class="reference external" href="http://docs.notmyidea.org/sde/prog-toulouse.pdf">Jetez un oeil au programme</a> +! Avec pour objectif de sonder un peu le ressenti des étudiants en +terme de consommation, nous avons mis en place +<a class="reference external" href="http://spreadsheets.google.com/viewform?formkey=dHV2bVllS2lWbzhyV3NBN3NUbi1TM2c6MA">un questionnaire en ligne</a>, +que vous pouvez compléter en une petite 10aine de minutes, +n'hésitez pas ! +<a class="reference external" href="http://www.reseaugrappe.org/consommation/">La page sur la consommation étudiante sur le site du GRAPPE</a></p> +</div> +AMAP + Média = Paniers bio à 5e ?!2009-11-11T00:00:00+01:002009-11-11T00:00:00+01:00Alexis Métaireautag:blog.notmyidea.org,2009-11-11:/amap-media-paniers-bio-a-5e-fr.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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à …</p><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'ai à décrier +est celle d'un reportage télé, passé sur France 2 vendredi 23 +Octobre +(<a class="reference external" href="http://docs.notmyidea.org/amap/amap-fr2.avi">voir la vidéo</a>), +ou on parles de +<a class="reference external" href="http://amap.zest.free.fr">l'AMAP étudiante Zest</a>.</p> +<p>Malgré tout le temps passé à expliquer que justement, l'AMAP c'est +avant tout, pour nous, une notion de solidarité envers les +agriculteurs, malgré le fait que le message soit plus profond que +simplement aller acheter du bio (ça, c'est possible aussi en +supermarché), malgré le fait qu'il s'agisse en fait d'une remise en +cause plus profonde de la société, les journalistes n'ont choisi de +prendre que les quelques secondes qui leurs convenaient, celles qui +ne faisaient pas tache, celle ou je dis que &quot;l'AMAP permet aux +étudiants de réapprendre à cuisiner, plutôt que de manger des +nouilles et de se faire des plats réchauffés&quot;. Bien sur, je l'ai +dit et je le pense d'ailleurs, là n'est pas le problème, mais mon +message n'était pas celui là.</p> +<p>Jamais, dans les quelques minutes du reportage, on ne dit ce que +AMAP signifie: Association de <strong>Maintien</strong> d'une Agriculture +<strong>Paysanne</strong>. On ne parles même pas des agriculteurs ! C'est +simplement plus facile pour les étudiants de venir récupérer leurs +paniers, puisque les points de distribution sont sur les facs, et +en plus ça ne coute que 5 euros ! ...</p> +<p>Alors je crois bon de rappeler que L'AMAP n'est pas seulement un +service, c'est un engagement. Sur 5 mois, un engagement solidaire, +c'est la donnée principale de l'équation, celle sans quoi ça ne +peut fonctionner. Par le biais de cette AMAP, on essaye de montrer +que d'autres agricultures sont possibles, que la solidarité c'est +bien réel, et qu'il est possible de sortir du +<em>tout, tout de suite</em>.</p> +<p>Mais bon, apparemment, ça passe pas bien à la télé.</p> + \ No newline at end of file diff --git a/first-week-working-on-distutils2.html b/first-week-working-on-distutils2.html new file mode 100644 index 0000000..dbde655 --- /dev/null +++ b/first-week-working-on-distutils2.html @@ -0,0 +1,217 @@ + + + + + + + + + first week working on distutils2 - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

first week working on distutils2

+ + + +
+

🌟

+

As I've been working on +Distutils2 during the past +week, taking part of the +GSOC program, here is a +short summary of what I've done so far.

+

As my courses are not over yet, I'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 +Distutils2.

+

To do this, we need to rely on informations provided by the Python +Package Index (PyPI), and there is at +least two ways to retreive informations from here: XML-RPC and the +"simple" API.

+

So, I've been working on porting some +Distribute related +stuff to Distutils2, cutting +off all non distutils' things, as we do not want to depend from +Distribute's internals. My main work has been about reading the +whole code, writing tests about this and making those tests +possible.

+

In fact, there was a need of a pypi mocked server, and, after +reading and introducing myself to the distutils behaviors and code, +I've taken some time to improve the work +Konrad makes about this mock.

+
+

A PyPI Server mock

+

The mock is embeded in a thread, to make it available during the +tests, in a non blocking way. We first used +WSGI and +wsgiref in order +control what to serve, and to log the requests made to the server, +but finally realised that +wsgiref is not +python 2.4 compatible (and we need to be python 2.4 compatible in +Distutils2).

+

So, we switched to +BaseHTTPServer +and +SimpleHTTPServer, +and updated our tests accordingly. It's been an opportunity to +realize that WSGI has been a great step +forward for making HTTP servers, and expose a really simplest way +to discuss with HTTP !

+

You can find +the modifications I made, +and the +related docs +about this on +my bitbucket distutils2 clone.

+
+
+

The PyPI Simple API

+

So, back to the main problematic: make a python library to access +and request information stored on PyPI, via the simple API. As I +said, I've just grabbed the work made from +Distribute, and played +a bit with, in order to view what are the different use cases, and +started to write the related tests.

+
+
+

The work to come

+

So, once all use cases covered with tests, I'll rewrite a bit the +grabbed code, and do some software design work (to not expose all +things as privates methods, have a clear API, and other things like +this), then 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 !

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/focusing-on-what-matters.html b/focusing-on-what-matters.html new file mode 100644 index 0000000..0d2ecc1 --- /dev/null +++ b/focusing-on-what-matters.html @@ -0,0 +1,195 @@ + + + + + + + + + Focusing on what matters - Carnets Web + + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Focusing on what matters

+ + + +
+

How to avoid the information overload?

+

🌟

+

I do have a problem with information.

+

You know. I have to check my emails, irc, twitter, my feed reader etc. +I need to.

+

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, away from news and +agitation.

+

Working remotely is sometimes hard. Hard because you need to at the same time +be in the discussions channels and work on the interesting projects. A real +myth.

+

In practice, I'm really bad at multi-tasking. I tried a few times the Pomodoro +technique, which forces me to focus on a task for 25mn, but this split of my day +into slices of 25mn breaks my natural flow.

+

So, what do I need? I tried to change my tools, it helped a bit. Still, I'm not +focused like I would like to be.

+

Maybe that's just me who needs some more persuasion over myself, but the best +way I found to work is to unplug the cable. Literally. At work, at some point I +was using a RJ45 cable to connect to the Internet. When I wanted to work on +something, I could just unplug this cable.

+

And that's amazing how you find yourself in the process to "check" +something on the web. Mails, irc… well, you got the idea. You're litterally, +without even noticing, switching to your browser an opening a new tab…

+

Of course, that Web isn't filled only with lolcats and twitter messages +(even if I would love to see a pie chart with the repartition of lolcats +VS the rest of the web's content), so sometimes you need some precious bit of +information that's there. Fair enough. plug the cable, do what you need to +do, and unplug. Alexis, unplug!

+

It also helps to have some fair bit of documentation available directly on my +machine (I used to have the python docs, I should get it back!)

+

I'm feeling adventurous, so I'll try something new starting tomorrow, and I'll +report back in here my findings. Here's the challenge:

+
    +
  • Check emails only once a day. Do not do it in the morning, before +working, to keep my mind clear. I would say at 2pm (after lunch). +(This doesn't mean I will not send mails tho)
  • +
  • Stay away from the Internet during the morning. I'll not connect if I don't +need to.
  • +
+

Let's see how it goes :)

+ + L'image d'illustration utilisée est un travail de 55Laney69 proposé sous license CC BY-NC 2.0. Merci ! + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file 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 new file mode 100644 index 0000000..985343c --- /dev/null +++ b/fork-you-or-how-the-social-coding-can-help-you.html @@ -0,0 +1,247 @@ + + + + + + + + + Fork you ! or how the social coding can help you - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Fork you ! or how the social coding can help you

+ + + +
+

🌟

+

With github and bitbucket coming around, a lot of new usages appears for the +developpers: it's now easy to get feedback on your code/modifications, and to get +help from others by, for instance, forking repositories.

+

Eeach time I see people helping others, I'm amazed by how we like to share +our knowledge.

+

I say github, because it seems to be the more mainstream, but I think it's +something strongly related to the DVCS principles: the "only" thing github have +made is to turn that into a social network, and to reveal the awesomeness of the +DVCSes to the masses.

+

What is really interesting is to see how this platform is addictive: it's +automatically updating a webpages with the more accurate informations about the +projects you're involved in, and add a bit of magic to that using webhooks, +allowing you to update your website each time you push to you repository, for +instance.

+

Quite nothing, indeed, but, I don't know why, I find this fascinating.

+

I haven't had the privilege to see my projects forked from github by strangers, +but I've forked others repository to give an hand some times, when I wanted to, +and the main reason is "because it's fun" to do so.

+

Yeah, you're probably right, you have to be a nerd to find fun to fork others. +The good point is that geeks are a kind of nerds, and some geeks are coders :)

+
+

New ways to contribute

+

In addition, it seems that he community, or the communities, are there, on those +new social networks for coders. It's really handy to drop an eye on interesting +projects, to report bugs, propose new features, and check what new projects this +or this person have made.

+

Well, "it's not new", you may think. That's true, because it's been a while that +SVN was there and even CVS before that. But, it was a bit messy to "fork" a +project, isn't it ? And I'm not talking about all the hell SVN involved with it +(who have not had issues with those messy .svn folders raises an hand !).

+

It have not been so easy to share code and thoughts about code, to propose +changes on existing code, than now. You think it's better to implement this or +that in a different way ? Clone it (fork it), make your changes and publish +them, and then ask projects owners about it. For sure you'll have answers.

+

Even if they don't want it, you can easily keep your changes, and keep getting +their updates!

+

Also, lot of fashionables projects tend to move on DVCS. +Personally, if I know I can fork on a DVCS instead of from a "simple" VCS, +I'll probably be quicker to fork/clone, and to publish changes on my own copy, +than if I had to do so on the upstream repository (and I'll likely dont have +the rights to push to it), because I will not be afraid to break things.

+

DVCSes makes the contribution easier.

+
+
+

Release early, release often

+

Maybe have you read The cathedral and the bazaar, by Eric Steven Raymond ? +(If not, consider doing so, it's a really interesting reading)

+

Among a lot of others interesting things, one hint he gives is release early, +release often.

+

I understand it as: if you want to get contributors, release your code early, +even if it's not perfect, and don't be afraid to publish your changes each +time it's needed.

+

Without notifying it, that's basically what I was doing for my own projects. +I guess that's because Social coding platforms encourages those practices, +partially cause of the possible impact publishing each of your changes can have +on your final solution.

+

If you have considered publishing your projects, code snippets, or whatever +(code related) but did not done it, considering them not yet ready, maybe +should you think about it twice: you can get feedback and probably start some +interesting discussions about it, if you write code that's readable, of course!

+
+
+

A step further for open source softwares

+

Well, DVCSes are a honking great idea, and they're starting to be really +powerful when applied to free softwares. I mean: if you can't see a project, +it will be hard to contribute to it. And, I don't think anyone wants to +contribute to something closed/proprietary, just for fun. Or maybe am I +missing something.

+

Maybe it's a kind of revolution, about free and open source softwares (FOSS), +that is going on. I really like to know I have my word to say about the changes +in the tools I use, and to know that I can make them evolve.

+

Let's take an example. Imagine I'm using a web framework on daily basis, as a +part of my job as a web developer. I do like using an open source software +because I know how it's working, and because I know that I can interact with the +authors of the framework while they're doing the changes on it.

+

That's communication, nothing more, and of course I can do that with an internal +proprietary solution, but it will cost me a lot more time, for a dead-simple +reason: a company is not as big and powerful as a community can be: it will cost +time to work on this framework, resources to maintain it, fix bugs etc.

+

Well, I'm starting advocating here about Free and Open Source Softwares use on +companies, what is a bit beyond the scope of this article, so let's back to +our DVCSes and new social related tools.

+

If I find a bug in this framework, while working, I have the possibility to +go and talk with the creators of the framework, to open a ticket, and even to +make a fix for it, because I've access to the source code. If I want to create a +new feature, I just have to fork it, hack it, and then publish my code to have +feedback of the community.

+

My fix/work will benefit to all the people (and maybe others companies) working +with this framework, and it's a way to prove the community that my company is +enough skilled to make code-fixes to the framework, so that's all good !

+
+
+

What's next ?

+

I hope those social coding platforms are only the begining of a new area. I hope +they will make people realize what the power of the community is, and how easily +they can becomes part of it.

+

If you're not using them right now, maybe you should do so: have a +look 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 !

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html b/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html new file mode 100644 index 0000000..df16bee --- /dev/null +++ b/francois-elie-quelle-ecole-pour-la-societe-de-linformation.html @@ -0,0 +1,170 @@ + + + + + + + + + François Elie : Quelle école pour la société de l’information ? - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

François Elie : Quelle école pour la société de l’information ?

+ + + +
+

🌟

+

http://www.framablog.org/index.php/post/2013/06/11/francois-elie-education-conference

+

Quelques bouts selectionnés.

+
+

Mais pourquoi continue t-on à enseigner des maths à des gens qui ne vont pas +les utiliser ? Ben évidemment c’est parce qu’on n’est pas dans une école de +l’initiation où les mathématiciens font ça entre eux et on n’est pas non plus +dans une école de l’apprentissage où l’école a pour but de donner un métier, un +bagage utilisable. L’école ne sert évidemment pas à ça. D’ailleurs heureusement +parce que sinon on n’enseignerait pas la philosophie qui ne sert à rien à part +fabriquer des profs de philosophie !

+

On n’a pas besoin de tableau numérique pour enseigner l’informatique elle-même +pour enseigner la science. De la même façon on n’a pas besoin de machine à +calculer pour enseigner les mathématiques. Évidemment ! On n’a pas besoin d’une +machine à calculer pour savoir faire une division. Au contraire, surtout pas !

+

Il faut cesser d’opposer l’enseignement de la programmation d’une part et +l’enseignement des usages, c’est important mais ça c’est l’école des maîtres et +des esclaves. Ce qu’il faut enseigner, vite et à tous, c’est la science, pas la +technologie ou l’usage. C’est en amont de la programmation, l’algorithmique. +C’est, en amont de telle instanciation, du codage, du chiffrement, la théorie, +quelque chose qui comme les maths n’ont besoin que d’une craie et d’un tableau +noir.

+

Ce n'est pas un hasard si le mot "numérique" à remplaçé le mot "informatique", +c'est qu'on voudrait nous faire croire qu'il n'y a pas besoin de l'apprendre.

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/gnome-3-extensions.html b/gnome-3-extensions.html new file mode 100644 index 0000000..260f4c8 --- /dev/null +++ b/gnome-3-extensions.html @@ -0,0 +1,179 @@ + + + + + + + + + Gnome 3, extensions - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Gnome 3, extensions

+ + + +
+

🌟

+

Après avoir tenté pendant un bout de temps unity, le bureau par defaut de +ubuntu, j'ai eu envie de changements, et j'ai donc essayé un peu de regarder du +coté de gnome 3, à nouveau.

+

Et finalement, j'ai trouvé quelques extensions qui sont vraiment utiles, que je +liste ici.

+
    +
  • Antisocial Menu vire les +boutons et textes en rapport avec le web social. J'en avais pas besoin +puisque je suis connecté à mon instant messenger dans un terminal, en +utilisant weechat.
  • +
  • Coverflow Alt-Tab change le +switcher d'applications par defaut. Je le trouve bien plus pratique que celui +par defaut puisqu'il me permet de voir "en grand" quelle est la fenêtre que +je vais afficher.
  • +
  • Media player indicator 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'intègre niquel avec +Spotify, et ça c'est chouette.
  • +
  • Rechercher dans les bookmarks firefox +permet de… à votre avis ?
  • +
+

Un peu moins utile mais sait on jamais:

+ +

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

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/groovy.html b/groovy.html new file mode 100644 index 0000000..2a30a7b --- /dev/null +++ b/groovy.html @@ -0,0 +1,153 @@ + + + + + + + + + "Groovy" - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

"Groovy"

+ + + +
+

🌟

+

“Groovy”, c'est comme ça que je l'aime la musique: peut importe le style +finalement, la bonne musique c'est celle qui sonne, celle qui groove, celle qui +fait que tu tapes du pied (le droit chez moi) et que que ta 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 ;)

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/groupement-dachats-partage-dexperience.html b/groupement-dachats-partage-dexperience.html new file mode 100644 index 0000000..57f5c4b --- /dev/null +++ b/groupement-dachats-partage-dexperience.html @@ -0,0 +1,212 @@ + + + + + + + + + Groupement d'achats & partage d'expérience - Carnets Web + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Groupement d'achats & partage d'expérience

+ + + +
+

Quelques retours sur la création et l'organisation d'un groupement d'achat.

+

🌟

+

Il y a quelques années, on s'est motivé entre copains copines pour créer un groupement d'achat.

+

L'idée est simple:

+
    +
  • commander en gros, pour faire baisser les prix
  • +
  • se passer d'intermédiaires et favoriser les circuits courts
  • +
  • aller à la rencontre des producteurs locaux et échanger
  • +
+

Notre groupement dessert actuellement 18 foyers et une 60aine de personnes.

+

Au fur et à mesure de la vie du groupement, on a développé quelques outils pour se simplifier la vie. Voici un retour d'expérience et quelques astuces / outils, au cas où l'envie vous prenne à vous aussi :)

+

Organisation

+

On organise environs trois ou quatre distributions par an. Le modus operandi est le suivant:

+
    +
  • chaque product·eur·rice à un·e référent·e, qui s'occupe de faire le lien;
  • +
  • une personne est désignée pour coordonner la distribution;
  • +
  • 4 semaines avant la distribution, les référent·e·s mettent à jour les prix / produits dans le tableau de commandes;·e·
  • +
  • 3 semaines avant la distribution, les commandes sont ouvertes;
  • +
  • 2 semaines avant la distribution, les commandes sont closes;
  • +
  • Les référent·e·s ont ensuite deux semaines pour récupérer les commandes pour la distribution
  • +
+

Quels produits ?

+

On essaye d'avoir uniquement des produits qui se conservent (on a également quelques autres produits plus frais, mais avec d'autres modalités).

+

Entre autres: bières, légumes secs, conserves, jus, miel, pâtes, semoule, café, vinaigres, pommes de terre, oignons, huiles, farines.

+

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'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'est pas animé par la même éthique !).

+

Paiements

+

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'attendre la date de la distribution pour l'encaissement. La plupart des producteurs acceptent d'être payés sous quinzaine.

+

Le jour de la distribution, tout le monde apporte son chéquier. Nous avons mis +en place une moulinette qui s'occupe de faire la répartition des chèques automatiquement, chaque membre se retrouve à faire en moyenne un ou deux chèques.

+

Chaque référent·e est ainsi remboursé·e de la somme avancée, et chaque +membre du groupement d'achat paye ce qu'il doit payer. Nous n'avons +volontairement pas de structure juridique et pas de compte en banque. Les +paiements s'effectuent directement entre nous.

+

Transports

+

Chaque référent·e commande les produits, puis ensuite s'occupe de les rapatrier. À Rennes, on a la chance d'avoir pas mal de producteurs aux alentours, donc c'est assez simple.

+

Le mieux est de ramener les produits juste un peu avant la distribution au lieu de distribution, ça permet d'éviter de les stocker trop longtemps, et d'éviter aux producteurs d'attendre trop longtemps avant d'encaisser les chèques.

+

Pour les grosses commandes, les voitures se remplissent bien, mais ma petite Clio suffit, que ce soit dit !

+

La distribution

+

Un peu en amont de la distribution, il faut organiser l'espace. Des tas par membre sont constitués pour faciliter les choses le jour de la distribution.

+

Le jour même, on se retrouve, on charge ses marchandises, on échange quelques chèques et on papote ! On en profite pour:

+
    +
  • discuter de la date de la prochaine distribution;
  • +
  • trouver une nouvelle personne pour la coordonner;
  • +
  • discuter de nouveaux produits;
  • +
  • refaire le monde;
  • +
  • changer de référents pour les producteurs.
  • +
+

Et c'est reparti pour un tour ;)

+

Nos outils

+

On utilise un tableur en ligne pour partager les prix et prendre les commandes. On a essayé d'utiliser ethercalc au début mais ça ne fonctionnait pas pour nous à l'époque (trop de petits bugs). On a donc préféré utiliser Google docs (ouch).

+

Il est d'ailleurs possible d'y intégrer de nouvelles fonctionnalités assez facilement, du coup Fred et Rémy ont planché sur un moyen d'automatiser la répartition des chèques (qu'on faisait dans un premier temps à la main - assez péniblement).

+

Le système n'est pas parfait mais fonctionne quand même assez bien !

+

Quelques ressources, donc:

+ +

Bon groupement d'achat ;)

+ L'image d'illustration utilisée est un travail de Rudolph Fehr proposé sous license CC BY NC 2.0. Merci ! + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/habitat-collectif.html b/habitat-collectif.html new file mode 100644 index 0000000..c2b8f15 --- /dev/null +++ b/habitat-collectif.html @@ -0,0 +1,159 @@ + + + + + + + + + Habitat collectif - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Habitat collectif

+ + + +
+

🌟

+

Habiter à plusieurs, partager un lieu de vie, monter une communauté, changer +nos modes de vie et prendre plus de temps les uns pour les autres.

+

Ça fait réfléchir un peu quand même, non ? en tout cas ça marche chez moi.

+

Voilà quelques ressources qui peuvent être utiles si jamais vous aussi ça vous +titille:

+ + + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/help-me-to-go-to-the-distutils2-paris-sprint.html b/help-me-to-go-to-the-distutils2-paris-sprint.html new file mode 100644 index 0000000..9b92967 --- /dev/null +++ b/help-me-to-go-to-the-distutils2-paris-sprint.html @@ -0,0 +1,164 @@ + + + + + + + + + Help me to go to the distutils2 paris' sprint - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

Help me to go to the distutils2 paris' sprint

+ + + +
+

🌟

+

Edit: Thanks to logilab and some amazing people, I can make it to paris for the +sprint. Many thanks to them for the support!

+

There will be a distutils2 sprint from the 27th to the 30th of january, thanks +to logilab which will host the event.

+

You can find more informations about the sprint on the wiki page of the event +(http://wiki.python.org/moin/Distutils/SprintParis).

+

I really want to go there but I'm unfortunately blocked in UK for money reasons. +The cheapest two ways I've found is about £80, which I can't afford. +Following some advices on #distutils, I'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 way.

+

I'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't make it to paris, I'll hang around on IRC to give some help +while needed.

+

If you want to contribute some money to help me go there, feel free to use this +chipin page: http://ametaireau.chipin.com/distutils2-sprint-in-paris

+

Thanks for your support !

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/how-are-you-handling-your-shared-expenses.html b/how-are-you-handling-your-shared-expenses.html new file mode 100644 index 0000000..9134457 --- /dev/null +++ b/how-are-you-handling-your-shared-expenses.html @@ -0,0 +1,227 @@ + + + + + + + + + How are you handling your shared expenses? - Carnets Web + + + + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

How are you handling your shared expenses?

+ + + +
+

🌟

+

TL;DR: We're kick-starting a new application to manage your shared +expenses. Have a look at http://ihatemoney.notmyidea.org

+

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

+

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

+

I said yes and gave it some more thoughts: We probably aren'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, boooh!).

+

I then discussed with a friend of mine, who was excited about it and wanted to learn +python. Great! That's a really nice way to get started. Some more friends were also +interested in it and contributed some features and provided feedback (thanks +Arnaud and Quentin!)

+

Since that, the project now support multiple languages and provides a REST API +(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's it (this was inspired by +doodle)!

+Capture d'écran du site. +

You can try the project at http://ihatemoney.notmyidea.org for now, and the +code lives at https://github.com/spiral-project/ihatemoney/.

+
+

Features

+

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

+

No, I don'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 way.

+
+

No user registration

+

You don'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 you).

+
+
+

Keeping things simple

+

"Keep It Simple, Stupid" 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're back from the +farmer's market on raw paper.

+
+
+

No categories

+

Some people like to organise their stuff into different "categories": +leisure, work, eating, etc. That's not something I want (at least to begin +with).

+

I want things to be simple. Got that? Great. Just add your bills!

+
+
+

Balance

+

One of the most useful thing is to know what's your "balance" compared to +others. In other words, if you're negative, you owe money, if you'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 balance.

+

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

+
+
+

API

+

All of what's possible to do with the standard web interface is also available +through a REST API. I developed a simple REST toolkit for flask for this (and +I should release it!).

+
+
+
+

Interested?

+

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't hesitate +a second! The project lives at http://github.com/spiral-project/ihatemoney/

+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/how-to-install-nginx-php-53-on-freebsd.html b/how-to-install-nginx-php-53-on-freebsd.html new file mode 100644 index 0000000..e8dae65 --- /dev/null +++ b/how-to-install-nginx-php-53-on-freebsd.html @@ -0,0 +1,193 @@ + + + + + + + + + How to install NGINX + PHP 5.3 on FreeBSD. - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

How to install NGINX + PHP 5.3 on FreeBSD.

+ + + +
+

🌟

+

I've not managed so far to get completely rid of php, so here's a simple +reminder about how to install php on NGINX, for FreeBSD. Nothing hard, but +that's worse to have the piece of configuration somewhere !

+
+# update the ports
+$ portsnap fetch update
+
+# install php5 port
+$ make config-recursive -C /usr/ports/lang/php5-extensions
+$ make package-recursive -C /usr/ports/lang/php5-extensions
+
+# install nginx
+$ make config-recursive -C /usr/ports/www/nginx-devel
+$ make package-recursive -C /usr/ports/www/nginx-devel
+
+

Now we have all the dependencies installed, we need to configure a bit the +server.

+

That's a simple thing in fact, but it could be good to have something that will +work without effort over time.

+

Here's a sample of my configuration:

+
+server {
+    server_name ndd;
+    set $path /path/to/your/files;
+    root   $path;
+
+    location / {
+        index  index.php;
+    }
+
+    location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|xml)$ {
+      access_log        off;
+      expires           30d;
+    }
+
+    location ~ .php$ {
+        fastcgi_param  SCRIPT_FILENAME  $path$fastcgi_script_name;
+        fastcgi_pass   backend;
+        include fastcgi_params;
+    }
+}
+
+upstream backend {
+        server 127.0.0.1:9000;
+}
+
+

And that's it !

+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/how-to-reboot-your-bebox-using-the-cli.html b/how-to-reboot-your-bebox-using-the-cli.html new file mode 100644 index 0000000..ea12a67 --- /dev/null +++ b/how-to-reboot-your-bebox-using-the-cli.html @@ -0,0 +1,195 @@ + + + + + + + + + How to reboot your bebox using the CLI - Carnets Web + + + + + + + + + + + + + + + + + + +
+
+
+

+ Carnets Web +

+
+
+ +
+
+

How to reboot your bebox using the CLI

+ + + +
+

🌟

+

I've an internet connection which, for some obscure reasons, tend to be very +slow from time to time. After rebooting the box (yes, that's a hard solution), +all the things seems to go fine again.

+
+

EDIT : Using grep

+

After a bit of reflexion, that's also really easy to do using directly the +command line tools curl, grep and tail (but really harder to read).

+
curl -X POST -u joel:joel http://bebox.config/cgi/b/info/restart/\?be\=0\&l0\=1\&l1\=0\&tid\=RESTART -d "0=17&2=`curl -u joel:joel http://bebox.config/cgi/b/info/restart/\?be\=0\&l0\=1\&l1\=0\&tid\=RESTART | grep -o "name='2' value='[0-9]\+" | grep -o "[0-9]\+" | tail -n 1`&1"
+
+
+
+

The Python version

+

Well, that's not the optimal solution, that's a bit "gruik", but it works.

+
import urllib2
+import urlparse
+import re
+import argparse
+
+REBOOT_URL = '/b/info/restart/?be=0&l0=1&l1=0&tid=RESTART'
+BOX_URL = 'http://bebox.config/cgi'
+
+def open_url(url, username, password):
+    passman = urllib2.HTTPPasswordMgrWithDefaultRealm()
+    passman.add_password(None, url, username, password)
+    authhandler = urllib2.HTTPBasicAuthHandler(passman)
+
+    opener = urllib2.build_opener(authhandler)
+
+    urllib2.install_opener(opener)
+
+    return urllib2.urlopen(url).read()
+
+def reboot(url, username, password):
+    data = open_url(url, username, password)
+    token = re.findall("name\=\\'2\\' value=\\'([0-9]+)\\'", data)[1]
+    urllib2.urlopen(urllib2.Request(url=url, data='0=17&2=%s&1' % token))
+
+if __file__ == '__main__':
+    parser = argparse.ArgumentParser(description="""Reboot your bebox !""")
+
+    parser.add_argument(dest='user', help='username')
+    parser.add_argument(dest='password', help='password')
+    parser.add_argument(boxurl='boxurl', default=BOX_URL, help='Base box url.  Default is %s' % BOX_URL)
+
+    args = parser.parse_args()
+    url = urlparse.urljoin(args.boxurl, REBOOT_URL)
+    reboot(url, args.username, args.password)
+
+
+ + Vous pouvez également télécharger cet article en pdf. +
+
+
+ + + + + + + + + + +
+ + \ No newline at end of file diff --git a/images/abeilles.jpg b/images/abeilles.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d6910c3baeda6d655de827f6d6ffc817a50428ba GIT binary patch literal 71082 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 literal 0 HcmV?d00001 diff --git a/images/cors_flow.png b/images/cors_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..63b8be8f5e8de793ffe2c9504a6f1bf6d1d8a985 GIT binary patch literal 20718 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 LzgOel$g_V3vhcbA literal 0 HcmV?d00001 diff --git a/images/daybed.jpg b/images/daybed.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b815e6c27822df1936c7278a23e2d8e42dd36a3f GIT binary patch literal 134507 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

x>_{>8tMroQbwUF^?J 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

Vo3xOPDX%N$43-5 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 literal 0 HcmV?d00001 diff --git a/images/filtrage.jpg b/images/filtrage.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7d448beb9bd5214e1abacdd2e46eec83befb8d30 GIT binary patch literal 120392 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

RL!VF~4}p)hZ^?=~{v2e%0cv`I$bTcw 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ᕾ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 Byq*96 literal 0 HcmV?d00001 diff --git a/images/focus.jpg b/images/focus.jpg new file mode 100644 index 0000000000000000000000000000000000000000..032220a70dbe70a6994803c46ee397ea04f36c83 GIT binary patch literal 83682 zcmbSy2Ut_Vw(i~u1VZmf@4X|^rT0!KQZ-2Ly@Ld#BfX1&AT4weLQxo48i-01FjUj!q@&{*MDH)|B(3yR{4vaynURmWd7>x=j845 z7Y|Pjh5;1Xb z^mGVtVpsR|_H*zF2Y`Rv^WRbc)nD7PUm00iLQYy*L{jw1{Qso?HuIlS|2_EY+kZ%W zGyM;rfpla4;{B`azj(ft03dsEWt*&j@$MD_KxYB~TwDAXkNYtIkjDc6X5!!Ohwg8G zaSICalNS>U4Gk4_cXky0YtVnv|5f0hlK(aMxAsK;w)aolv1>THI0SnIvHvxyqpz25 zZ~%LtpM#?_yU739iT}q1|4prb(?b~H?BX2Y>~qzW)w~v#1kh`xBySvYS z<>CKfv47LyFZ@Tpz5>)$zX6&%q5#DN4FEkH1MsMc0jOQsRSx)1zZt+Sfxl1QEwkPYMkg+NJA7E}T?K?4v0T7yW?74!jv z!6@)PmA?P#|2R(pZ;KA^y@!0W1@D%WL@GS5g@%-`b;XS~6h*yV)!5hSz##_fb z#`}#=iqDKMgfEY;i*JSRiXV!fh+lwTgWrMw8h;jl8~+prgVDkGU@|Zrm^I7;772R* zD}}Ydu(0>AP1p$m0RaPn5W!6XV*&?)Ac91KVuD73eu622ZGv+`VnQ}TNkT0`8$ut# zIKl$Ldcr=!DZ*XCA8-md4_qE@40nQu!!zMk@E-UCd>j6Qh?0np=q8alkq1#MQ4vuy z(QBe*qHn~+#GJ%(#HPgV#3t!vKX=wG7Q-i*%3LMoQGVM{5E+6c>(z|@(J<- z3OEHXg*t@;#XX7=if)QIiW5p|N(oA1N^i;sl=YNvDL+yXQ1Mb}QaMq@Q$3-2MYTx{ zrRJhmr*@>iPhCa*ntGcCM#D#=OXES4M$<$yPIF94MJq*XNgGC6LfcD=ql41%(&^H9 z(Ph%L(S4x1q-UX5rFW)Jp>L+2qCdOFbWP=&^R?7#E!SqRT{5sUXfk**WHWR!tT5s+ z3No59hBB5hzGggNqG3{Ca%4(nYGYbthA;~RxpRlm9XtVgS6tlcyIbfw@ zRblmD&13Cj-D9I>Q(|*x%VXzpYDdZXAIpgKyy~Ufv+sXTp?;4*j zUj$zR-!eZbzcRl+e$0aWC;I@g)f=2|bB8i5`is zl7fKlePl5Py#_$4hP9U$E-y(hyhgOqtB zGbc+UYa;tVc32KyPE9UG?uFciytI6fe4G4d1rY^Lg?fdLihPRBidBl6H#u)Q+^o2X zQ({*_Dm_-hDRU@0C|4?PsBoz`snn?KstTxjs5Yt|sfnuvsCB5FsmrTJt7A2w8rmAE z8snN&niiT5HCMGbwOq9tw2rlJXh&*eb?|lcb+UElbXjyAbwc51F>o@u^h!EX_4FBx^`>jC>zB_b(ng9_1cqp2nWF zo`1YGdLzBNeW-jqeFlA5eZzd;`w96a`r-WL{qy~g1M~xG0>ME0z^)*gtI5<@ zFn@4D@Op?+NJ+?fsAcH0Fv>8Wu(5E#@Rab~2(5_fNW4hL$bl%1sMx6WXw~S7d*Hph z_Xc9PV&Y@AQQD}wSfW_Z*mrT_aXE3{@87!L6VDQlir-AoPH0FZOAJVyOHxQGPsU4j zPaaRXo>H9hJJl(5BuzZ6AnoS^#|IAE7!VVVIqr1p#C2JBz33A;sy!Hjhi;`a2-poFtzWBaB{So~qSU>E+ zOV^j119t|NURk}G88jUnf35#|_>I<^S3{~p{lhnhU%Zun+dU#X(m5(UiW$2x*75Gf zyN+?`am<9wMAxL;WY2rW_kB~!Q!l4Arr*ry&Wz3)&A$I&@nL?>ZVor^H2-nIYvIdc z$l{MB)H42Z>I%h5!7B4=<(j}+3r-r>yRNZ5wqdrhwCT9{X)AE+=XU%K=}y5e+b;T} zfGw)@+k{676SNIaxGe00Qr)c#rJ^VqS~@%ER1FMqy1_{Q+9_Pf;gffJLH z)l=`&A7`oO4Ci$hvKK>_w=Q>og#IM>S@cWbSI=+#-^+iz|NQy01gQUAXZ(vGSA*gr2)Rq8)P z{=bqxSb&lctcReWASD2y1fi7RpFx1_YEFX({ag9psmfo1;o%byLZEOW5Fox1Fr)xL z=#{cCC_W7T>PiR&Ay7PgN&rU1K_H<@NX=>L;7=2q4VSEVdQ8iuhIsk@`rUx_FLc~Q z^y+4gfpOP(q%@pzD%*I??_X6%^RI^f(cIPI>xxVH&*uNhT?9y=;FY3KN_VgO~f~B(?8{K=%mWpCWD&O(MDdBsC zC>y}4bHbT?Q6CIHN5P0$X}x>9*MQ~YjyKEWfKty5%`hvL%u!HB_PG(&wSsgR#W(Xr zfo!541#PD5f*<8@!t|u>?x~kK2w`n8Mf|MVL9M(TKo)ZDpA|IE^aDv;p{d8vlcdan zn*Zd^i0Ui=p%1Dx(rPDw`As+k%T@zYZF1l5GWmv;8uNI|&buNGbZ8N^tgp2+L*&ar zeScS@c_8AQfRJjBS?kgq$TVJ4Q6;Zpco?{gN@g6{aaP^Ui_fWM`PoW^FUBo}AX*|a z&ToYYZxu-Knb9qce#Ls-)st?px(kUMi;Ck>_JUiT6>s6^>El47%tgTn_ ziOTr?2Fw<%{n+Jv#G{(Z+*JYN8Xs4PKuDXksLwm$oDn>fSnud-T%)WVZ_-{3< zyL;G~XIYSGzHs~A)~sEDwd^^vC{{u1CjQXl*H7TT^^Gj*=h-&uu0&9sHKVpZ30O|P z-?%;Yo_67r$m9+m&h`GVWEYgbN-zO1yf(-?wH&7<@_cY6La~Yd`U6X$h*kar zIH2N}E2B)BWH-#K-ozi2-Fb~BWJ|jblFr^GZlsxCD?K~KLd-eh;4;hyF*T5z^(s#h z1B#Zt{r#ILpl+I($4REaC#vblkJ8AiNR z^{J&H2pIvm&)o1easyEx3vR9V)32NUX7zS|(C0+V-5XbAt?05jl+3we;*gjf0q$A4sl|aUI)~W9fXRHGkiV zZ&QS`#^nxsmV-O?rvL zW*Sp?Jf|>-s&b>4!_FT_5hJ3*i0Q0#LGJhW_!|w zjb6IzBeNC-8w8_M2*8KAA5NFR3u!o=%rz48r;d}hVERBi%FB=Ow7fjK3(uoA+7V!MQQnPBySiV zh2kZW^zmar?h;AF#6hU1*659z+<3Et^NsO>XbPG38;hT|BV z*#-CLdofrNqX#I$`NMBmLW8&*3x^n6Uldt`njYdw6}1L*m=!Ss`q(wj#z)J zLUZ|5On7>uWIPp|Q*WE0t2-Ta{B@@}g=1Gl^qHtT6SO@Oct@7}B9b@*echuv=-eJ$zTq@Kmw$Yi}#9mN&ykUpYo~J$1A+ z*Cmc=6-BJ4H+4j-c|#6_PZvHs2@R#YT7Ad zs&I8DQo-w>5{$kv{6XbH0@Y&C<6w%&k}EyKYIhJ4t#C8ht^o|DwWS0|f{rE(z#1f3 zQdP6Bc-jY%8VefO^pO_p-ihwctiWo}KI&hU>W7$lE=`>5q0$RgOu}{5fF6wW&!hsd zcf|iewJatpul7xd0w9K2RWE}?Y$m`jrB)fXtDmhr*B`bHQK=)uEA1C} ze_`!G@&5f+KhxE-t(wQ9q~h7Fq)U7{8geMIM9uwJDle-%(d72u}6QVz= z($}8mf!X%xIG_@Tv>>?s9EGRdx|=&0Xdx;#<_l)u>`bA9@%A3w3LIBYm2f}&JbbWm z+Q{dL9@WS1y?kns?b=X&gQ0;{Ux(btx z&9s_&b<%qIxM9QQtd^d%ue*1{=N}PNg?zo+$HH?Oizv}$_w9W#4su7orG=EEnHb6|XnV%f1&2N-!CecA^$YZH}v z#nZvk?hMLs0b{%Hyw73zuS9bL9l8`QPnLkmHNu(2_WI)WZph}<`)m%ZxdpS7>RRFu z`qa7l$pIBsh&$R@IIK z41f8N22ddg_akrw)$P^P$QTTmeLfGXtb`J$S8TfWAp_8A0eyA@LG+u?Cji8HU}=HtoRDB#o|hMr(m zPZ+^_`qh}*Gqg{Q{s4)P+v`5|b9n$2*>`WDF&*4_xw8*NW52`@;zU1{J&QA?rUB%hv$}m+_ zH;WdV+A-S_{4Ac&joIj-X{4gUu~SCg8D=JUIKHq<7r`49J>o3yavR;v0nwa96qM?r z)YG;Q3*5YafFL`j10zVBD|7dwuPmgwbP`oYX{P>Y5rGM2clfQaglg?`x^&xb_2 z-_uS_qigD0rqPdJ8`A;$KDEzl-&xOaHsY;R2e)(weC&VO zSyx`M1GtLKA={G(6)0FqPRip_|C&o!#X-v%;Yfo~Vfqw3*e3GLkF5YQw(CQ=Q#Ki0 zdmdXT>#l2IXl%I>OYzl3N}9;AePec*og?qJdKAIENZC{GbvB24wC2xzT`y-ph7yYk9|h1YkL~ayihru81y$<@3ok>OyM996lCD#@i{ENIs-S{>+OKawqVN z&#EpDphkJ1XS$w0s!;5i&Xd>Q3M+9=$j^M(6#YvE8(5gp7M58^GN>%j{S+%dQ2Zro z7#sfeP)6c%+rx1hnK(mZZYjrqG7pUrLh>26&2bww_~)paiB_Pdq6DYWDkVqC37m7- zhdU;f(*nT4`l9lzRwkicdHOr_jtmN~7onec4cK5zb;H6kX9ireq3%=s- z!$S;I!-qj~%5v>h6~=dZq5z~RqitR9*@VF6rY8U~nM7d@O~Yqhbn<4SKfYth->z5M za(+4V_tsQ6ocM~B>CLt>Q{s2_oF3+z1`4Egk;2uKKyNqhrpNIgK)OST#v)0rgPS!B zKEhnp1?nZ~e;x&nmjF@O%J zsmH#Nzx)`P`6j%efv+sOGdXrqKK{?s?1C?ll%le01KyueboFiKbii8VB{Ni5&^2|P z_pA?i!*WAFFG}fAE8f$`JnSsW2GGKn3+%Cdpink`CtD)eF&{0pGy&wBbRQTSK!R15 zj_!X#ndv7p)D77uDTE`L!iEYQX9GG^Yng2R03n7=-iN3yrGN)hOu4j=6VM$3u+_wQ zLhDOC6U)s^o-8=;&xuc75KHczd1|YGSQB&`Dg^OpDt6y&`zzKugY66BbGjh6;)=az zkJ#-Ebb|PHhe>;n>9o)S2xPPOjqB@DCPX8ph{MjW%fHzS2o%mYOTN9aPO%-617FY1 zQ8HHdYJ`jFq&s%s698@GqSvdAWcr{b3!RxSBsQAu(W;we_L{Wrh+^7HgB!GMG$pjk z6h2y)=2lY;Y{zz7;H%#&ib@-2WXzdmZDZ%m);Jyy2|K;l95ci2TkRzRx;FS}$+~U1 zPF*M+8!A8AmS@Hk&zv1)CimN6d{0TFmn!Bpk`&&*MFw|uJw3rjx*rHFO4q(QV$&PF z=mAsAlSoCL2`p7L=|ZvQ5#OL=QHdF8QlN}ti4aX}*vqBYocTq3w z^8_a5x+>@#J@wx&zNbQ%4R>-RJ>;6Ft@@b=-k}fk*=D>eAj*1(5DeVGD@)LI7uem; zM^Yo6OLcOVGMv$Lve?!O@<>Al{{Y^tloqb2Z0lQxaQ>soJ6slxIoZ?4Sgv>BF@jIk z?>@9(Afs)9tVM=QJ31VqQlDu90`K=4LL{ls8u8UCG4MrPG#R98hioD|jz3qRC$L7I zhDt~CUHS!i^Eu)ElUJdeD#3F_2xfgv+nO`XpzX;7$fWbu#(V0cg%K(!o%XK#23&G>bDXbhcuXNmGOv5# zb8Pt1w`Eegf1NfedK;P(RH~9uK#+|Mxb@(Lbj_HiQBB=P#0gbe4D0f*-kW}OB?rmt zgSr<#q-PfIswZ@s3O!|>b;JIy~B4DV^jmKfbz@dah;?WjNGou|!i8>|aO0L3A1cqJIuWOYUxpkYH zIuX=<{d=g7Z!F%W8#xnw&hZhI!Rlr2R19)gt7Jw&N6D#Rb0=5^)JJ~AOZF{& zr#s?AsxX`tPU*9svO0J<(6MURz?c^u^UQErui% z-uV$JSmU4YCD;CrM06`u9EnGXrn^8AuRldXR51XiZ0hRejN(_L$*Xd|B@ENGjMHH| zL=Bmk&cJ!kNfRO|2rqErCm5)H17v6y<$G(j)ATEr&#EVRC%ToL+G#9@bz2=G>4|kK*0sNZl=Jc8W7reAE`?4 z4a@Cc!UXz?7Lnq|$4S%6k|?wmQZyaVkYhkTN)JL$ff+Wg7aR#IGRudkjV8+)*IB`L zO>S`Vx`U7%KZ+y2#v6t_ItU-5te8BUjNhkJny@y+*l?SR-JVr=x_8wjO-{vkto>NE z{RsIhgKrvXSDxW{CdF;DV(SMT1??h@LYklWJrRCe3ZBmg!_# z8~rw;v<1v|jNdp05+p28dUkhhC|Xv=e4j@@r&?;zL721HuHTwp!3t;Uqy3?RTb*s+ zi`%#5L?3;tn0;xJK3nakhrkh-=%e+5ZT8h@{ZR$ilSsNkvCDI6f5(8S{Ey)HLEFKW{c}9YCCH-KwI*6_jb_1^GS9 ztW!Af;Pj34xHZPif78&R*4`Tq|Fx9hjoD}ksupR2uLT(W;KuR&0oolEc3%{}eo(b@ zTgatgfKAtCIz(aoONd$OR!-1-B%6wQ(S^*R^G5Hjj36KQ_Hd(X{Ae+0;d@4^sUp>F zj>kTa>2wfh++fgENI)U5tSiR8&e{5UzD+>UPp3}>@2!s7t9+56T=~C}Fwl%Bm5GZ& zi5<6zZ64!dBf>k;?A3-GZrTy#`muGKa~-FjP-T+FRDsU!+j?Wd$<`8&N7UO8PgfiC z^b#LS1J#a^EUok{DHr|1PFI6Wy-wBeJ;^5$Kjs??747G{6c2nFe))PLGv=r+$Umw;Z4)fsU!s@y7nK_8 z$TJMCl3bc{l={$on7z_u|AnixSUs(KMG%e+FHb^@`C?`{6)bA%_cHYBL0wzT&CRSn zG@>J(_s4SXPg&wLY>+|0D+bro$V8cYCYOf+ZPNNWrfi|F`pQKvaW{d}I|thar9=v5 zyV_{GQ6)g~}qxOt)P2qEP- zEJnIT(`+M8eW~J4XtT_y3fU{vN8eTtle=w2jVkC$3T=zNV(3#TvUi>YewqU( z+1k>QOa=Y`CsOlo$+SPWS45&ZtnQR6IYuHC+Ggp0uRG`(H6`>};cukUc-Izf!Jtx; z!p5lO2qevezO2V;RFz~%-Hgp(I7N8Zo7ywcW#LIW8PH8scr}tZ84XvfKY)J*+M+G8xr7@5-rxz2Z z)f{i6v~^2Od(w$w%$x;@mJQ^jeYsN-t_cLo6ZUDV{Wr#gKg^^jxl<<)Kp zd9#8Gi_VUZIE9FfbZ4IT9PoyNLNno*-1Ny_r|M{-BFIe_XSCQf5d|`ut>Yc}F`DNX zUnD8u#Pyx1#|KZa_tyN8Mo=ob+oyYLJURnarD|bC@ zN9OU2+dye1ob+oqh|Tl(v8xy*LZnMqvG2oxMjUOq4aw3G9O>KXJJr}1s_rkZ>ly$Hwy^EtZ< zJ_RmD7pnNr3IJ)bd#I#9MZx&f7LJ5;`_TE{O(@T|7kW=wn_o2~k&;sXzMdffL@w1p zMt0m8+HzHWZb)|KT6WaBedUh+tYY{FfTFf#+%kv+n^!D*?>I}@Wa}cBYbT77ET#?{ z!+`wTZ`?NBJv9KV+AeCw6JT&T;3Vb51}Lq6kA5DP9eBT z$$O$@8K=TiB~m|#KwW9&kfFkYd14m5(QXAn7v8WAd`kWsA)D2-c+x@DZvOJDdP9~o zO~eB1X?xOLeUO&jiFS3-+0VIQI$zy?8X%lgHQXsrhQ{DJUn&`H#m-URt=6_reP8#u zL9ZP@sOFel_RH^F{mo^8tG%{Cb2nFUXZl*%1DilJF($3lNXk3`U7cf|hcErSi7}7P zrSzo>r=K3P*Si9uZ!fFg6yzr~neKg#gCLgD6sX|zOGV5_I$Cx@xM)#Bb;XzUrjjqm zzIR$KRp(R1zcsJsDY)jXf!+;5S$;jJrV6T=hqAR_HokaO>hV)BR>E9iTe_ixDA#nR zTO#RAT@_|eT8D>>9KSFq?e-4>>F30!tRumTMrMZ}KGX3!F+U2sV;JCNIW;X*Xg-rq zUxu&3)s@enBaz1vPE^#-Kuc9Rt@=tLK* z%EFC{)=s%`#4s(yY`*?o_^ECootadG-BcmBoJ0pdI-mfqqc$lOU*3c8F?@*)pZ=j1 zuoF`mQnZojMn*9j@;py+xd1ooV#dXL6@>yjd8BA!t2KrDD4kBYZ=aJD`i-`y-;($1 z7~3s)CW3I5=e2UCT!>y{E|%mjc+X60?P-~q`a%tt4-w5p6$g?+>;n^-rAEZ2%?B6y zsf#@gGvV^fltpA#fdc8xLwCh#E9}cgwqjt@`)$-d>R&^bB0Oubd>;XaGxu*Skzq4${^F@Lb zsh_oFWI0EOTDpCU4;Bti=0vo|lk~#{%YiS9&5^vWO7GV)@S~X5dnNp-dwBH`HF{xx zfN$pMz#pK3b2W^xR`&G!A!wS;{z1~+jA$#Tb!TnQ8n`D*7U?gO9$un6lGpP{FJ0t> z%D^wEaz(6~{SHXCr5CXKA=aPgWrH97=Ur4=_kF=m=`0TI)WpV=X#Cu4q?}AlV+WV>87J@J?%H~18>B0e*(Cf0>7SOHD@g! z`qc^PnO%)Vw3f>m!?&v`a(DY6@3tA;;co7rG#%Dxk{!UdwrPQpdih4dqHhpW72dH} zo2Zl`TKRkyPwqOeP^{i@H9^E0pz$hhk01)#;PO(s;}ErK;h7x(-$wm>;z_1*dEj>~ zhmcO;YHdUCn&|*P_dC`T5vO_a2%_1APzu8%?{>2K*$U43ndgHSI4*&wC$biIBLc9} zKPAJhm?Chrm|?ob53&S0DS{^O?LKf@Imkx^i&R;*%Z^cm(RXn#Ud2VBq?X-NYTcw4 zIHfpPQ*IQDs3)bX|2x(l;T`ym`#aXHi-;Rg3L`lHxV=$2UkpEYT_b&pqU%6mZ$7QT zTCrmKz<1o$9r@FD2k0Nu?t61b*aq2>9O31*EtPK z(Y@kq`b`Q9AIJCFVt2PuH5Y$?1gZTKYyEpd&hl?{I~DOmHVE*FpNMb%T6pj6&RV_( z-WIgZ$S$z43p9w(Rq1O!onz7+MYX7MXX=X7h9?^}2-@9+VA!JVT z+#p-z%?BK~E2IDN-7O-$9L&g3nbx2$YE=33`LGI)0XuK31jQA+D#u13te9&;oCv|K{d?)7(tw_m3oSdG`(UB;Ps{fHOUPj8FT zBT?K>P1eB%xE^%>P!+sc7U&akU_Hpl#gOfF%iWq<6#uMo{8tgLo|sV-i{lxo5!}1L zq>$Ncj~neolTiIbC7&x^(YI)VButxwS^N)B`ziRs{6wfH!qHp*=$9dH$XGVr|Zyo|C&B2K6crYH}5a9*y=+amhkHyerGO zzq-JC0F*;g$je=RE-q)#-wJbDhPzF4D_l3nxx^c!tz?{t#Z7Sta1+q8p$@Zl z=PDd?!Y|*DF}&{@?jw^>X))elMLO5LJlh*N;vDks=wuEZX%nr|$_hVfxC*mEYW!=t zcAF{Y1RmWPmZ+Nhx}-T%U&{8TvS7A?+~XtETge!$^HCSt$Kon?vw6?QY)mfCg-a{K z-eRG_%n(t8Xk-q4bw=T(LN{Zv4%EK_O=Ndp?zfQO=J=y?`6UCKZ`V?OXkhqQ)luZ} zy(St4pWuh ze}I+u83pienXFHErDtp4Y{t8v>g%=SZQG(LhHn>sNOL5{k*dA0O)Mlr$eg>y4#1Yv z&WTlvB8`t{_rs9eW6xL7bVo&1@}HHz$#yK`1a47Yr$fA(wwFp(@GrF=Kx{d+ipGpS zM$#UyC5%Zf?%NMg?QsqnqS&_C?7%)pN&&=U4Ry6>RU@9N*7@EK;iMPYyH|&+R)3Ed zM@t#8IiKr!swXF>Bgymx)D(ZnXn7>9bUa_#CRkR}tk(YX7|s?B=O(5SCp4%E zb&dXYfn?wv(;?#C<0?A`_Bv?zOlG|NC{KK<77>pL*J>cNO*?c8wu6m)p5Jy+ae;|m z?(K~PsvQ?Bzr)D#wygl^VdyfBcisf$z&nJ5LBA)v{N~OfuL0ILX5tA};xX9 zvBr5Gsk(Z4&3*)5SZ45>jleG*=UT6CpOao5dQ#tWtbu;9Vk*f+4cX|dl|iX??NL}h zTa?EZe)kEM+qRG|KzDH-b~d*z(3@0V1_abUwzbFr$n-+&r<%Hvj3Yi#?4TFSL9i#` zYTqyDK^ld&FtmdH5+_x+{Mic@XWzvRmDw!`>tCg!()>W((=)i@HFH-&x*u zKuv0+6|RnGR6if1f`M)7dpnxP46n1YJ*i`&pi7cXj&(Tt8XXp0tdmoa;H@*Pdw>qq z+3G8n!xmRMe2KhKcmVJF0~COQt3*pC7?8MSk45Y=$}QYSN2EsbyF7iJ?-&wK@D4Tn z!g$6;%|=BK->yA2z!$Z}#;OqPT-5#bo>4|kf?SfmV3wsYxyXyx7Z*r&kDbV*;u8OJ zA@yVvQEu+^Av-*=+m)jY(}S2|n?*#5G<_@P4=@LMo-1Q7KCN#Jf2$b1FNshN_(9Ae z=KZ4+G%hk#JyE#|9y0Me9sB_-OLQ7`c^U0$O704!`O}lj&W;eJEb}L@QGWW2>gX1! zvl#LWB6-Eq6RlZLusbN?K#I;?zn$>iN-y^7aoH1)&YvJTFu>qjzT|RGD%A-u%G-}mxjDiZ?`3)U zVM8aVouUx-_A^tE-Re0k^Vv8bo@{mT?(r{(sNckeq(`50YY!?qcoU-EBrse-gs>y& zSt$x$KADeEuQg7X>juVC9MrA^p9Y8OA((7G(6JTKB|83n6TU90ZBrr|#zN z3rU9}V|n46)qjBe?~1YcZA~Kkk^~3m*C}|Um(gAjWxuWD22(Y!xhPa+7F9mKT<{+t zIibFk9OKj#a6O$9ZBj@{`gYhLP~AQ^@~2<7b)a=Zv1N<@d0PjleJ&4`Ie4e&$Q#MEFt|N^90SkSN4r{ zkIXzJ#@7q+4H=uP%2{)C^UWKsQ}<-9R`Ka41URYO&KKb_M?7i8Kol!apBKOO;9*jB zw)^mw;Qd>Lf+$OJxeZ8$1I`u^Jw2_nV?i=WNG80kQ64?FOq;}zHZ$BmO*pD4bQA{e4Y4RKP zWQo!S_;|_L;RJ?!lvqu}G_`7`-8vYkzd02X`w6fUaLc!6GPb8(1kj&g0~6*um|L`6 z3{5ZZe^XP`C!DFJ3pq|;=_`VLG~KtZ;CEj1)&;dL=Ok=0{s4niz#6D@{Fz_8cF$_ncEhgQS*Ks{c zNADqJFQ{s`=^gdM1BB`l$iMybP5zmOD70%0lr!B=&MNq+Zqbb+Ee=FzZ7~IY!wL%Z zeV{+XI;>hj*SW@*TiIwnF4MA^-m@Zg9uW2IEWU=f?UZ{L|AGlAC8C~XO3(}vH{g}r z|8#X<;Y4bQn^8bi4MwKpnDp0M!*?hEDLx4@0pvnBX2-lG!$Z`alRl{4@QfG1@Hbh! zs?}|cXg|g{bKP&B`k*e@;3cps`>uJ&E^2l)7PGOm_yZ{}b|+hx&(juI;h4&vEDHnC zZK-5Kzm6F}XUhhAdm0$A1&KI?R<`RJ? zxX5ktsXOAPQ8vdE>TBYc4_a6@uJIwqsi7kKD0E@*aGv(#cZeA0mthsP5LI8JO0~?d zS<*Mjl@&qxN(scf_->B*nNU?dX8va+J!S#%jb8AMfeYw1D*k-sk-)NSK~l;29%8HK z+QW>`_Qf+*^bk@k9*fXChx&Prw;#!RpLwmnVAPAnS?6yyaW&;NmHG$$3}uH#7{n)y zsyw`={{H$+T|B@DT2fjc&`z>2c$oy87v6c-!MtRXCfKC@L`W2qYL=-To;;*#UG-G>u?l-hN1Z^T0ZZ77v)s6aK#dP2w z(yZJqH?v|S6pN(`2aRUBJ;iq45|1nxJ$<;T(IA|Mp3k-`NVlKl=6V5_o(f@SwIbiw zoiE5Wz?FlWPJ-+s59ap5BjUcZEjSyh3!a&ygGV5~Qm+Y~A!tCN`w@>z) z2mOzbW;mJS+&p(v=eHl~l7)HP)TfvX$S#)9dOVoy=PB2S2u@l3pCz0Bo?@wWQ?wi# zMeAA`20>_i#cl9qv9ZCzLq-fa76Hz1kVPtvg2QYPCN#z%opd8}ReoJyEa*~7)=)nu`O zj!5g5j^{0Ge&)4iEjF**RJhq++#e$O11v-|so+TEiwgy2>+|4Lo)UXg3Hsgn>kbkI z9}eDUS+?^SaUnvcV+iqtKiG|CJ$r4_Q2sER*&o09Ij#Roj-IR2)It{TzQ-A+bPV{2 zMB%e+8WRWlxV&4)l-Y@hAIZ5(tC@kB(TmJd`u#Yhi*@-h3ZF2yz>`)$Fz2DudHZ%_ z(MwhSnfav`H+7_W&sH}{W*^;>9_dW8`fqU-rUU1N2gko{8gB5vv?x~PnQEa_={+zH|Gtfx zCmYm+2x~Fu06YpH%9u02gb;?s5x7`PrKh3TqJZW4OA6An{ZK408>p)H2yWG?6h?Sj z@d%+S7zFm6VL^+)r{4M;$I`r8IIh&45U;k@Zql`3Bs=p&8MAh{Yu=M?nR&L)s3zuZ9dYD^icpQ} zWx<_!@Phjekl-|r()t^hGHO^Wp9b2*WfX$3!ZtqQjQM_{GFMTr9h}t?m??>$+RB*s zWMm%$GA}z`{-vCvW?%f?f(l%b;>Q6JwK!TbdzDgbC1(M13q13q! zR?wqTR8iv*w8TOKMcsIHr~)gbsVT@#uS^2lHZ(fDJ%<6Aa$hQlZh}c~sD$CWQ3T^B z`m0;uIZmd!gWn2buB`}ROrx@L+_2*7^-7`=8DD+_$lTnunwH$E;8K6h&!sD`qhv*{ z%p5t<&G2B`y4vL`21>XzV&c`6MN=q`*XX6Sv6=*eer4HYO%G?aYH5{?ZDQ3BVmKLk z)}?Ty!t}zL*u8sNCMO)=nnC$6!uj zyMZYBiJx+hzd$NX$4s7xs%^fWCPMIaQm=1$S(Y>@=22IDZ~alT6dx+skteHPAb1hi zA^IfONhj{LeC7Tl5%p-eQCyatn$1jAGnV@?kA?v6n|ZQpA&(Ci7KC{HZBLbKH>9=S zJu<1{n23F};xNSO4%Zuf&m-S{CQ?yTF0Za}wS)0dtDPzC*PNHd z-H6`KN2O;ha3iQr$jM$goOffM{A1>PKV~*2^=7$jwAJ{efVJ(7TQ(ltTRI%^@2kbr zy^_FXjzMAe`^bC|B5570vOhTnqaE<@yI@lUT7g}v?$G3+%?IUu_^|2o>=AIP^M6rv z77k5tT^!yBF;8Wa(|fgtv^Bc?5oIslI07(tg`ILvE`LN)a)bCYCrq}CEuQ8Cyd2$2w%4qb z0Au3xt7jRc*d*%>p1&^Erh*)EVsIs~=01SZzLK*JqWh0@%4SknKIy(A@@tl7MhqcM z=zf*aH~a_i*>_Qaae}t=c4dIR`-%a>$GcS+<(KtRu$T9fA#`8aRKa~89!S2htoTXg zq?%s&5>20s|CiTSxCOl1K5bT6*mrU!Mjb`~ySR$P6@r%E?E2 zj^n{bV!Q34jdX8wJ_@%I6gF-NBkF!aRO!;dL23EV`LpWq)`09)$3hM7)|dUG)zeE! z+E0_|wpN^7$fih;FIMk@SAgcuQl_r{84n83%?zI~THM3ZOwC>0w`WW@Z<#;Elw-~B%fHwal{DNM zj@vRlh<%^#%CjeDD@@Sr7nO!m-bFHFOzDt~H7gq)W&rZUP)*Lx5*mp~0GYwqJHn(h zAo86rqti+9CN)Z<2K1ovm2r_}*K>(m%REAJt1U8TAsEq|&fJTs65YP(Dqi{=9`? zQOUXjxe{VZMoUL<9b%P>(AB~M0wTpH zqZe2g%hkz*e~W|_FDj|?uCRRGwjeD4%^;v3g7c^e#XZRPwTO-tKE-oC@$Cf5y@0~k z3LK_b*}=A!9b2Z{{YAP!th3EJ_rUt<8H-7TgSjl#D<8z?7NA1eDQij?NQOo@F$PFc z@z{$>v<7#;@5TmLZS7AJb|(xs&4Qb%ww_}jeJmxUGs*N1WF^KB4eBIMY(=Sh^ z2N7qCpX)Y=+On-pfPa6BzcjP^4{!s^;Vv&n*3xlU=%Gm4WH_G7(rErVDx-*P7Z@#5 zOEu1*W%agmB;wVoUk1bK;m+t6Q{JF^e`moRod1Y^^d=#Cr9HO9N(*yXvYy zK^;W;DIpI&LGPk%A_|!(g&UU?@hN^?Ng^sUvwR0twX}#;XEloyZNokk6f8QnfZ)&B<>ih3jdH-i)-$`2c0tMS z79^C`dCe-tM(D1={wk`+hgH(ugt=A}R7^5ZS@OyZ1>(!p@!1$R;T`COSO!f1yQ2du z^7T7gIS$LeIKhb^Tr6Fi|D(m`)mFopl60_OCuG+P@dtrSxmH*{Oj2Zg!z2K2^bgvR z>{+QS$(&7L*P11GU(Q-=EA;L}*j5F!NWF4NH@Yfw%$o1^Cw(4M=W4>lGrJ&{_2b*d zpr(NNwDgNni)CKWakp(4n56vu=Or1zS!aKSJ;iaU1h<*pd4AGkUNUcSTKKu8s^7n3 zZB5f;87|?sZh0g^_)GH3L9>E{Lk%??^P9ood0}RbT?t-nQ1Pq`n`B5eXo7~ll&b8*vX*wiN1=RJW%70Q~M^Gw6ym?3}tE_euli7LLIrh-`2X)xtawH)kl((Q;_b*L|8o$ zg)b!zTFhIu<}aHy158vE8cT}Tf2IZ{wjFZrJ3?rBTBcBCj8qA#2AW<*M?a1nO-9!$ z8)=*iW<2XNFr=63r#*mLk%3679m!%4MLLdtWuHNkG5l(=JM9Ej-O%JW0-1nuLOIBHMD>L zXpml*eTM}TFTk_=udU$k(8mmIKVEfP;0GbyVzkGhGO~4BX`74>$N&Dqs+xqH2DSP_ zIDLC+dj2hvw$x_PPI+N^EA|%l!bwJfY!kIZ$;E3|UkDfZ*3AI&!zo}UMp#&t2=%|u z)pZ;_=i>p#EvQb`;0vtgPq$qqcGK2bTgFanL6SjR`3>MZ|J?9h8q0?Z1;CG=OetW$ z%0n-D05j2lekoUQ(`UwMD%_vFe<#LHI^w@qkTg^7P0n~LMmH?WbD|Nkm zpL^x6?L8)-JRaqz{6Z4ZbyxSWX)%(h`;20{bn71*sB_g4SZxPR>gfg6U^ga#7#Dy) zK@A=n_4tVJMyl=}BThZC2u0r1Nk6H@S70?ySCX%=6#Dwnrp?vgk?-7|od{8#PAn3G z>7L#E!uto%XhAQ{hZ#V7O>-G01zWaUM~4>!>x(3e_BA-OUsz#n*yn;fFGAxVqtE{z zEXV-NQ{MN|O}rB$tX72?1lx=P3W|m(h3@$x#_QPHj^eE*|(u-5U>@&{Du`tNSju#P<|iIpYt%8_b=&p z(#`%#0kR|>&{yOhFQ`<#{g&M`4RRH@sKdZcH6n*21a`Zv1%tq^`c2x$jJPr>TfJhH_7>^v z9~+=#be4n~X-V#(wkL=>c~zQai|AN<@qGH6KM_|Ed7MARG0Tl~P=5Xm^Pb2P?@w{r z#mjdh={Kr;)(=06%9egbWg1LdBI=MZcyc~Ow1hvwuQdS$5St;c=%R^;);{ z6}OP&-PcYcf_pUscSYrmZkpxFBd6o<6B>EvB-X^)0o``>5Y=_oUxvT1uXX+nHMn%? z51YHmw;7t2jYjspq1I7Fe#FiBaXFpvZE6Efx7(F$A1xm?s`*Ft)~LU|5ml7DS@K}n z?mNx6g%t0!vp*G}5=l>Q13oLtI6>3{OT|~%1d5zk?!@ymeMbM7%vBIPs*3X+bMCP1 zQ?r9kF~-EtilBwo1iBMIW#b>!EwTFzEXoL)tEb?%fnbI! zXdC;%Y(rYZ$GW`l-k>z~S6oJ!&vKuaqst1i`B2v)Mg(YJzm|+LsTmb5P)oSHbe|9z zy6vGAogc*FC{nTRkasM#u*a<}Kn~At_*T{ICp*o^3beDJFG(gPz9xAw+>P3oqf0Ru zpBrYbL1&dHBeEt<*tinhpXb{Itmx9*Sqg8N_}?2c6ZCo?8sz;X=5gUQB8$hQQOGq+ zgPG4_wSZfo&!v;`?e^d+5J8|8S)gUOTi*fclz^cGg+!NJe_v#FDXPpp77 zo|`1j9Fr*KN|W+G3;d1c^xC$c*`J7`q%UP@p1#IE0+#~|d?H-qzbw}{jYuw6Wj|gO zU7>TRW=Q&#TywoX@uZzhy1TY+756xFZ0q<153QTIYBq7SsRtzevElDWy5YI5vzcqK zs{>Wz+=JaA+!L>Dxm^+P^yd5F+zU$bsQCP8F1`>8omfWQT+}_a z9Wc)h<&99PB>ZS*W8%xN5k{S&j@G=Wgisw`Vd*y|kbs+&Q+s3+^Qi31dd3!yro(kS zL=(6X&mutr!_L0Q#LuparuT@d4O-k3Fh|q63{5JYb6P_}WCY{4-?T zRc~+QzE{X?yDdST8XEmLSf>MXtoOqj6i?yUOt%}V$m+b5JmektXt$bRN%nBh;WP}@i8&n;5I9ge>v z9b&W6^(vlarPD`Mxvu1RvD0n_xL%L=`OHS*8Z_~}OecuHW7jkThG{44jCg9NdX_?@ zcNWJ^`#L}L9DkAzsh^HcT+>wKkS?wO694?rgpkihv;p^x=rB%|zqY=FhRc4Hi$ z+(9JIaxK2E)Bx$O=IRfTnmFS17aD+ZPT!rB9>5DP1GOlsJN(6O{jkfV`VeV9B|J+B z%E$qybhiiFa_}^fJn=>PIP(-UvbA6#sz~c9n#ls-xuh2w;Eo5ogi8m3T8w~SSXR~d zB0wPjDBy3#6m7BH>q!7>wkxG-!bOsN43h9&@)Jc8#m0{~?}sw&84ipEX}i6ex}Sqj zXt<@Zdh~e(|IA0n9YexOjG->N^O=@Y28tt9o}PlIGk}`s^u=D8F%7Q4xsnDqS>rtz znmXee9MzF=u7?c3=DdfXKhyI+K+ES3UC$Mr(O;EP-ileAuMvGRR}4pJb*unLvgZy7U3y04IZ9j){z$% zbS`4{b0sE0ues*_1FX!uj6%J>!dme0*uygqD~IUP-Byqq`c{2dSRZLo_K0>ss63G{ z|JnSWv~=rXdGI#wbcyan`9@7a<+69&t9WjEe%;6%1~rW)-4EmSDV5ca=a1Nh9BxbR zB9Gbm8y)%7m8>95St9U~*1*VY7J3;TlPmm_ge3lT>rG^M?zMIyBs*5H;j09~aUNr^ z5|xH7%1AzJEHq;k;PsqYB4m&EGuy|8(EbPL4IgN|#w-rv(t3`e>0)KeEGj}r4i|h4f0)Yo+(E}oaaPy$5B~t|kP*}Y5V=?+n z2?rTWut-9>@cvw!CuIMlQQ#?urWZ+`kuv>J<2Ji)>^f((W_l+7jO)b0ORWs?8z1oC z-Og^9_PyDneM`+%CZQ7P1B1f*jyx|>VnmfCCKd1h1I#m2q>B?<1jpXzF1T?#jdOyb z$h89YxiJ_RsOV$JX56Gx)TTL-u(`eO^xJ12C^0EZGvVQ84NB2ZpO1ITb#v`jF zD^JiwmMAZFj!#CpqwQKE{ipl5e#rAaK+DH+{u8wDhDG!+A)OZg$Tba7p=4F((Q|5 zjSSy)k79Vv^$*DkVJ>R1mZ`|*Hi8K*nl6~1bfh1Fqd>Vk$m8g0<*@!0yMi(H=x(XE zeuGi=3Cyokz_^jfM`(B&9%D(Uz+8gKpb7faVO&?FBCoedV`#38kI&%vS+Adv$M@gn zYF8TWemRxWbfhkhoz15(N~q(>C@MLh7Db+kUZ!74OgwaA@)T(Hn8;4Ts0{g&#}4c) zr^&ggeOsMZT|_vqF8>Wz9g?LnQY1VM9H8b2kO&B5J`c+)%!2&1^1Z~sw>uhAFd|ax z#V#;oa!tahgSjDJa%=VD#{=Hw%1v-U6g*{YiJTe1C&^ zZI_^25Nrr>@kp(AZ)6g-cyL&JC7()fK&-U-54#i*MLs8MB=BOl4jVkRElSjALlZQ~ zm!HENz~p!FjuQ61DHipqe%^{->->@sC#+9-{hLQrdcqhD1-t0FZzEh)-?a3t<|B9i z*osoW7(1;=TFurcfb2vI9PB7XToanGjj0-I@B9g212Cv|Z-BHDct-HbkvW!P6D&DF zdi9@wPjm>?vr6T+@&tG}b8qqp9UtkT=+S6vnME3#UcmGg?Oq9M`AT)y8Hgdohs`+VL*-)5nd;83dBl|vzT!+zo#M0~(? z34_(n+SE=01`U!m%}8Fm6D8tIL%m!2Gzi*l%Qx$1ZXu)jI>9RC=I1P++0UJ^#Tfq z7kf|PsP{2MoR#orfC1LA7Fv2`gI#2ZNBOdD8e+;;EY}Lg%3}dX{C+^*+<%KZhny#m zmC;M0O3KPxK(e?Dlb5xUd+lct+%N{`6aG_~mOVUD_GkgpWITJ2UJRuVphH)Y_(8Bl zBQ=Q6Mc5#x8;{VC!SU>gK;mmD%Q5<_bCc4tvsC&o$uwZ$5?TLrt3o>bh)t0QdgKWD zu;d#1^q9vAol}E&2lvT|+%<`@cwfeX&_uwfy3VbwXGd1l!nf$U@qzG4;17*R_Nt&s zn>XBVvhHPzud!&4&5K`rJJ3qkEt29q@W?kvNVW_|V=Q&a-38jWREAvOT1TT9i*0F} zO=?@ptBL8xera{;qQ!cM=F=$RdELa$Rz|9p?g3DB!1o&;1@M_@l=uY`wQn_3d;_0` zL0PL#9!EsUUZM)6*t<4QFY?T_V$L;KT|Et9m+!<{iPAK+fRl)%H?d?zZU>cws3E30 zg%K6)>L;vfa=t z)}06QcoD*@PGkX3CqVw*C@|5goqGALf~rW_9I>x=g|69U@u2g&ZWc(XUzs}RGQECF zPPyzRIe(b4pVsCr1?t^BjF~HsrXzzR+z$AzR#`phc@o*wMrPB8=_({`mdUPzer}Zr zbsQGYMy4;iY8hC*?E*xm2ekqKf}2MPcW|l4<>&V#gqa-VBf*eNa*sOJq|4-Je9DCk zs@Y*Ov5z$yYtIy*=86~Jk}Ay`-Nm-P{U9vDPUel^9x^kE^~vR1IY!p625i}FmVp{y z_*NJ@a^1s-K6%iPhMwADhNq%srs+-dt35PAZ53_9k$K+3T~5cM%Y`vk>WFVS75+?a z2E}8BR`GA_RK7EIu6u~7IyuRimkFV zPu8-O239A(K5Vj2S}T1{s<9b1q|=)AItbNTGGq{-H6_PYw}RNnHZ+}QjV&D^p;?X9 zM8glHEIu{Ow)!=drQP=uM#uoD#_#k9MxU(6p^5{r$IVMm>RX8+-j&S%66O3^y5_Al zCF_n8Ea5fD>G&q^F*w?sXUz67x%Yp722-oC$M1Y)0N-v@(a+yyDiO2A*x-NLD)|D| zU*EuM?Tdo(NW$%n1PN8obkY|qy{B?=f=}?4fmeNT7yBi38Y@;h7UQ$wksCMSW| zkcT%9|1AiW$EC2pLF94bl(uBv*Ls|mJ^pw zA9<^1v{hylT9SQWqeV8bX(}9iyD}ybr8;8^IBKUet~mS&{gJoR!VdBGkl8fsZfXCu zI|H1*7Ey|;F6L5~*Wj5f`-PR(5_RQrHGCWrAxrE?Uum!>hgg{OJVe?RL`s#|(W|rV*|KOmkPs zyo71}2#Kgg+C@Mu2&)LDj@|z6;+R^|R3A|_IkfxRa(hN|w#C2&<<;;U1TJIlF~&-P zMC4A9E9=6XbnXb>W2Af58H5Dh+Ad3cSqkVR%FXYtBTO#K1rzOqZ)|>tffm?lcuoGN1Ie)Az0x|g_i14sGu@%d2 z&M5Qm3M<|7G1c26i1>GIX&=Ff7#W*pOLAf8AKZhAhyH4lnN=FBon59m!cXO4^YJS8qRE09Z`e+m`TB zxC`PhO%iEA&0q`T&WDNwbrpj~8y9#WlS%D9vfBT4JF_x1 zD{6VC=_WzIXOx_DBdhh%DH7##`BKdAMm|$`(VdGEdwM*^0w|T51ItH*}QlMUuNx?@TjT5ZxT6M z(098oGVKNs-7_YFql!%*AAK6*qkbI6N7lyV|)3Ho#M{pxo+Mx#oX6{c$ zDBSQ5Wr~s{y4{|1s-b@sC;`^_oYvqr*JNak5I-ETeIzUzRXnPjlqQrGiG!J@5kah{ z<0+t6FY}~nMQQvyH@)nPzv&g3F9EZ9>OqEEIvv{WG5KG?x-C1U1&&Y1_&4c? z$)}2vQPp3)j*iWW&sbWs&Rbu-;B=~yW9xsz#Ua^SxF5U1nVT{e^4*VI01S49;Y~r%X1iUiX9n)Mb z@_-`cVwF;DSiil*-v0oNpIdfG^~!d89{jY%PfmzwzGZi6Y5vpJZ5=gSzcpmtLFT47t?@o z3)F39Kn62}uYHIrPy-D0wa=ZMJK;-L6;=A|L`>76pdnCQnN@(5z}xLNey}L)^+9y5 z@v+>6VLGV%S3d8)F0U)80ZXz787$JsFPUWQEwaAd2x7SX@tug|0EOoKP;er@d0o9Z zW7}?XtRg66+*I18a;juD`)QVzx6AZTC@hD^Tov|gA8f_>yXBhNKfLyFb(?iYr_gQ! z#q`FwBTPxZlnui(fgLRyn_nulhPXb{hY%j z>979)fd9t=>3lRK2E;~I#Q%zaRGXcWFl z@)aKhk-LKN0OjurHeNCCH|%)s&G<00)2PUX2ED z*Kj`+C~EIynoV#r>`}T*Q)Tu+iVlX)S~$+8F_Sp2Op{C$>YFG$=pS9IBAnJ%1b^FI z$Ki2fcQzQ?opzm@a$ULfudo0@js7+J+|XJF(h_eVjETP6sbW_h*v3Z_+Z7&MqTemA z)FZ^J4O8{2=ZgmK(glVpq|Ypi>m5Z-gbrlDD3vyoL2k8t5^mk0Fb&L5I`EOD<=-#} z5e4TFyy>X;upMhTB8W+)Lg$m6ZP+3I$mLt6t){sBwI$ln5BR9tD*ZVND?Te?P`P?s z@x5T(6bsaMp~l$j-QIOXbk_l=F*);A_0qTcKX9x&Pfv15839xs$4DBCDhy?+n+8-u zhTsUTVmvCNiGuIF?z1J~HzI$dNyI3#>W7t(BW)tB>*;l)1X^>`rA?EMv~pZi&uBUI zt+K8Zsv+%?-=I~<+OO)dRO8;ZEBX=>E4CzSsHUnDxSYj$7SXp?(7*aNia>W}a_?f_ zimfYI(19-m4p(L(@BU*6v=#R^YiDosA*Im67C6}Qxmv6c?{ftL3ZigedEXyE#n>5l z;I7y5<mhj=uV=LriXy-EvL1Yf&XEa5@Y0!|+VJj(%rnq3Wec(!Rfn7p%4d^7>l`znVuAcE{ zy7{KJqv$%4ZwGLm7W!tC^3n@?fSlzdMZ!#ie?K5)_TK}%NGw9E&$HWwhS!yQlUI48 z><11^O=QI5BpI=6EZeYR0A)cMXq_wAf-TDK2{5~&U$}<)!6>iCFzde;(ncitQ=kBv z^fL~{f8P#HAM{N1h?_KIXpI?LWYUzo`KtM~Lv)`+3?!3Chtze$g=?1!S$ z_&S6@Ue(5fz|gfm$N%R>8`Djdn9=3_Y1jtZ>=-fr|83G~&hqEV%cL{>&JqrCLwen{zzM?9LKj(r!{Y$sQ zuXGvHtd3>CCquc_8Ym@8vVJa{F()Xxe+o5@*-Z3qOLluglJ)lZ&A5;>NfsYK`axGrN>^Cguldl|+LMlRA$fEPcwJJ-0 z_9c{s!lvCSHdSiCbnWJAG_9(LZ&M-gdN;jM&u)y_Go~F%4^4l;sGH5)hb`SBJ!(J8 z`I3|_J|>wii~(~!q06L0u?iAKjoWN1>21EV5}mwNNKp{xrtkQa?c#e8xlg}mlMLTU zo8A6|ON(lNedHC;6oH7)HMI=E)f(?mHwNBGspV+LFL(8Rn0ToX#pItA-0+nqGJcla_?ZSB5qMULb)8>Ju_W(EK03b z-heU+Py&YTyAX-+Lg4Y7vJ8vWVM<2}{Z=!}vGT^uDVYtc4l|Hnmubmm-#hKrYZipl zz{0AR?L3pVC$Yp4^FdZ7<9bF1wF{iEbRl~Ava7W9qKrs5%_=LXz?O|9RMx)G!B~7( zq}KSk-{E*MG#pBO^l7uBc1v^DH$trj)P7kuLBj`*%`YeY;ZWQsA3H)nQdTRXTq@36 ziFW{1_QFmX(;%eUbGoMc8$^s-TmkNl9#b7tJ=^~9>h}1{-`jc;B?&Rp^HDpZUW4R; z*z`4FC1Ldv=<1dG`68{)4Nw-7{r$2bdCgbhIh6XjPp<ypEad@idE za{1!Y&cl6mGDB8IDp#+cj}vn!iwa@IcApm3_#gPLj8;5aA-<^w zco|Z)7vxu=Mx*gseBO2%Hb{8i{i)4=&KcqyRcl$3>L-?#2!?isC$wevt*%hKW79=X zRs2CUpysIES(+a$qP{n!x3t5JSOSCMez-uih&m%-BIyhOnx=?J>xLg9GvWm%a$gE) z;RQU~HV6~`0-uBV9R~CjY6cMre;e=%^bw9S_F}s^=K2~oX@OY?vRw;R8oEnpedwX9 z`+~$+HN#-+DN&$SyR>|oNN{BJ*M;!-?sCH~VHf#9GA}-4l-AU2zoy~~-FI{ehLTRD zue!GJJNoe8;~kn-j>G2wAp+X_hTny@lV$O85gGky!LQUv3O%7jYyNql6a+hu{xMUVjQy@icQ!1yClG6)mfC4o2c zRmhW|^pvgk-QB-;zF5jhBs#EwE&#fVq)27Z74CKX-TddF8qztu#1)(j4^(O+F0*gK zK{Zzk%Qi;=SK2YnF6887GK=m{z5|#3d?VL_n_QnFAEdD5dN6(F4!%7D%?WhCGKA88 zW66hNiavH$n$-RWctB}CV8LYXeS+7Kml`)MzPOX=0qK4G!UAN`*T#Vp>{Zgy2vjQG zTn{gq39R;s};cQ*Q&(+=zm#M%Y&#S0**5m zJ}gHN;lXQfZ{Nf2x(7_UalB81gK_t(9Zmwz@$jy{S~y;V@vIr3JKWj>WUcJ!Tlq^# zz@XwHT>hTW{P}C`DDa0GfOuG11rBdQ@L5%rU$q={2UHy(RZVO=Emqj;Kqh2*j3;kO zPCr|bEDOo(bgo07-y^K*=ys*^N+jtO`BQk@3H$?!xd{XtJA>~d%WjRv=VYG7rMw7= zq>1M*ECpriyfrB|rsowgieG5&*-*fV*ig%s_uO}Ae)f){r(ByveU+e7x92B+q2S7_ zt?Z-A*np|6fR|%}n-hAICKe2^lFx5b&dymqmj>okr9>yECwXFAwy0N{@}9EbFQ7vrp(2;eygJG zJbm0ajQCXu2HdXWnk)P{j!SDvs6u>}{0%?qgy=&7sO?Fv($vZLEnV5!mB=pJZZBE3 zj}E$jtSRt0^MR!s6?!&~QnDn>9FQut@?;yHTxYCBj?o+c?eVB1dkx8Fo88L={G}L9ObKUZc_Gjg`ej@P7c|-MqE@dj<3H zKG0vyrUw!Z>Zq8tm+1x|du<1)b;Z-L?GGfVlww;3Zy*)sNfR2rC5M4n1p-u2sr68ObX8^WixnL7yYmUxZg#tc>cM?@Ry3d| zCa=K^V#qQr@1uMCO9o3B5V|$~P{PqpIjBE)U^*@EZarGIbe=w4Sn&-+ai9-43eX*3 zo4$k(H9Gad=-NpQENxv?6OVLTnn#rPJ;^Sx!P3XV136Z!-wlS(B19~YOrv4qD3Kj_ z{_M)r>&O5Dh*I7F=+7l=bm?uB72@b`R(ly(rOX&gdqCgns4N;KcJRjN@v=Vz6R%~O z$mQ0y2tpu#lPnKD@*eNum}yKDRh*JgS9+7l*xr;=W3S7hARrPmw!`Jd>kk$Nvd{bw z7BwB0DF<-)oL@Pw^O{N!+gCbpa0k5G96+FzgRf0`{<8ikruz}_l7W;Lc$t3F#F!=M zNL}8wxlqE%+tDxoHoL+b6U@vYef@sj()BZJjIMn8fz|69US<>W<@@Ne(##FsX1b5P z_Le%3P^2T~(tn(d@3o+#$3$?YfcCa{c^sx){=QE>M(JjPryKSlmscdYxxAy5-A;F( zY0ifQ#y3EX}d+(DohyqFu}>7y(}>aI?VCLWD~u5-#INy9K(=;0!8Y=_vweKs5|p}G zw`x-`k2O^+l;S0~8_Xk zKL9|uzHT8K^aWG@{I$K`l7eZHMUgh2h)Aprz?e~$_aZhuTiPz-+;wS{h2+N~itoUNJ z{4!39rGaWQKu%@*uPBurqEn<8a;@h_+a;EDdd?9n04T6Jqw5z)6j=XP2IMqK185T8 z_+pvW3^*xLk>RiG>_YE_*HPs3^ilAK5#W6h-do%&e{l4%{uHY;`$*G~=+nCM7T__p zIVXxnG=qTdv|zCCF&^sr*?gjVMrM`bMpvCgV3sTwsT3~8GLJ{XR&432&pm)#3b=c6 zJmJINo9jsP!Yuv+Sf5cg7Ieax_NQ#QE56RHv*JHkz)ax`25NG8h~HYH1cQ^cwQ^FO z0VG_}BIN*dZZ2#7*+VY0KZKN^OZX2P;jjjJ(5?w0TqSU^;$}-}<)-$e9hQOUjsZ!H zrD-) zJ>e+sa)IOg*ljfV;M~OrBC-yAVeuR(s z=}hYQwpm6)HT~OD^6b8rq*g@~;j+tRyhf=(d3L9`R6jM-)9E+55ek~u zl81WemcJI>fsn@=r*sG8#+AiSHvnbty67?9yHd;FaHftUOPe{ljU^_S8ADz=TiF;q znvZBNAyKnESCM0q--ll=88zUrT?3ubgGLzh|HK+}JAQF28GPXmjLUttYNz=96%&J6M~x zh8x*?heo@9+IdD$2=CM|ZYyR9u#C52`4FT^K2Q|R|5{ZD3c*swT?74^BWzX$3`(y!MCa!lqtX~=M?iosaU5umnk>~ z_+5#)jP!&c4w2k4wJe$cv}PHumL})PYaFU$yrs4owuAT1OYHuLvHM`;tSb`LiAy$a zNgflZfNE;nwv{o2Lk#&fIX9npa4dF5`Re%&|LKf^m(K9(Avzk*#iuvJ?BBw(Paj_U zpj%MJ*D#?5qn?sPS&9X0Vbdw+cZ(*S&OY+-K#89g-Ig}Tm>7R-HP)wi;+L3grwg4UH~A~l~}GS zQ=67$4eBGH{n<4I$O~rvTfa()4_7qZxoRlfeDS#xf2_d#|8OMxzdi zT{SH%g_|dT%L=rt_URfP{F`J3fL;z`n9Gl#81lv&;oJfAp3PmCEr7(95rY!;r;E!s zp2$~e-&l^@2p4St3`)Fd{x;ti0HcsZO>ik5VI@QlOsh8K;;~&8*nL|#Qkic(--~4z zBghgkgQTu#ii}33L?C^7KvLPv5D|e$clVGxdEA3MgvuO5OY_jXbqvS0jgeObxNzV8 z`HRobFQ*Vjp_*9zFR@g*(dCS@BEg|J!de4TngG`I1uV-9l7*h=s{42n$UE)+ z@ol-y3?Q7$bf&uppNy5bT z)w}yIg~LGn984x(NJ@c%A6DNb-kniNuy;`X`HSNT`8rS^YPpdCdV&!K(`kNIB=j}U zVpSc%OVyvjU8$<^Y)i7<*48zd8b6fHpF?mh)QcdI&ysahHD|roYUs_3n7)n?^_9YTE1Z_Q+t=Q!Qg(`;Ib zzrZs@{crNmlR)!Oz03OHRlu-``}ZuDZyO%>wZrNXwzd_UO01A{%h*Nsp=seBf=Oaq z{Qcm28N7EpZalm+UAAl)doi`?NC&0;=mh22sTmkf8jGEdLYl%prrILH2&*#{3@@pV z?HRN;FT#%c(ZYK) z69*$`W}qIo#_`OS(tWAyyTH&ZIBiCOA-^Mu`e{2!vMTdMW2}P~{a=&U$Y7g9T_O>J4VfD>b2jV44&Xy#oZ0VKYPx(}9 z^lrT5A7&4uhqNtUrFh|zX=xQ3UrV6N(N)TSVn6hJW6$YSz9iiW$9n>4tH+AlN*+Jx zyjNGhwz@{%#<}Rv<~$i*+*X|5$gBFPz}3gqUnbu$T<-`Ludq^#)x7o%E$;s2#DUAR+_%0X*VJzUXpUYN$oBRxDVky&+o#0eqCHa98Glv78@=zdlf~!sxqcD|4@BhbWPrcIEsctyFuE<&{VNqPt&niI420Dd z+>uG+md98->iK}7o*~Y5`7#tM7^<;@;NkR0ZB}1U^x^YZQf}fB3Ks8UOiH;>_eo>1(L#x!6(M_-!!=tf&%J5g9QYmlZb+Q zqltZ0wf)0MP?3OmxBxVfRV!o4qFFIN!SqR%0HXDAI{RpC%*lS$qDcoF<`Re+vtM2ViTcRvjnn${Cia zcNXT3U(G@^mCK`LQjHXfN?T*(pl$>Guv60ngyO&~kT&uSKrn>~N^|!bKY61AwC_#= zG^d+BB{$=VHzC9n9U1rbXerRw6C@&Yh#V8T;KTX%5V+|DHM7^zXnG|Jd7dJ#(f1vF zT7cpUtqS=4Jc%BF;G+MF0ecO1XcTPkD{yaee+R^SvO;(8^Gw`*CeiTe$6ySYpn@LIJM-e$&9@nmPcFW`McwE9JXUm{Y3NN7LS`r_f)^@-rOh2D} z$h0Dy`yWMT;n&pv#o>((0qHL(DIF4{Q-Lvhbc2+1gGh~%l5S}jF}h2|iF9{&H%KGl zZ@>TGzP5Ysxu0{+`*{*=bQVvOhco2;>|bv!1sULL$PWusEPcSW#M|j0{W&_1ZYY*E z^G?58#m|~8Nw-rEsawObJFOJ+H`9&7f0-qy73pawQ487?FFu*zn3`i$0X6!xclPOi zufq%wKhEwAIN{0Ifi{vXXknCu{@|o{V5o{QQ}bujYs5G3ruFkRD+*N zet-Jo&c4(|mg$@Z@Z-|$%L9CS6Bt9*dhur<&1q=9k-wgb=X2S}kXTW+SV`%uJKY1s zUU5r{2A;psTt%uu_<;B4mSKF|y5b>+b4<)K0->p`7^KPNg^1XA1 z8`&6aB~*gR$6||xcl>@R$`4wyDk)>phNun@AZuFsf!B^V=gkI*rsHctZ#8`3wpy>M z?lf@SVG`v5E#YW$#e^@gkd<~{pr4{vYn>PQLbLc{ytdw^DV2@IF*4MXiszg*e^bhekBv{upt!sl zYLARmI0e(32L3|2s*Jjmkb^M1MYo(KhXiPxPDu)6HR%+35<1b_b7MODxMwn7726JP zkoVH_h-k)9^*#zxX?7?UH=j9%?ZK|YkS?QMqjWakzbU|X?%XW-BRMWNAaOP=X+*dX zWIIM&{KI2BT2WxZkCH|^i$g`TDrTOkOGR^!cWKbUX_vuilzp+fj)&Cwm<;wQ8xwOR z*qL5=h$>zGn6}Yu=@xp(ts^TF3YP;Z}IN4$IL5+f1dDWIbsn7|A*&&lW|TG(lg5Whaz9M zb~q%}nnTwo%QjBfV>J(T)cw5b*%iym(77dN?LG!0>aZ{WH~Z&iw>x@qooI!~+YT%k|uZ*0RR(4J@`sFbGv-mO%^ zf_MD$QjC06$~q)QgaJSR^X5AqKZ#Abcy=q4$nnIeVcENjQSlle+g5``W{b$T7&tjF z#HMERCAr+R`AZK`?S=?`u50}4LNy!l&JR|`tPt4TG3b@7<6R9Y%F@!o-LCw!2b z=WHabH5)P1ZgSwzvO#RT#(yEb*<2D( z1;^*%phUr#G{02hSHbTOE}mYXp}>ZaM69G;@h^a?f<@lcC9Q+Nv7Hx_WqyWl4v$UKn6%R!8Gp@@gi?pNW zaSP{|%?D7l?;REtpg}0dUO<=db_fs%>|S74Lg~USzXK>GJoaFp-u`W&Xw4`ES~;-9l8%kuVOC4P z6J*8!wclBSv&Vq-WdxHhsAoyMX(z>^02|ewqx(pcP+f;(@-fVDX$a-QT=Ktj9lXQ3 z?x&9HzdOcfq~og(e_-&fKdUY4b`y8qji?$HCIVMwYpuzJ7WKUbK+)*9H&uj zIqKrXA^w|%j-df4Qo7TON)jE4Yy(|v?tf+pc85g_0ih}grdt%z9ki{l6UWn(tIjYmi|2ZQqMje-sX14Z2x2TAmARZ|5xay2-&dY4 z-AB-(3pp?eVx%ez(ef&&?GW2lT++Ikp>P^+y0B+{!-A^$c+LyqQa!xfsCL9>Ub0Y* zb7qA&4pXO>sXy5Btzgvwawqq{9$S_YFRBRn{*X`Nz3q9QH#jD5mTuy+im;%?^egjO z93fX8o%Zm>X;VmD`}q$LgAjS$Dzs)-3NF!GizlbcQj^{dr?+?K=|~ORO&J0@iz?6iWG8!kQ=j=5n8kG;rVP;q&KXii zJ*=!Y7W@tMMN;qb_DB_oMrb6+I;gpF?liHtEmn|6bNM`Bdy&-n99E{x0gF;@Ec6+* ztfmeZ{uV`s;^`de^iCh>UYqdT0H%UMR}IiQGSKe)7k0{LjP{<0nMy2D2N9|sq@&pv z8oz&ft>uSMETIIE*6g%wo0yy?czOXz#2?}#IC);zOF6h|)ieM6Sa#-YgC5L{Vctvl zdnLv5R4pmJ@v(x=N8p-6d+(8RyW@Z*&UN0QUdAm>!s7_Gq2VM`ck``Rd78WV*D7=0 zU;uy2_}ej4jAUQvw82z4{X1jFwE#@7E$n%YY{3lt@_XjbkE-R=!tC5Kplad1*+U;1 za`t_6f9CYL#XFpz0#Bd)s?J*(+(!9`UrQ(!iWR!{26io%_>T`~9>t1Fn|$FXT!y%=2W}Jv1UJ2UxwL6!8};ZyGX-zZNlx+W=F)>- zu|tx6)+7Cg;}puypCdCirmTvznHWxkeMBGuEUdCl3QtJrMtq80HF?q2F?~7)0H-4FtTJmSdzc3 zkJI|8`5;wx)OV1*`x>L8cjm9OrkmbDS4|uP^=F!p;bb@Zpp6@g<7U(mlxtaI@IJbr zvY&nE9xE2=qtMdsAx8lEgx>!821Ra&x{K}}tB(!U7<*qm&m6TJP}$HgKq`=s!StPk zASN}Pg|&B5?NN>eV0Bce0B3?CufWvA^SihII3ORd8oO)_Bb*@)r=l=uK416 zZd~-FS{15=b?rG{+njI7I}-qkeK#m6Fp`Cb@j5(szWsCQ^8BB;RtRe!q^A`dnmo^d zdTpmPUGp`r>JO%g>)9S(=Oq0;fUrAMrhma}5)t;~DLr9Nn&B{H9s-&^Ncngk&xvPd zv@zyh`Nqt~IBoyb$Xs|fk4)A{uF1p9!HlF*5_Q`xYAtUpoyw(QuPYiH>EL+f9n||g zk7n!nNWG=_+BtOCP>|9Ytt>r-1G7jY+%6pe#NwkWA?a&^XjTw5AYSL)OC9O+Bbc>!L$X&m z+>fB{m4U>GM?me}7a$qg-K548z*8NNnrF2HuqS3zUWOCYVexaLIXlMtN}glZ(`zn! zJh!2JYydNutT~}y*~Q$nqxLXPB5~{5Q3~ZY-rWPKfR1&tl9f;&iYufoUCUhi?E%ba zIUJ^5{8UFx&O%aIp5h4uA1A%{rNg?zYTaITsm+%}f4?1D(VdVliH2Pgi%%SY=FW09 ze!T|F_V{!NLNccbv4XIkGXbCAUEcO066+Y-c7UVQhEW8SfXrDbl2 zf907GB!@^b*0(1~A$0;n{=9Mm&T=Q{f1g&cpUeE_)!#L{{Y`u4CkZ*lxc5}ST@g?wuj#%Uwz7)g64|P zZq+!tI~*b84|Si^0lBNcsm}OCJ5ukDiYLyh2M7hysbmjzjs_u0oq#Y-AHUW?oYv@hm*^jRW;d1F42Evnr#q+_A&SxZydR8=jqY(I}k$~ol2%V#{_eGM}G z0>9SHF&<0WmlegXn)vDwNSF0OraN!&k=LCa&rj?9x2#lg+(YEf~XfHNh38WV? zsWkX(mNR;GP+{e!%o_P1&-a|hY0cwXmh6*dLfIsR^*>-ptE|37(qGSG2iZN(B3c{^ zD|e>>3cMMrIvKY89NX#RirYlwQ9ylBJiA}!O?E9H?G1C%vOne#uHZ<5qh?L*9|P%$ zAl9%B7ZRYz9*l5(ZVA8pl%p|+b(cGD*35-irg1AZ`IQqa?*#J9YMxYg0OJ@6{tzEL zI)j&k(=Ohu@@C4rKY$F;p!OZK%bi<2jgko4RxjDb2n}a{wblsTQT|P=7NFz-&CrCG z7w5Bv45Q?f{rN7BOB!P)UgRIIO0@(6iUkIi#Urt!^1jg-)BXC7@a!p@Ho!k3fF5p> zlf=XksSaaPaDf1gM>_EGoP!TM4wY#qi->r_%2G9&p!tSFb(FdEVQJ&TsW7tL$3Y0} zXKZ)ad$Cio#SIP{!X-&^PRmv1AK;P+oA9Y5R*;ENXlgS2@}c9GWZxSY!t|#o&-|+x zLxE`J5x)%9^J`sPt+aR5Z&-Oa;xG1bj1>BO-AnWzV%AVh1d{d}UmtMfLQ%x8utj4| z>%+8TO% z*~A?9gQiUTOR_5y`VIGw?Kd@H_B0pr-9Ga+8=>U~GO)tfoxSt^Ni_rT7H_1TW}WNR z2fl`_=<81s3tuyS4R_C&;=CAA{R%bnnt%H922aIy&;L+;$wG{@FSvfHN#`%lunysi zKa7Xj(eAhU$|WWHqYI$%zoZ*@uMhF%Q`PSCLfkuhd4cY4!@X%o-i`qfsll-FSEUWa10&5I^7RB#oD)15Z5Z#4%rP@mvk0wq zUmYL-86?|4^%d)pHY6+S=(#6D04vP8y4dgwn)r|C)SrBD0T=gc083m-z~bi8Ivzto znWqy_)yj=G$k^hQ74Hsn5|WtT*|{Gn&HtnJ$KQ3zNYEiFo;}owo;hWCg|x6HexHo< zA5ld*Nj9eO9&FO)a;?k+jj|*=_iTKfCNGoMm(2-XB}Lc?R}>>A+1YXa3swrtMLW_u z3)?fu)D`BM#cJ}bGSR;kX{kYz1G@l&6!Yl57!zS$NU&>@3B@f`JehOrS z7)4)T5S1g1)M;(LR@WI(Pn-3( z)WrChHguj}O(Y&B2WM=VPRCxgnW1I4%QU$X7V6A?$ia!t=N#cqoxY1TPtw<9n$-*s zO-~LKUIJqNT)b`aR#X2K*$p-k8hZVgqaBh${bf?iA4V~$vgCo$p}u^MxuErBtLJW1 z^y`lP8+}@{Q;k569CxJ({}B}}>G!AvVP^)8^gx zJtnO5ClC@$%YVH0JBVUpP%_#@R+8<+Rzu;H&URLtuE#%TI4h9}*{Y zn~A+brnLTeBi;8}*X(&G=<)=(uB2(V4epC$b*a>33vDVSUh9n0E^WT1i1g|C2S`5D zx&U{;{OY%Y7qu7X8cSVDY+S}CKAL}R`=M*&7?gqeo6%4g@4ThERa3=2P$}g@J2gyi z+k|7pxGCTMZ?6wxr;}X@VjHIy!}29H4Niwpvv7C~kWinF#7wU1`xJ?tY%u%-WZth!-rI2xWT8%)ik9U+ z1az8moh7XN(Z|M@=hwwA=T+i$1{?Ay*Y{1r3xFkW5k}q~&qC;XZYM4_ zg>Flroxci-E?N;LLn@8BB8IxL_PBMai6VfA65HkU2y>uuTX9#-tK9)j4?X+g&}bE# z$wy_U?3OJfD6}Bt(IoDkCSMT7R^wx{p8hH9*QH==7D*`wrw@-}#%tLm`a%uUX<9I} zYid_JP`NcSt&Z|m@F_8XW~-Wp8?up4N~z`(zr_bG>93$JCf*7M!p5V)9&Z#1n`V)s#%G0Psn9ybt&WeEH%Kt~>VG$WTaEF` z1K!bM!NLfs%_0Tuq+Q0h{x$etOC6x zL`ey=vzl34B6U@d5-X^DtcE#h{^WHYBdEQJc4c=iXkHDYb4;z3aktH#G4nktMn61v zM$Q4`D8hT~yl#Ptc)p2+_13|BMe#TEd+ETRpzb(APFMg2gJH`gxAFxFg4H(t)vqME zK?hQ!!CyQF5dVu8nl3M&pbB`L1>muey#z7LuVb!(u{P%@pMp)$SxV4wr~^XiKLQt6 zN|X-+{{gtsRYx!x07Zni7f8^dvhqy5mPV7GVFH{HV@MQ{HfuwV0@u<0Yyl*T z;iCJ~q95BqacEv?m;hgh@Pc0-(9ohk`bx^*uw5f$@wFpw&24XHnmxs^KlPE6*wGluPfio3rDB)r_Osl@V1=!(KZPcn!3V8pvg(Vx6 zjzyK7e6u!ODoL!tcB%BeKPjS$L#*~^#1I=!AFpr}t5JY=r{!U2Jl_OE#eA#Nw4Y?9 z_*^i&Jt*pyZ>c?`Nj>wVqeuX3gR+xnmL-&;iDY*>9du*UWOSn@8-nkeNJ|9sIc=){ z0j}o31R(5W5`MyoO&tei2XcCr!Kyv(^kV)6_dc1)@X+E5j4$Y~9oAVDsa%3dJ=LKb zqT5hqK_Pkf4BjM-jVH<*DPfLfdyh&MPN$mpI~?_| zdivMdV!p>z2gPiE4}lch7)@0p)P|yQ1=yD3gQ-|V*Y)pH$^vhYZrCk$md_l2^!fWo zmQgzeFS(jNr#6RZRZ8Az9(h+G^!@>uE$}b((8C@Lw#;8Vh}q5?>WBGZ(SNM!^J?18 zsuf)ZrS+4gYw-InsIy;l?34PuJxMbxY#6ZOp1unz#9Rl9rbGuXijPq$K;#6N)Q+qk#kAvQCw;gqt^{vOH~ z;5DE@<1MM@aK-kQ;$Pq)1yeAz!mp-=thr%)9>IJ^8r+c@TOP||?nc(vTp}2A6;E!< zsi&wje;?OR*zz?N@3bN<+S<^Dmq3xlb^vTN37IXy8h1q)5V1eXJ_w8cT9D4=Yto>y zC$v*%PhY7LRI^X(x6Oij_D;e@tBt;;R#RZ)uU4IUg~7@V{dx2mZc^da!-ELJPL|vk3-M_ub7-Re#Ws3fw$Enw&Sx+B~1}@ z)hh+gKTR+(YTad`Oyq`}9ZWz!%l*Ve)WTt;LC^i$&{;5j!?`vEMq;ybFH*h@re+c&KGMuxAAvkCD*3+Ihy z=T2{xm?>{Vk>qrv)eunqqp2$VPiK(x2Bx0Q_u5`cvL|yERmh-LrkOHPyArep&CGzy zN9@(dBiFAfZu^uArUn(ZysVQRKU75RUWE004VV^FsFpHFqmRoh=IW}@wc)-ym?V)8 z6Mmfx2d(4yHNXBFwwkB7z9Y6u{rGY?>l^1TxcqGz?62n01PfQ7XO<(BB7!9N)M}+< z^)EmRj2F8|EpYKd-#);huqHCYp`4>^_pvQWAljg1;I3T3h?pf<0#82vMj50`C}LN` zbCYy@gr-3*A@;{_`FE0iV~jp@NEluE>yV?!9i&M()DYvaE_uqKBd!MXoPspsN1eZz z&q8T)s{i|&4+Gq`t=fftDSSMGR)>1CMzJD*HUE8Rpd!F3?x)RrPeqe2eb&-%#Ij07 zRV#cA@4Y0t-cE7C zEG*nRW!U-aDHhAQdl%r;|DjRY!=xno9I80-Xo(uyx2#OV+fv4t0)X2uZo4{pdW9f4 zx^Jssu6Q~+&Ac)QYf~a-lnd_HEyV3*y2rW=Ugl;+(^aXnlyx};OD>^tmNIt!S082| zuD+wrAX#u|8EX{klS!y=jq_4-S9!^s7K6jMYMPVxD3JIcU=Ym(Ds{?t21_Vabnii^ zD4QD-!|0R9IiL|&uGdKZ;RFl$NcB7eKvq4{3|YE4`xMlIBph@ZWVutTwL;ArS$}?a zaUBEvVqpXv*6sXMMHf%SF$;lvH2-}-t*=BJE5E)yf<2az!s$?^0i4-yp<-;7XD~;9 zXwO+|IxrrRX5}nFSXK&9^moA~Q>fA~tvz+ax9@i=r=bH~?7_s#?u6nV&#}%^A*5E8 zPUuTqoIuc8?a?0WWBiX3f1&^&hCbmU7#*NMHBq$C8B7Vj9sd z`IGjq)c|SE62U+ExY1R{vd=6pk-}|H(d}z%fH>Fkc~h3vr7u_+W^9g$VrTaj#G=>H z)SvT*03iz$EnE7MXl{3P;t4lMN0SB~Zv*o@^z~$~Wtto`DiW2*E;)&H>Q$}IL|>$U znju8}FUrrUs2-=!NkiX;^SP1Q+t$M{yg$%J)`Xzbt^lbf)Je0$oupc3OZdiCv0>Xc zX|=mFoYGE1Lw%EhQ9n2AOE2yA55T0eT^7DT zC=6-R_1^umMc3Y-^Yf{fV?DEq=9KKLn{V2J(V>sjvyc2zf~3*MVz_;`xq;flxH3>H znIO~{8#yV7GR;fYQ7T26NT!xIeTBDv3l}Odf#{I`1DqNzK1X+=SLX25?)*`Vr2e|B zOo)N8K%qNUTZ{4-`8MsoOUOg5IAZi41V(Dg$$=*WiSoysuv4U`^X;Y`(k-%#BFV|- zS2oywTdzL;0zF~@j2ki*q`uyrh$qe)YFx`Kjl954GbO2 zFv0%F{@wlf=lmd#Acs%j;H&$sZd+K)jZ@l7rhH5bgGUVAz;hxt%CYyTi{D~(CoD$i zmD`fB&zUe8svUIPEYjQ|(8UF}6zGg&)U9!`Svi`#eux~7T%xO)%=&I!LuG^5hbyv~ zAl`n9#e_fI>S0SU2c9a|(VkP>vVn`H7OGX>GY@MriN;?*{sDT*hqcaGrEPy}?qWxx z#@>9B8+#_m6+M+Vzj+cnkJ-7p(#Trk?ipE}UBAo6-{B-QVdL6Ut&*Ee7mH}(G2Gg8 zUbC=v*Fuc8OOj!}I~K~cQSN%}H&#KDqg0jA*X;dbA^Vf0>XCFn9-*zc^g%dx?00#x z!qQ(1i9G%}m~XbQ7h->ZkH%}v6K(knS67j`+%^$9dRomTC?NLEPVq$HWix>4{`@!Z zHb&ng=1@U@?h3NqA^zdPaEoTqowO<;<$8G+kynHK6zPbCo#X0m_V#o-@mvCT#Fwem z&SP@czE@`ey}8a*fxLjukC-_c$CdJ<3;zI&vrI^f-fTq^ykhfTYrd=>v}i+EF(vNL zhJdmX;PXxR3RX%ghnSb|)$aHdp(yNa{rCpKZ(n~huHHnA6;=$wk9h9gH6xca0~6L0 z4a+;f1Cfsg_D!f@i0IY=YLY)faD3AulH&CC*5x+go;ezxA&vT33G!+C|!I5WC)8bc;n?D>}N~`|> z?8r|qj#m~;XY=6he=#`;q2+cYOMZ*l)co=dHy`39+Fg{C0h|(tQ0w%T4zua(0}jSH zRYdlsK1R6W;bny|9xdua@p!k}N%DzRGKK{8JJ2)IP^jHt7;@saVY%mn_NY%d%QTN~ z`Pg=;uk}b%4rzrd>%OL8M`=!Gw_U%bucN1#K>nR^2mdFjsa*cT3?f5%iCbKTT# zXs_h9O+oy$O7-@eghg=GUp*O4zr$}J+)?kEj*BMl-2=+FwZ>&tvNg>ZX}5bu<&aiZ zRba|z33sFsRyDckO!c#X{sxXe*jd42EyQio+GZ3t(@kx@k0?6E-SfPN|C_Jp_M%5l z_Eiw~1#W6TZP+h}1``|wkfePvw2=N{`8V==f6k7I4c%46yVP59hy$PJYF&}C>_5P= zvT^XEdM1$jo91vkXB8q9p}kKIM_bCHV^uzk)GRFNezl{?@GOe!Eo}0mJC(n?&E4bF zO}@F|KdrX{CNxL!oz7x&a-e7Jao~;VCXdm7zPxsIC#JFoYI150-dAzej5NNL;MOlM zcUq^v5yQwv@9~lh;vL1D=PwLJKsH7(QouS+^m{NKoh(vs;c9N9TD2dHkKI-2gkl~m zCmmM;%UuKSUjT+nU6Q$D=`(=?Josd=!q$9MKvh4Cdo2((lWRXAtM*~IM4F7ZNj2*IWfCcE zfDJO>oP?%%AYaNmB?}Yv0o2Gljg5x@%5>jYxKLRCVuxMKdoQH3c1v?KHUec=4zz|F ztW(bx6{FCdjv169y63plMIviK{_Di$6?+-~@6%>%Fc`A@%{_l{CR&+|?jpYhi0qU& zRlY_B@rt6bXqYcb-nsCqqZ>yv;wvAV<)2WB6HFL%a}Z+dnFy~RGV(6h5C0{ zjmz(I!4|&B)&pKb-Clle8}r^v9-q)*QJ1$=AC@KKPXxm?|I07|lo-Z%S-e#mCDRQB zUigh`XoiddHRfwn!_!}r@;Hi;(52y!q)Rm*2Rq**{oqP5LnfT4+Y z?Npn~RCT0rS-)~n8LPB&m)va9vz<^GN{z!8y`atI`}5v0)k;`P9ff6f9B^^^{cM{l zb8{R>i^A?P>LSM;t%tp-x2_Fm!h2l5m(LyvHob#4?p|dOrfa!?)uOjklbvC4o=RjN zeY?!AYsk8yySYyzf-Z&h86BdDgS-|!i+cM~qvezwOW?lMjrRJ04%X0k7vRR5JuX+gSO;-pbmcO{CS zjg&n9(lY&lSJ~Mq@nzBg)^F|5Y*Im~w z6p)S`tn4FgTGpn`S^9}}&-J17Y;;z)qYQ{VUH$HO!quazYl^&l`@%H{iY zamoyT1+GvrV_vu4+|Yv*(KLg=7DshPS)4M~lAZO=XMx%!7Xdc0Kqh1dx$XIaL^FN9deM(2{Yf5`j4_faEBb%q#e zFI~`JAWkHawfczW9Z%|kb7>sm*ZcVNHJjYi%0qU!eW189?d>H}M_pigqgB{#$6jYa z7~35B`PLgl6l=LE5ha{d2M$G!TkBZ&Bc!=YK*v!P&{L?<$6Sous?ud}YdTt|`%vUr ze?E0;`l?H57LbG+`)OJvMkfQOHCFziB!Q0}t^2&SVOX{2ZG=X}RC0Q@mvs2z%Hl{& zDBq!U@gXI8Vy!-3TelcxuiWnlx^_6}QQPb|eFGVWqcHsaWts?7wo z1=4->y(zieCpmBI+yBB`Fl`hV>zM|e=ahW*-+qOJ3JtDQ9Z>Cl&+A$HVE*Fr)V2i5 zDkcx#&3gN7G)E*ctmKU@>xSR?lvn(wGAAy8b%hlj=yE}{Fqip_O-3X-=fAQ2u>hfA z-UunJ&$Asi&dhEjkeq!E7kMQi@x)DnD-H<@?p{Oqj^X9|fg!tp0Itj5D$`LvU%sQ_ zMNOdWro9D<{6GiH{+N}g>#Y4~#Y{EBElXL+cNv(IO% zx?v`Tp*#_%)p$2iqB|C_z)q-7rDDdZjpl4FIQM<{x0!3G_Cy;(Nj$|4WRN zRfJZaFrG=qx@Z6wt_XFc0-@4)UM3bo7~Br$LDXl*8Z`GiePnUIO%@9~`0^yF`WX#*kwqwPL?TE}|LD6R)_at;8fsWrh$h^<40 z0O;BtgY3A3G|T9%=>T;V%cb&My?PL3YYi}NJ(Znv{T|rzY(V%_Xd}mxsL+1D4k{V1 zKIJnQ2((7@-v8gwL4`snoc25}KTuz<6Ic#wz?<~+bx77wS&Paa4a zftg4q=L47~RIZ+*p0=(Y$>A?9lE5qr-o7>jEaoj{B?%OZ<47Y&mSyEckQP-e+@0$Nw-nGEtARg*$177s$`ewDv^=E_Nw!kmFc z2>MgaMMDisyGjPLh#Nm%-KmlF#XUPqY243v9`ci4ikx3Yw%aJ2vf5rNr-ylKHQYpd z=qUa*4chn|5I3tMlL34=x)t#KdnCeyX~-*&45`U3uvtD((XYWrdkv>}dduOsyw3cU z*DCR<)n*`rNhdO6RkD?q(>PY9yP16jaxEf?udFmQt=g&>nJZe$>-{=`wdN-4Z9MdA zuDis-2S`f-^#c_?&4s*PbsafTf)xDddge`frUDzscE1aU&R-1tB3gN+y9%tsz{{Ci z-o`2L`8wxt)%YC-T!d58h{RT5k(xAewQ~j;H6xAHxkA2~430 z!bCE6NW8t{&!?X-NoalK{C$N@6}kc*N6`p}189b5iQqboUU)*(3B)XQEmr-;@2__I z>k0BVv@jyrT^-?0I$)1lF&`VNs78nT^b+-a?Mj}mcA^fYGu(Y0_&h*545;rAz#9E4 z>hf}lJprG;A;VzkrI8#*%wdRpSssK7-G~N6(J?E=u+G@on?pGo*|hrUL?hp^xoYA! zJ%&wWqY(S#tP1(^ddsp)W*SH%_FV>jnjI``#|Eeo6@&aI2*+1c}es+!B*iqiHd}&$DbG$T9kyT)9rNjRK`6 zJ#+|igDnFWNzYX&NlKJc_u?G2o|zKmpku-W?Z!a%-9ZWA@Xo`N0#N1&+<65fJcCRr zlM_YrB~*0BXBE*w=yVk|*?!|d4m_(t2qJ*bi9enQf&Tz3Hsuq=eXz&m$t7>g#JxW) zg~hdhl{R3`TiiKuDyD?>nQNb;wR9}S$`>Ed&`^H%ro@0WSiPU%7eh+E-a+1qLaP20 z8t0an{@Egh$o96$0+}e%IY61vP4R%A4{htV_))!aK-0zNYOQI^U%DM+^ASY6ihV%6 z##Y*L-KzPnI7INxgF2{8iv(fg~h&&4&QSxqF z{M@d=?`cEDqt4Bu9uaC5ECceWn1bPiwe%P(AOk!4^~OG5=y#ldfSM0fz7bEAYo*h7 zE3z>wBJ6wj@urJSWcY8?D+WabsKJbHcFHqolyMB9+_J{>bbDVOkVePHxtbH?O-UNL zYKZ1lh2-#9tk-Yc$Y4YfNcki;%>sgR5^0-_c;ii>PkD|Tk|G+b+aM2lOPu6K};VN_xTci=89@y-OCB1<40LBUv;|vSN+wI@;SiiXlI>Y z-j3QAP@c7<_ZOcWUyVGw{6Mug|D=0*`*M6^^(tF5mAWR14P%trwogYLIu)MJX>*hz zeF|Pka+M;RoQtWc2AC;*CyB|YdPWVt zu[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�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

LGxdpF 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

CW-+P8jBUMn-`>N`N-x{5TZN(#k> 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 literal 0 HcmV?d00001 diff --git a/images/marmite.jpg b/images/marmite.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5b9392dcb59365f60cac80d6711bba1364c1d212 GIT binary patch literal 49039 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 RZ4G6zfHq$KK$N;i|Jl%X2i^bx literal 0 HcmV?d00001 diff --git a/images/privacy.jpeg b/images/privacy.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..87230028111e0c900ed23b362d4840c7536b254f GIT binary patch literal 153381 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

d(kCUOXYZ)*u*ZdKHWTHMN^UR@o5px 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 literal 0 HcmV?d00001 diff --git a/images/ihatemoney-fr.png b/images/ihatemoney-fr.png new file mode 100644 index 0000000000000000000000000000000000000000..f1cad7191dc5bb3f423f842e92eda8f12a8bdd36 GIT binary patch literal 61513 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 literal 0 HcmV?d00001 diff --git a/images/illusion.jpg b/images/illusion.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a0ea8572d6084d2f2e20fdb5eb5022a84ed7ae7a GIT binary patch literal 69573 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℞e8%ZO@dGIy-acyl?9m0_o^fJ8)-)3QX6 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�SMww4RA?iAV>{VdN@fL`P-1qArNX|@<2 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 z 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 )WjnK4EQzS9QX`|smBOlLQ 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 ah5|ZwQMoRO^;Nk59cqAif4L z);|~%guB2o{>Kw$1wj5SXBGh9#ucPx6%|Ou6jhWIRYcUJ6%~NLDDOC!U)ew!|7rbC zEh#OpM9Rv<$;846urjl-^0F}VGP9F1v+#0o^RjXQ08LQFKbnD81!ez>o5IQe)&L|f z4gg?46(ln&D@z>2KU#u+j)VLcPsfA(#RCQo0mOsuuJg~pzgEYzm|6f~q5dXnY|9Bj(rU2(}I;gh_|B?gt+Qo%`*$V~|0~CV)(FYc! zPfpQ4@o8ZQ7iI>_Qzj0D2?AgQky^bI%-=si4+jAEFBSz5US<5P6VhL80bn52kpID;0fhEXpF#VB#^oP<{_y-Yl0b4HNCE6W zx`9R$xFUe_A0FKQV7!0hRTCikqr4nX#DDrJ@-H4?Fp&Py|H_X84Y*f7fQaDfK>RBYI2NcB0}21} zL-HRU(CC5e08(Fhzz9M3E0Fd_CJ6vQtpId=3ep!46;YKIBP9hy)YTM8|9<}d z0frO=o}T{|I}fH-QQ$62YnessW0> zYwp)tUh$ncoAGNKB5LX?e>DOyvodoW+_fll!N0Q$$qKUMd#O`CG@4}aXc)eFI$ExE zp&nLUk}CQAR>#%PT#xm(QsJlZ46}Xb9ylV@Nq>aUZ}(fP5nPSn+=`-TbH>du0v1%K z9)RgWQ-yzN7ZxelA~1kul!{{v1#aG5JvPBEa!16ietPX`D9@IE!u-(Se8I*%$3NIc zK2+1n9XPNF|1GVLew;l7$;9*q{;ZthLvW}1?E_zI&5Hj7R`4u@PflHNpb^tcspz