Jekyll2024-01-07T21:11:12+01:00/feed.xmlRétrospective 20232024-01-07T00:00:00+01:002024-01-07T00:00:00+01:00/2024/01/07/retrospective-2023<p>Je ne pensais pas avoir délaissé cet espace d’expression aussi longtemps !
Plus d’un an et que de chemin parcouru depuis mon dernier billet.
Je n’ai jamais essayé ce genre d’exercice, et puis
<a href="https://blog.zwindler.fr/2023/12/22/dans-le-retro-2023/">ce billet de Zwindler</a> est apparu dans mon fil RSS et je me suis
dit « après tout, pourquoi pas ? ».
Par la suite, j’ai vu que d’autres bloggers semblent tenter cet exercice alors, allons y, mettons la timidité et le manque
de confiance en soi de côté.</p>
<!--more-->
<h1 id="professionnellement">Professionnellement</h1>
<h2 id="évolution-professionnelle">Évolution professionnelle</h2>
<h3 id="carrière">Carrière</h3>
<p>J’ai signé mon premier CDI ! Cela fait maintenant un an que je suis en contrat à durée indéterminée à de l’ENS. Je travaille
encore dans la même équipe auprès de laquelle je suis en détachement et avec laquelle nous arrivons à rester soudés malgré les
hauts et les bas. C’est une équipe où je me sens bien et où je suis libre des choix technologiques, ça fait beaucoup de bien.</p>
<h3 id="formation">Formation</h3>
<p>J’ai pu suivre une formation en administration PostgreSQL début Décembre, après des années à en faire la demande à chaque
entretien d’évaluation professionnel. Un grand merci au CNRS et au réseau base de données d’avoir accepté ma candidature,
je comprends mieux cet outil et son environnement et j’ai hâte de pouvoir mettre en application ce que j’y ai appris !</p>
<h2 id="développement-et-adminsys">Développement et adminsys</h2>
<h3 id="grosse-refactorisation-en-cours">Grosse refactorisation en cours</h3>
<p>J’ai commencé à travailler sur une nouvelle version, plus propre, d’une grosse application interne qui est très utilisée
par la scolarité de l’Institut. J’ai fait le choix de rester sur la même technologie et de repartir de presque zéro devant
l’ampleur de la migration qui m’attendait : 3 versions majeures et beaucoup de refactorisation à prévoir, en partant d’une base
de code de type spaghetti.</p>
<p>Ça prend du temps, c’est long, je reprends des portions de code pour les réadapter tout en cherchant
à améliorer l’interface et la maintenabilité du projet. Et j’apprends aussi beaucoup sur le framework Symfony tout en me mettant
des claques mentales quand je vois les bêtises que j’ai pu faire. C’est positif : ça veut dire que j’ai appris et que je peux
améliorer et optimiser tout ça !</p>
<p>Pour information, cette application avait été developpée dans un premier temps par un précédent ingénieur qui découvrait le
framework et sans doute aussi le métier. Je ne doute pas que cette personne a aussi évolué depuis.</p>
<h3 id="maintenance-etou-déploiement-dapplications-internes">Maintenance et/ou déploiement d’applications internes</h3>
<p>En vrac j’ai :</p>
<ul>
<li>fait passer une application centrale d’une version 4 de Ruby-On-Rails à la version 7, j’en ai profité pour nettoyer et factoriser
la base de code</li>
<li>apporté des améliorations à l’application centrale et des fonctionnalités plus proches des besoins métiers</li>
<li>mis à jour des sites sous SPIP, certains passant de la version 2 à la version 4, sans qu’il y ait eu de casse, en
équipe avec mon supérieur hiérarchique</li>
<li>corrigé des bugs sur une application métier et apporté des améliorations suite aux retours d’utilisation</li>
<li>commencé à mettre à jour nos outils internes sur la dernière version de PHP avec un gros travail de refactorisation et de
nettoyage du code de base à gros coups de suppression</li>
<li>apporté une nouvelle fonctionnalité à une petite application interne, j’en ai profité pour mettre à jour Ruby-On-Rails et virer
webpacker (cette dernière étape étant ce qui m’a demandé le plus de temps…)</li>
<li>déployé un nouveau wiki pour ma plateforme</li>
</ul>
<h2 id="documentation">Documentation</h2>
<p>En vrac j’ai :</p>
<ul>
<li>documenté mon processus de déploiement d’application Ruby-On-Rails sur nos serveurs avec nos besoins spécifiques</li>
<li>documenté mes codes sources en respectant les recommandations des langages/framework lorsque celles-ci existent</li>
<li>documenté mes README dans les projets pour qu’ils puissent être repris par quelqu’un d’autre</li>
</ul>
<h1 id="personnellement">Personnellement</h1>
<h2 id="négatif">Négatif</h2>
<p>On va commencer par le moins drôle : j’ai eu énormément de pression et de stress cumulé, entre mes activités professionnelles,
le stress de la période d’essai qui n’existait pas, la pression que je me mets habituellement pour des projets ou activités
qui me tiennent à cœur, et des pressions/critiques extérieures dont je n’étais pas la cible, mais me touchaient quand même, j’ai
fait une attaque de panique sur mon lieu de travail, foutant la trouille à tout le monde au passage (collègues, médecins, conjoint).</p>
<p>Il semblerait que j’ai fait un burn out, ça arrive, j’ai stoppé net toutes mes activités associatives,
commencé une analyse auprès d’une psychologue pour comprendre comment je fonctionne (depuis le temps que je repoussais…), et je remonte
la pente, comme je peux. Et non, je n’en dirai pas plus. Mais si vous m’avez vu exploser sur les réseaux sociaux ces derniers mois,
en étant plus soupe-au-lait qu’à mon habitude, maintenant vous savez. Et je vous présente mes excuses de vous avoir entraîné dans mon
sillage si tel est le cas.</p>
<h2 id="positif">Positif</h2>
<p>Parce qu’on ne va pas finir la note sur une soupe-à-la-grimace, en vrac, j’ai :</p>
<ul>
<li>acheté une maison avec mon chaton</li>
<li>suivi une formation sur le compostage et récupéré un composteur</li>
<li>recommencé à prendre du plaisir à jouer aux jeux vidéos</li>
<li>commencé à apprendre à prendre soin de moi pour autre chose que du médical</li>
<li>commencé à apprendre à dire non ou stop à mon cerveau qui veut toujours en faire plus</li>
<li>revu deux amis que je n’avais pas vu depuis au moins 4 ans</li>
<li>passé une bonne fin d’année auprès de mes parents et de mon petit frère</li>
</ul>
<hr />
<p>Bonne année 2024 à toutes et à tous, prenez soin de vous et de vos proches.</p>nororeJe ne pensais pas avoir délaissé cet espace d’expression aussi longtemps ! Plus d’un an et que de chemin parcouru depuis mon dernier billet. Je n’ai jamais essayé ce genre d’exercice, et puis ce billet de Zwindler est apparu dans mon fil RSS et je me suis dit « après tout, pourquoi pas ? ». Par la suite, j’ai vu que d’autres bloggers semblent tenter cet exercice alors, allons y, mettons la timidité et le manque de confiance en soi de côté.C’est quoi, pour moi, être « libriste » ?2022-11-27T00:00:00+01:002022-11-27T00:00:00+01:00/2022/11/27/cest-quoi-pour-moi-etre-libriste<p>« Libriste ». Que voilà un bien curieux mot employé pour désigner une certaine catégorie de personnes. Adepte de
la philosophie du monde du Libre au sens large, c’est une question qui me revient souvent en tête. Au fond, pour moi,
c’est quoi être « libriste » ? Oui, les guillemets ont leur importance. Dans ce billet tout personnel, je vous
propose de voir un bout de mon parcours, de mes réflexions et de pourquoi je parle de philosophie et non pas de
politique. Quitte à devoir faire grincer quelques dents.</p>
<p>(Ce billet est très décousu, je l’avais commencé il y a deux ans sans trop savoir où j’allais. Je l’ai repris, il n’en
est pas mieux cousu. Peut-être que dans dix ans je penserai différemment, si je suis toujours de ce monde.)</p>
<!--more-->
<h1 id="mais-cest-quoi-un-libriste-et-pourquoi-ces-guillemets">Mais c’est quoi un libriste ? Et pourquoi ces guillemets ?</h1>
<p>Si l’on se réfère à Wikipédia, la définition de libriste est la suivante :</p>
<blockquote>
<p>Un <em>libriste</em> est une personne attachée aux valeurs éthiques véhiculées par le logiciel libre et la culture libre en
général.</p>
<p>En matière de logiciels, le libriste défend les quatre libertés fondamentales telles que définies par la
<em>Free Software Foundation</em> (en français, « <em>Fondation pour le logiciel libre</em> ») et le projet GNU, tous deux
fondées par Richard Stallman.</p>
</blockquote>
<p>Je ne suis pas sûr·e que le terme « libriste » soit bien choisi, il a un côté trop radical, trop intégriste qui en
ressort, et, malheureusement, force est de constater que certains adeptes ont effectivement un comportement radical et
intégriste. Quittes à vouloir imposer leur point de vue. Un peu comme certains partis politiques ? Je ne me reconnais
pas totalement dans ce terme, et c’est pourtant ainsi que des gens me voient. Et c’est aussi comme ça que je me
présente parfois, faute de trouver un meilleur terme. Vous comprenez donc peut-être la raison des guillemets.</p>
<h1 id="mes-premières-armes">Mes premières armes</h1>
<p>Comme beaucoup de personnes dans le monde, j’ai découvert l’informatique à travers le système d’exploitation Windows,
de Microsoft. Très certainement sous Windows 95 d’ailleurs. J’ai connu le tristement célèbre Windows Millenium, et,
oui, c’était une vraie purge quand il crashait. Windows XP, qui est arrivé peu après, s’est montré bien plus stable,
ce qui explique sans doute sa longévité ! J’ai connu le temps où, pour pouvoir jouer sur un jeu présent sur une autre
partition que C: il fallait passer par DOS pour se brancher sur la partition D: et exécuter une commande pour lancer
le jeu de notre choix. Je ne le savais pas à l’époque, mais c’était bel et bien de la ligne de commande, certes
basique et tapée naïvement en suivant, à la lettre, les instructions que mon parrain m’avait indiquées.</p>
<p>Lorsque la première machine est arrivée dans ma famille, ma mère m’a imposé d’apprendre à taper au clavier à l’aide de
mes dix doigts. Grâce à un logiciel de dactylographie de l’époque, propriétaire et payant, j’ai rapidement su utiliser
le clavier AZERTY et découvrir les logiciels existants. Très rapidement, je me suis retrouvée frustrée de devoir me
limiter à des logiciels gratuits, ou fournis de base, et bien moins performants que la suite Microsoft Office que
j’utilisais au collège et au lycée. C’était vers la fin des années 1990, début des années 2000. (Qui se souvient de
Works ?)</p>
<p>Et puis un jour, internet est arrivé dans notre foyer. Avec une petite connexion, il fallait faire attention à ne pas
trop l’utiliser pour ne pas dépasser le forfait. Et demander à la famille de ne pas utiliser le téléphone le temps de
faire sa recherche internet. Au fil du temps, des forfaits plus conséquents sont arrivés, me permettant de découvrir
qu’il existait des logiciels gratuits et performants que l’on peut télécharger et utiliser sur sa machine. Comme
internet était déjà une jungle épaisse, je regardais d’un œil envieux ces outils, en me demandant s’ils sont vraiment
légaux, s’ils sont fiables et ne risquent pas de détruire mon ordinateur et toutes mes données. C’étaient les prémices
des logiciels libres en France, Wikipédia était encore tout récent, le mouvement était alors encore moins connu
qu’aujourd’hui. D’où une certaine méfiance quand on a été biberonné·e au tout payant (logiciel, service et après-vente).</p>
<h1 id="cest-quoi-ce-truc">C’est quoi ce truc ?</h1>
<p>Arrive l’année de mon baccalauréat, que j’arrive à arracher tant bien que mal. En cadeau, je demande un ordinateur pour
pouvoir entrer mes cours, et aussi jouer, accessoirement. Beaucoup plus jouer que de rentrer mes cours, peut-être ?
Je continue de lire des articles sur Wikipédia, qui me permet de satisfaire ma curiosité sur différents sujets, tout en
squattant des fora de jeux vidéos et d’informatique. Et donc en continuant de jeter un œil étonné et intéressé sur le
logiciel et la culture libre, sans vraiment oser sauter le pas.</p>
<p>Et puis un jour, au détour d’un post, je vois une campagne le lancement pour une prochaine mise à jour de Mozilla
Firefox. Je m’inscris pour recevoir mon Sésame. Dans la foulée, n’arrivant pas à me dépatouiller avec Microsoft Word
qui me demande sans cesse de passer par le tiroir caisse pour mettre à jour, sachant que je suis étudiante et que je
n’ose pas demander de l’argent à mes parents, j’installe Libre Office, avant la scission.</p>
<p>Je fais aussi du graphisme en amateur sur mon temps libre, je découvre Inkscape et je fais des débuts timides et
hésitants sous Gimp, ne retrouvant pas mes habitudes de sous Photoshop.</p>
<p>Je teste, je tâtonne, je me pose aussi des questions sur Linux, mais je n’ose pas faire le grand saut. Je suis en
formation pour devenir biologiste, et peut-être plus tard bioinformaticien·ne, je ne sais pas comment installer un
système d’exploitation libre et les tutoriels que je lis me paraissent obscurs, très brouillon. Il n’y a pas encore de
vidéo sur internet pour que j’ai une idée de comment ça se fait. Comme je ne suis pas très sociale, je ne connais pas
encore les GULLs, je n’ai pas encore rencontré le terme, je ne sais donc pas encore que des gens, dans ma ville,
pourraient m’aider. Et puis, est-ce que j’ai vraiment envie de faire une croix sur mes jeux ?</p>
<h1 id="entre-tu-es-la-bienvenue">« Entre, tu es la bienvenue ! »</h1>
<p>Arrive ma première année de Master en bioinformatique. Dès le premier jour de prérentrée j’apprends que l’on va
travailler sur Linux. Ô joie ! Je vais enfin pouvoir tester et découvrir de moi-même comment ça marche ! Dans le
mois qui suit, on reçoit un courriel nous informant d’une conférence sur les outils de graphisme libres. Je suis
curieuse, c’est sur mon campus, le soir après mes cours. J’assiste à la conférence, je suis bluffée par le niveau du
conférencier. Je ne sais pas faire d’aussi jolis dessins sous Inkscape, je suis jalouse. À la fin de la conférence, je
vais le voir, on discute un peu, et là il me propose de passer un jeudi à son collectif pour que ses copains et lui
m’aident à installer Linux en dual boot sur mon portable. Nous sommes très vite devenus amis
et, quatorze ans plus tard, nous le sommes toujours.</p>
<p>Dans ce collectif, je commence à faire mes premières armes en aidant des gens qui sont bloqués sur leurs outils. Comme
c’est un centre social, je découvre différents profils que je n’avais encore jamais croisés dans mon milieu d’origine
ou dans mes études. J’apprends beaucoup : sur le logiciel et la culture libre, sur les gens, sur les autres, sur moi,
aussi. Je voulais m’ouvrir à la culture et au logiciel libre, j’ai davantage ouvert mon esprit à l’humain et à sa
complexité.</p>
<h1 id="un-monde-ouvert">Un monde ouvert ?</h1>
<p>Bien sûr, tout n’est pas non plus rose dans le monde du libre. Tout comme dans le monde propriétaire, on trouve des
humanistes d’un côté et des élitistes de l’autre. On trouve aussi une certaine étroitesse d’esprit chez un certain
nombre d’entre eux. Sans parler des trolls. *Et cela peut, malheureusement, avoir une influence plus ou moins bonne sur
notre construction.</p>
<p><em>(*À partir d’ici je reprends le texte, ne sachant plus trop ce que j’avais en tête il y a deux ans. Il faudra bien s’en
contenter !)</em></p>
<p>J’ai pendant un temps, peut-être un peu trop, été du côté “puriste”, à chercher le plus possible à n’utiliser que des
outils et des logiciels libres, usant beaucoup de mon sarcasme habituel lors de mes interactions avec autrui. Cela fait
partie de ma vie et de ma construction en tant qu’individu. Est-ce que j’ai des regrets ? Non, plutôt des remords,
les regrets ne servant pas à avancer. Si c’était à refaire, est-ce que je le referai ? Aucune idée. Il est possible
que le fait de gagner en confiance en moi, à cette époque, ait obscurci la personne que j’étais. J’ai peut-être encore
ce travers, il faudra que je fasse montre de plus de prudence sur ce trait de ma personnalité.</p>
<p>En quittant ma région natale pour l’Île-de-France pour mon premier travail, j’ai pu avoir l’opportunité de m’ouvrir un
peu plus au monde du libre. Et découvrir ainsi que tout n’est pas toujours beau. Les dissensions et les prises de bec
sont présentes et réelles. Peut-être que ces sujets sont moins visibles en « Province » ? Ou alors j’ai tout
simplement mûri à force de prendre des coups sans le vouloir ?</p>
<h1 id="oui-cest-politique">Oui, c’est politique !</h1>
<p>Dans les milieux que je fréquente, j’entends souvent dire que si c’est apolitique alors c’est de droite. J’imagine que
les autres milieux disent que c’est de gauche. Donc, est-ce que le logiciel libre et la culture libre sont
apolitiques ? Je suppose que l’on devrait plutôt dire sans-parti.</p>
<p>L’un des avantages de la culture libre et de ses outils, c’est qu’ils sont ouverts à tous, y compris aux plus démunis.
L’un des inconvénients c’est qu’ils sont également ouverts à des personnes dont la mentalité et le mode de fonctionnement
ne nous plaît pas forcément, comme l’extrême droite pour ne pas la nommer.</p>
<p>Pour moi, être libriste, c’est aussi ça : assumer ce genre de choix. Est-ce que je veux que mon outil soit utile
aux plus démunis ? Oui. Est-ce que je veux en exclure certains groupes de personnes ? Oui. Est-ce que j’en ai le
droit ? Non. Techniquement ce serait difficile. Et moralement aussi. Alors je fais ce que je peux pour aider le plus
de monde possible. Tout en sachant qu’une partie de celleux que je vais aider souhaite ma mort. Je n’ai pas à juger. En
avoir conscience me permet également de savoir que je dois me protéger.</p>
<p>Lorsque j’aurai mis un certain nombre de choses derrière moi, que j’aurai de nouveau les ressources nécessaires et si
la situation sanitaire s’améliore, ce qui est loin d’être gagné, j’aimerai aider un peu plus que ce que j’ai pu faire
au cours de ces dernières années. Pour remercier les personnes qui m’ont elles-mêmes aidées. Mais également pour aider
d’autres asociaux sans, ou avec très peu de, conscience politique à s’outiller pour s’émanciper.</p>
<p>Je reste persuadé·e que la culture, au sens large, doit être libre et accessible au plus grand nombre. Quel que soit
son bord politique. Pour moi le logiciel ne reste qu’un outil d’émancipation. Même libre. Et le détourner de cet usage,
c’est en faire une arme.</p>
<p>J’ai sûrement tort, ce ne sera pas la première fois. Pour moi, même si le mouvement libriste est politique, tant
qu’il y aura des gens de différents bords politiques dans le mouvement, je continuerai de ne le voir que sur
le plan philosophique.</p>norore« Libriste ». Que voilà un bien curieux mot employé pour désigner une certaine catégorie de personnes. Adepte de la philosophie du monde du Libre au sens large, c’est une question qui me revient souvent en tête. Au fond, pour moi, c’est quoi être « libriste » ? Oui, les guillemets ont leur importance. Dans ce billet tout personnel, je vous propose de voir un bout de mon parcours, de mes réflexions et de pourquoi je parle de philosophie et non pas de politique. Quitte à devoir faire grincer quelques dents. (Ce billet est très décousu, je l’avais commencé il y a deux ans sans trop savoir où j’allais. Je l’ai repris, il n’en est pas mieux cousu. Peut-être que dans dix ans je penserai différemment, si je suis toujours de ce monde.)Code en vrac : mettre à jour une colonne d’une table dans PostgreSQL en Bash2022-07-10T00:00:00+02:002022-07-10T00:00:00+02:00/2022/07/10/codes-en-vrac-updater-une-colonne-une-table-en-bash<p>Vous est-il déjà arrivé, dans le cadre de votre travail, de devoir mettre à jour une colonne spécifique dans votre base
de données PostgreSQL ? C’est une tâche somme toute assez basique et rapide à faire. Mais quand ce n’est à faire
qu’une fois par an, si vous avez déjà sauté sur cinq projets différents, comment vous faciliter la tâche pour ne pas
avoir à retrouver la base de données, la table et la colonne ? Est-ce que faire un script Bash peut être une solution ?
C’est une question que je me suis posé·e cette semaine et l’exercice a été assez amusant à faire. Voyons voir comment ça
marche !</p>
<h1 id="faire-une-requête-en-ligne-de-commande">Faire une requête en ligne de commande</h1>
<p>La première question qui vient à l’esprit, avant de faire un script, c’est comment faire une requête en ligne de commande.</p>
<p>Pour mettre à jour une table, il faut utiliser la syntaxe UPDATE table SET column. Rien de bien sorcier. On peut le faire
très facilement depuis l’interface de PostgreSQL. Mais peut-on passer la commande directement à la ligne de commande psql ?
Un petit tour rapide sur le manuel nous permet de trouver l’option -c. Testons.</p>
<pre><code class="language-{bash}">psql -h localhost -U postgres -d database -c "SELECT COUNT(column) FROM table;"
Mot de passe pour l'utilisateur postgres :
</code></pre>
<p>Mince, ça marche presque. Sauf que devoir donner le mot de passe par la console n’est pas forcément le plus simple à faire.
Si l’on s’attarde davantage sur le manuel de psql, on peut lire qu’il demande un fichier d’environnement PGPASSFILE,
conventionnellement nommé .pgpass.</p>
<p>Sur une machine de développement, voici ce que vous pouvez mettre :</p>
<pre><code class="language-{text}">localhost:5432:*:postgres:postgres
</code></pre>
<p>Les paramètres, chacun étant séparé par le caractère deux-points, qui sont attendus sont les suivants :</p>
<ol>
<li>l’hôte</li>
<li>le port</li>
<li>le nom de la base de données, dans notre exemple, database, sinon * est à utiliser en joker</li>
<li>le nom de l’utilisateur</li>
<li>le mot de passe de l’utilisateur</li>
</ol>
<p>N’oubliez pas d’importer le fichier dans l’environnement Bash, n’hésitez pas non plus à l’ajouter dans votre profil :</p>
<pre><code class="language-{bash}">export PGPASSFILE=".pgpass"
</code></pre>
<p>Retestons notre précédente commande :</p>
<pre><code class="language-{bash}">psql -h localhost -U postgres -d pg_scolarite -c "SELECT COUNT(moodle) FROM maquettes;"
count
-------
255
(1 ligne)
</code></pre>
<p>Impeccable, ça marche ! Voyons voir comment nous pourrions faire la même chose à l’aide d’un script.</p>
<h1 id="un-petit-script-bash-qui-fait-le-boulot">Un petit script Bash qui fait le boulot</h1>
<p>Nous venons donc de voir comment faire une requête SQL depuis la ligne de commande. C’est bien, maintenant nous allons
pouvoir faire un script Bash vite fait, pas forcément bien fait, qui fait le boulot à notre place.</p>
<p>On a besoin de connaître les paramètres de connexion à la base de données PostgreSQL, de créer et écrire un fichier .pgpass
qui sera utilisé par psql, de lancer la commande, et de nettoyer derrière nous :</p>
<pre><code class="language-{bash}">#!/bin/bash
dbhost="localhost"
dbport="5432"
dbname="database"
dbuser="user"
dbpass="password"
pgpass=".pgpass"
if [ ! -f $pgpass ]
then
touch "$pgpass" && chmod 600 "$pgpass"
echo "$dbhost:$dbport:$dbname:$dbuser:$dbpass" > "$pgpass"
fi
export PGPASSFILE="$pgpass"
psql -U $dbuser -d "$dbname" -h "$dbhost" -p "$dbport" -c "UPDATE table SET column=FALSE;"
rm "$pgpass"
</code></pre>
<p>Et voilà ! La prochaine fois que vous devrez mettre à jour cette colonne, il vous suffira d’exécuter ce script !</p>
<p>Un gros avantage de ce script également, c’est que vous pouvez programmer une tâche CRON qui exécutera ce script à votre place.</p>
<h1 id="des-améliorations-possibles">Des améliorations possibles</h1>
<p>Comme dit, c’est un script vite fait, mais pas forcément bien fait.</p>
<p>Dans les améliorations possibles que je vois, on peut récupérer dans les paramètres de la ligne de commande les paramètres de connexion à la base de données. On peut également
donner un autre nom pour le PGPASSFILE, afin d’éviter de potentiellement écraser un fichier déjà existant. Ces paramètres
seront à préciser dans votre tâche CRON si vous en programmez une.</p>
<hr />
<p><em>Source de l’image d’accroche :</em></p>
<p>Un vieil ensemble de casiers à fiche en bois ancien ciré. Les poignées sont en métal vieilli et les étiquettes
portant les numéros de casier, sous les poignées, sont en partie effacées. Au-dessus des poignées se trouve d’autres
étiquettes avec les noms des dossiers. Image par
<a href="https://unsplash.com/@jankolar" title="Voir le profil de
Jan Antonin Kolar sur Unsplash">Jan Antonin Kolar</a>, sur le site <a href="https://unsplash.com/" title="Visiter le site Unsplash">Unsplash</a>, sous license
<a href="https://unsplash.com/license" title="En savoir plus sur la license Unsplash">Unsplash</a></p>nororeVous est-il déjà arrivé, dans le cadre de votre travail, de devoir mettre à jour une colonne spécifique dans votre base de données PostgreSQL ? C’est une tâche somme toute assez basique et rapide à faire. Mais quand ce n’est à faire qu’une fois par an, si vous avez déjà sauté sur cinq projets différents, comment vous faciliter la tâche pour ne pas avoir à retrouver la base de données, la table et la colonne ? Est-ce que faire un script Bash peut être une solution ? C’est une question que je me suis posé·e cette semaine et l’exercice a été assez amusant à faire. Voyons voir comment ça marche !Migration du blog de PluXML vers Jekyll2022-06-04T00:00:00+02:002022-06-04T00:00:00+02:00/2022/06/04/migration-blog-pluxml-vers-jekyll<p>Après des années à utiliser le CMS <a href="https://pluxml.org/" title="Page officielle du CMS PluXML">PluXML</a> et à tester différentes choses dessus, il a fallu que je me rende à l’évidence :
aussi merveilleux que soit cet outil, il ne me convient plus. Mes besoins ont évolué au cours du temps, ce qui est parfaitement
normal et logique. Au fur et à mesure j’ai appris plein de choses en développement web, du coup, ne pas pouvoir les mettre en
application correctement sur mon blog, ça a fini par me frustrer.</p>
<p>Dans un premier temps, nous allons voir quels sont ces nouveaux besoins et en quoi <a href="https://jekyllrb.com/" title="Page officiel du moteur de blog
statique Jekyll, en anglais">Jekyll</a> a pu m’aider à y répondre, au moins en partie. Dans un second temps, nous verrons comment la migration de PluXML vers Jekyll a
pu se faire. Enfin nous parlerons des limites de cette migration pour les personnes tatillonnes !</p>
<!--more-->
<h1 id="de-nouveaux-besoins">De nouveaux besoins</h1>
<h2 id="écriture-plus-fluide-avec-la-syntaxe-markdown">Écriture plus fluide avec la syntaxe Markdown</h2>
<p>Dans le cadre de notre travail, en tant que développeur de façon général, on est souvent amenés à devoir écrire de la documentation :
alimenter un wiki interne, répondre sur le canal de communication interne, écrire des README, rédiger des cahiers des charges… Forcément,
à force d’utiliser différents environnements, il y en a un en particulier qui peut ressortir. Par exemple <a href="https://fr.wikipedia.org/wiki/Markdown" title="Lien vers la page Wikipédia sur le langage Markdown">Markdown</a>. Comme je suis quelqu’un qui n’aime pas forcément passer beaucoup de temps à cliquer
sur des boutons pour mettre en forme mon texte (<a href="https://fr.wikipedia.org/wiki/LaTeX" title="Lire la page Wikipédia sur le langage LaTeX">LaTeX</a>
mon amour !), j’ai fini par chercher un plugin qui me permette de remplacer le <abbr title="What You See Is What You Get, une interface qui permet de voir à l'écran le résultat final de la saisie d'un document">WYSIWYG</abbr> présent de base. Sans trop de succès.</p>
<h2 id="un-menu-latéral-pour-les-titres">Un menu latéral pour les titres</h2>
<p>Il arrive que certains articles soient très longs. Et ça peut vite être frustrant si vous avez dû rafraîchir votre navigateur, même par
inadvertance. Les personnes qui vivent chez leur(s) chat(s) savent de quoi je parle. J’ai donc cherché s’il existe une extension pour
avoir un menu latéral qui permet de cliquer sur les titres de l’article pour se rendre directement sur la portion d’article que l’on
souhaite lire. J’en ai trouvé un dans un recoin du forum de PluXML mais qui ne semblait pas très à jour et, n’ayant aucune volonté de
reprendre le code d’un·e inconnu·e, je le fais déjà suffisamment sur mon lieu de travail, j’ai fini par lâcher l’affaire.</p>
<h2 id="juste-écrire-et-mettre-à-jour">Juste écrire et mettre à jour</h2>
<p>Une autre chose aussi qui me donnait de moins en moins l’envie d’utiliser PluXML, c’était le fait de devoir me connecter à l’interface
d’administration pour écrire dessus. Avec le risque d’avoir un rafraîchissement inopiné de la page ou, le plus embêtant sur ma pause
déjeuner au travail par moments, la connexion internet qui saute au moment d’enregistrer les modifications et perdre des dizaines de phrases.</p>
<p>L’avantage de Jekyll c’est que je peux juste écrire depuis mon ordinateur et, une fois que le billet me convient, je le déplace dans le
répertoire <code class="language-plaintext highlighter-rouge">_posts/</code>, je vérifie qu’il s’affiche correctement, et je lance la mise à jour sur le serveur. En plus de cela, rien ne m’empêche
de mettre le code source sur une solution de versionnement pour pouvoir y accéder aussi au boulot !</p>
<p>Un autre inconvénient à maintenir un CMS comme PluXML, et pourtant c’est un des meilleurs pour ce qui est de la facilité de maintenance, ce sont
les mises à jour. Qui dit site dynamique en PHP dit risque de vulnérabilité. Et donc il faut penser à mettre à jour dès que possible. Avec un site
statique, on réduit ce risque de vulnérabilité.</p>
<h1 id="ok-on-se-lance">OK, on se lance ?</h1>
<h2 id="chercher-une-alternative">Chercher une alternative</h2>
<p>Là j’ai triché. J’avais déjà envie de regarder du côté de Jekyll.</p>
<p>Codant déjà en Ruby-On-Rails et étant déjà familier de l’environnement de Ruby, apprendre ce générateur de blog statique n’a pas été trop
compliqué. Là où ça a un peu plus coincé, ça a été de trouver comment migrer les articles et les brouillons existants. Jekyll proposait déjà
différents importateurs, mais il n’en existait pas encore pour faire la migration depuis PluXML. Un peu d’huile de coude, de lecture de documentations,
une bonne dose de courage, et on propose un importer à la communauté !</p>
<h2 id="importer-depuis-pluxml-vers-jekyll">Importer depuis PluXML vers Jekyll</h2>
<p>J’ai fait une contribution ! Une vraie ! La documentation peut être trouvée sur le site officiel : <a href="https://import.jekyllrb.com/docs/pluxml/">https://import.jekyllrb.com/docs/pluxml/</a>.
Le lien vers le code source de l’importer n’est pas le bon, le code à jour est sur cette page : <a href="https://github.com/jekyll/jekyll-import/blob/master/lib/jekyll-import/importers/pluxml.rb">https://github.com/jekyll/jekyll-import/blob/master/lib/jekyll-import/importers/pluxml.rb</a></p>
<p>Le script marche plutôt bien, mais il présente un gros défaut : si vous avez des images, vous devrez mettre à jour par vous-même vos
différents billets. Si l’un·e d’entre vous a des idées pour améliorer le script : lancez-vous, ça ne vous coûte rien d’essayer, au pire vous
allez réussir, dans tous les cas, vous serez fiers de vous !</p>
<h2 id="trouver-les-bonnes-extensions">Trouver les bonnes extensions</h2>
<p>Jekyll apporte une base pour la conception de blog statique mais il ne fait pas tout. Voici ce que j’ai ajouté pour apporter ce qui me semblait
indispensable et utile :</p>
<ul>
<li>pour la pagination, on peut utiliser la gem <a href="https://github.com/jekyll/jekyll-paginate" title="Lien vers la page GitHub de la gem jekyll-paginate, en anglais">jekyll-paginate</a> ;</li>
<li>pour le menu latéral sur les billets avec plusieurs titres, la gem <a href="https://github.com/toshimaru/jekyll-toc" title="Lien vers la page GitHub de la gem jekyll-toc, en anglais">jekyll-toc</a> ;</li>
<li>pour le flux RSS, <a href="https://github.com/jekyll/jekyll-feed" title="Lien vers la page GitHub de la gem jekyll-feed, en anglais">jekyll-feed</a>, qui fournit une page feed.xml par défaut, à la racine du site. Cette page peut être renommée si besoin ou souhaité.</li>
<li>pour une “carte” du site, <a href="https://github.com/jekyll/jekyll-sitemap" title="Lien vers la page GitHub de la gem jekyll-sitemap">jekyll-sitemap</a>, qui fournit une page sitemap.xml à la racine du site. Je ne sais pas trop si c’est vraiment utile, mais au cas où ça peut
vous être utile d’une quelconque façon, c’est en place.</li>
</ul>
<h1 id="quelques-limites">Quelques limites</h1>
<h2 id="cest-du-html">C’est du HTML !</h2>
<p>Alors oui, un des problèmes de ce script d’import, c’est qu’il dégrossit le travail mais il ne fait pas tout non plus. Pour convertir les fichiers
du format HTML au format MD j’ai dû utiliser la méthode ancestrale du copié-collé sur un outil en ligne qui permet de faire la conversion, puis
repasser sur les documents pour remettre au propre. Il a aussi fallu en profiter pour mettre à jour les liens vers les anciens billets, puisque le
format des URLs a changé.</p>
<h2 id="plus-de-commentaires">Plus de commentaires</h2>
<p>Il n’y a pas la possibilité, sur un site statique, d’avoir des commentaires. Il existe bien sûr des solutions, certaines payantes, d’autres
gratuites mais peu regardantes sur le <abbr title="Règlement général sur la protection des données">RGPD</abbr>, ou des gratuites mais demandant un peu plus d’effort, comme <a href="https://commento.io/" title="Visiter
le site officiel de Commento">Commento.io</a> dont on a déjà parlé il y a de cela un petit moment <a href="/2020/06/20/deployer-commento-pour-siteblog-statique.html" title="Lire le billet Déployer Commento pour un site/blog statique, sur le blog de Norore">ici</a>. Pour l’instant, je n’ai pas l’intention de remettre la
possibilité de laisser un commentaire.</p>
<p>Je n’ai pas ou plus la patience intellectuelle pour trier la critique constructive, la critique non constructive, les
trolls, le spam.</p>
<p>Si vous souhaitez discuter, la porte est ouverte sur les réseaux sociaux, ne vous attendez pas forcément à une réponse immédiate de ma part.
Je peux être fatigué·e, ne pas répondre sur le moment et y revenir plus tard. Ou estimer que cela n’attend pas forcément une réponse de ma part, auquel cas vous
aurez peut-être un petit “like”.</p>
<h2 id="quelques-casses">Quelques casses ?</h2>
<p>Forcément, changer de système ne se fait pas sans casse. Si les commentaires ont disparu et sauté (dommage ou tant mieux ? À vous de choisir.), il est
également gênant pour vous, si vous me suivez par les flux RSS, que votre flux ait sauté. J’aurai dû anticiper et vous informer avant. C’est ce que j’aurai
fait si je n’avais pas eu une longue traversée du désert dont je semble, pour l’instant du moins, arriver à sortir. Le nouveau flux RSS devrait normalement être
disponible à l’adresse <a href="https://blog.norore.fr/feed.xml" title="Lien vers le nouveau flux RSS du blog de Norore">https://blog.norore.fr/feed.xml</a></p>
<p>Je crois avoir fait le tour sur cette migration. Il me reste à mettre en place le déploiement et ça devrait rouler. Pour celleux d’entre vous qui souhaitent faire
cette même migration : bon courage !</p>
<hr />
<p><em>Source de l’image d’accroche :</em> Un envol d’oies sauvages en pleine migration au milieu des arbres, en traversant une petite clairière. Photographie de
<a href="https://pixabay.com/users/sd-pictures-3553481/" title="Voir le profil de SD-Pictures sur Pixabay">SD-Pictures</a> sur <a href="https://pixabay.com/" title="Visiter le site Pixabay">Pixabay</a></p>nororeAprès des années à utiliser le CMS PluXML et à tester différentes choses dessus, il a fallu que je me rende à l’évidence : aussi merveilleux que soit cet outil, il ne me convient plus. Mes besoins ont évolué au cours du temps, ce qui est parfaitement normal et logique. Au fur et à mesure j’ai appris plein de choses en développement web, du coup, ne pas pouvoir les mettre en application correctement sur mon blog, ça a fini par me frustrer. Dans un premier temps, nous allons voir quels sont ces nouveaux besoins et en quoi Jekyll a pu m’aider à y répondre, au moins en partie. Dans un second temps, nous verrons comment la migration de PluXML vers Jekyll a pu se faire. Enfin nous parlerons des limites de cette migration pour les personnes tatillonnes !Je culpabilise2020-10-27T00:00:00+01:002020-10-27T00:00:00+01:00/2020/10/27/je-culpabilise<p>Tout est dans le titre. Au départ je pensais en faire un ou deux messages sur Mastodon et
les découper pour Twitter, mais finalement, j’avais besoin de laisser glisser mes doigts
sur le clavier. Ce n’est pas un texte amusant ni technique. C’est assez personnel et,
âmes sensibles soyez prévenues, c’est un peu mon état psychologique actuel avec le COVID-19.</p>
<!--more-->
<p>Je culpabilise.</p>
<p>Je culpabilise parce que je suis privilégiée dans tout ce merdier qu’est le monde actuellement.</p>
<p>Je suis en bonne santé. Je ne manque de rien. J’ai trois chats et je vis avec ma moitié, qui
arrive à supporter mes sautes d’humeur (il y en a plus souvent depuis Mars…). J’ai un boulot
qui me plaît même si parfois je râle/peste dessus.</p>
<p>Mais la situation actuelle me pèse, et sortir de chez moi me fais sentir une épée de Damoclès
au dessus de la tête. Je ne vois pratiquement plus personne en dehors de mes collègues et de
mon foyer. C’est difficile mentalement.</p>
<p>Je n’ai pas pu voir mes parents cet été. Ni fêter mon anniversaire et celui de mon frère en
famille, confinement oblige. Je ne peux toujours pas voir mes parents, de peur de les
contaminer, et je ne sais pas quand je pourrai les revoir. Quant à voir mon frère, je ne
sais pas non plus quand cela sera possible.</p>
<p>Et je culpabilise parce d’autres n’ont pas ma chance.</p>
<p>Je pense à une de mes amies, qui vit recluse depuis des mois, et qui ne doit pas choper
cette saleté. Parce qu’elle est fragile. Parce que l’on ne sait pas si son corps encaisserait
la maladie. On se doute que non. Mais son employeur semble s’en foutre. Heureusement elle a des
médecins formidables qui la soutiennent, et lui font les certificats idoines, ainsi que pour son
mari. Mais elle a aussi une famille, dont un petit garçon qui a fait sa rentrée en Septembre.
Loin de chez eux, dans une région moins touchée. Et je suis contente de la savoir plus en sécurité.
Mais je sais aussi que c’est très dur pour elle et sa famille. Parce qu’ils ne peuvent voir personne,
de peur de la contaminer. Elle et sa famille me manquent, et je m’inquiète même si je ne leur écris
pas souvent.</p>
<p>Alors je culpabilise avec mes “petits” tracas, moi qui suis tellement privilégiée.</p>
<p>Je me demande aussi si mes autres amis vont bien. Même ceux que j’ai connu il y a longtemps et que
j’ai perdu de vue. Est-ce qu’iels vivent bien la situation ? Est-ce qu’iels vont bien ? Est-ce
que l’on pourra de nouveau se retrouver pour une occasion ou une autre, boire des coups ensemble et
refaire le monde avec nos visions de la vie à la fois similaires et différentes ?</p>
<p>Et puis je pense au corps médical, moi qui ai connu personnellement certains d’entre eux, parce que ce
sont des amis de mes parents, qu’ils ont connu pendant l’internat de mon père. Ce corps médical
tellement délaissé depuis trente ans par les différentes politiques mises en place. Certaines mesures
ont été bien pensé. D’autres ont donné la situation de délabrement que l’hôpital public connaît
actuellement, en plus de la pandémie. J’espère qu’iels vont pouvoir tenir. Je souhaite que cette
situation s’améliore au plus vite, et qu’iels puissent tous souffler et prendre le repos qu’iels
méritent tous. Je souhaite que les politiques à venir sauront tenir compte de la place réelle et
importante de l’hôpital public et que la logique, absurde lorsque l’on parle de santé, de rentabilité
sera enfin enterrée.</p>
<p>Et je culpabilise, moi qui ne suis pas confrontée à tout ça. Est-ce que j’aurai pu être utile,
aujourd’hui, si j’avais finalement tenté médecine au lieu de préférer partir en biologie ? Et
est-ce que j’aurai été à la hauteur de cet immense tsunami ?</p>
<p>Je l’ignore. Je me sens impuissante. J’ai l’impression d’être dans une sorte de dimension parallèle
dont je ne parviens pas à m’échapper. Comme un cauchemar qui ne semble pas avoir de fin.</p>
<p>Et je culpabilise. Et le fait de culpabiliser me fait culpabiliser davantage.</p>
<hr />
<p><em>Source de l’image d’accroche :</em> Une vieille grille en partie rouillée dans une ouverture de
fenêtre sur un mur de briques et de ciment. Photographie de
<a href="https://pixabay.com/users/engin_akyurt-3656355/" title="Voir le profil d’Engin_Akyurt sur Pixabay">Engin_Akyurt</a> sur <a href="https://pixabay.com/" title="Visiter le site Pixabay">Pixabay</a></p>nororeTout est dans le titre. Au départ je pensais en faire un ou deux messages sur Mastodon et les découper pour Twitter, mais finalement, j’avais besoin de laisser glisser mes doigts sur le clavier. Ce n’est pas un texte amusant ni technique. C’est assez personnel et, âmes sensibles soyez prévenues, c’est un peu mon état psychologique actuel avec le COVID-19.Déployer Commento pour un site/blog statique2020-06-20T00:00:00+02:002020-06-20T00:00:00+02:00/2020/06/20/deployer-commento-pour-siteblog-statique<p>Pour une idée de projet récente qui me plaît beaucoup, je me suis imposée la mise en place d’un blog
statique afin de pouvoir mettre les diffénets points sur lesquels j’ai pu avancer, ceux sur lesquels
je butte, et autres. Ce blog tourne sous Pelican (Python) et est couplé au moteur de commentaire
<a href="https://commento.io/" title="Visiter le site officiel de Commento">Commento.io</a>. Comme ce projet a le bon
goût d’être auto-hébergeable, je l’ai déployé sur mon serveur, avec un peu d’aide de mon #chaton. Voici
ma procédure, libre à vous de l’adapter par la suite.</p>
<h1 id="cest-quoi-commento">C’est quoi Commento ?</h1>
<p>Commento.io est une plateforme de commentaire qui se veut légère et non intrusive, tout en reprenant
les idées de fonctionnement de Discuss. Deux options s’offrent à vous quant à son utilisation :</p>
<ul>
<li>soit prendre un abonnement sur le site du développeur qui hébergera une instance pour votre site ;</li>
<li>soit récupérer les sources ou les binaires et déployer sur votre propre serveur.</li>
</ul>
<p>Si vous souhaitez déployer Commento sur votre serveur, vous aurez besoin d’une base de données
PostgreSQL. Commento a également besoin de JavaScript pour fonctionner.</p>
<h1 id="déploiement">Déploiement</h1>
<p>Pour le déploiement, nous allons partir du principe que vous avez récupéré le fichier binaire de
Commento.io.</p>
<p>Le déploiement va ensuite se faire en trois étapes distinctes :</p>
<ol>
<li>mettre en place la base de données PostgreSQL ;</li>
<li>créer le service qui va faire tourner Commento ;</li>
<li>faire un reverse proxy pour rendre Commento accessible depuis l’extérieur.</li>
</ol>
<h2 id="mise-en-place-de-la-base-de-données">Mise en place de la base de données</h2>
<p>Pour ce point, nous allons partir du principe que vous disposez déjà d’un serveur PostgreSQL.</p>
<p>Dans un terminal, en tant que root (remplacez les points en début de ligne par un anti-slash) :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># on passe sur l’utilisateur postgres</span>
su postgres
<span class="c"># on appelle la ligne de commande de PostgreSQL</span>
psql
<span class="c"># on créé l’utilisateur commento avec le login du même nom</span>
CREATE ROLE commento WITH LOGIN<span class="p">;</span>
<span class="c"># on créé un mot de passe pour l’utilisateur commento</span>
.password commento
<span class="c"># on créé la base de données commento</span>
CREATE DATABASE commento<span class="p">;</span>
<span class="c"># pour vérifier que la base de données a été créé, vous pouvez afficher la liste</span>
.l
<span class="c"># on quitte le shell de PostgreSQL</span>
.q
<span class="c"># on se déconnecte de l’utilisateur postgres pour revenir en tant que root</span>
<span class="nb">exit</span>
</code></pre></div></div>
<h2 id="création-du-service">Création du service</h2>
<p>Pour ma part, j’utilise systemd, si vous utilisez autre chose vous devrez sûrement adapter le fichier
de configuration du service.</p>
<p>Créez le fichier de configuration :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>vim /etc/systemd/system/commento.service
<span class="o">[</span>Unit]
<span class="nv">Description</span><span class="o">=</span>Commento server
<span class="nv">After</span><span class="o">=</span>notwork.target
<span class="o">[</span>Service]
<span class="nv">Type</span><span class="o">=</span>simple
<span class="nv">User</span><span class="o">=</span>www-data
<span class="c"># le chemin vers le répertoire qui contient les fichiers nécessaire au moteur commento</span>
<span class="nv">WorkingDirectory</span><span class="o">=</span>/mon/chemin/commento
<span class="nv">Environment</span><span class="o">=</span><span class="nv">COMMENTO_ORIGIN</span><span class="o">=</span>https://commento.domaine
<span class="c"># indiquer le port à utiliser, notez-le pour le reverse proxy</span>
<span class="nv">Environment</span><span class="o">=</span><span class="nv">COMMENT_PORT</span><span class="o">=</span>8080
<span class="c"># remplacer user par commento, l’utilisateur de la base de données commento</span>
<span class="c"># remplacer password par le mot de passe que vous avez choisi pour l’utilisateur commento</span>
<span class="nv">Environment</span><span class="o">=</span><span class="nv">COMMENT_POSTGRES</span><span class="o">=</span>postgres://user:password@localhost:5432/commento
<span class="c"># le chemin vers l’exécutable commento</span>
<span class="nv">ExecStart</span><span class="o">=</span>/mon/chemin/commento/commento
<span class="o">[</span>Install]
<span class="nv">WantedBy</span><span class="o">=</span>multi-user.target
</code></pre></div></div>
<p>Une fois enregistré, vous pouvez lancer le service en saisissant dans le terminal :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl start commento
</code></pre></div></div>
<p>Pour vérifier l’état du service commento :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl status commento
</code></pre></div></div>
<p>Si vous êtes satisfait de votre service, n’oubliez pas de le rajouter dans la liste des services
actifs pour qu’il puisse être redémarré avec l’ensemble de vos services en cas de redémarrage du serveur.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>systemctl <span class="nb">enable </span>commento.service
</code></pre></div></div>
<h2 id="mise-en-place-du-reverse-proxy">Mise en place du reverse proxy</h2>
<p>J’utilise le serveur web Nginx, aussi vous devrez adapter le code suivant si vous êtes plus à l’aise
avec Apache2 ou un autre serveur.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>vim /etc/nginx/sites-available/commento.domaine
server <span class="o">{</span>
listen 443 ssl<span class="p">;</span>
listen <span class="o">[</span>::]:443 ssl<span class="p">;</span>
ssl_certificate /etc/ssl/private/domaine.crt<span class="p">;</span>
ssl_certificate_key /etc/ssl/private/domaine.pem<span class="p">;</span>
server_name commento.domaine<span class="p">;</span>
root /var/www/domaine/commento<span class="p">;</span>
index index.html index.htm<span class="p">;</span>
access_log /var/log/nginx/domaine.commento.access.log<span class="p">;</span>
error_log /var/log/nginx/domaine.commento.error.log<span class="p">;</span>
location / <span class="o">{</span>
proxy_pass http://localhost:8080<span class="p">;</span>
proxy_set_header Host <span class="nv">$host</span><span class="p">;</span>
proxy_set_header X-Real-IP <span class="nv">$remote_addr</span><span class="p">;</span>
proxy_set_header X-Forwarded-For <span class="nv">$proxy_add_x_forwarded_for</span><span class="p">;</span>
proxy_set_header X-Forwarded-Proto https<span class="p">;</span>
proxy_pass_header Server<span class="p">;</span>
proxy_buffering off<span class="p">;</span>
proxy_redirect off<span class="p">;</span>
proxy_http_version 1.1<span class="p">;</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>Une fois votre nouveau serveur prêt, n’oubliez pas de l’activer à l’aide d’un lien symbolique :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">ln</span> <span class="nt">-s</span> /etc/nginx/sites-available/commento.domaine commento.domaine
</code></pre></div></div>
<p>Une fois fait, vous n’avez plus qu’à recharger le service Nginx :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># vérifier qu’il n’y a pas d’erreur</span>
nginx <span class="nt">-t</span>
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf <span class="nb">test </span>is successful
<span class="c"># recharger Nginx</span>
systemctl reload nginx
</code></pre></div></div>
<p>Si vous avez bien fait tout ce qu’il faut, vous pouvez accèder à votre site Commento en vous rendant,
depuis votre navigateur, sur https://commento.domaine.</p>
<h1 id="coupler-commento-sur-un-blog-statique">Coupler Commento sur un blog statique</h1>
<p>Ça y est, vous avez déployez votre nouveau service et vous vous apprêtez à prendre une pause bien
méritée. Mais ce n’est pas fini ! Il vous reste encore à créer votre compte sur ce nouveau service
et à y ajouter les informations du site sur lesquels il sera couplé pour la gestion des commentaires !</p>
<p>Vous devez d’abord ajouter un domaine en cliquant sur <strong>New domain</strong>, en bas du menu latéral gauche.
Une fenêtre pop-up s’offre vous demandant d’y indiquer le nom du site ainsi que son URL.</p>
<p>Une fois fait, vous arrivez sur une page qui vous indique un snippet (portion de code réutilisable).
C’est ce morceau de code que vous allez devoir mettre sur les différentes pages où vous souhaitez avoir
un système de commentaires. Cette portion de code ne pourra marcher que pour le site (domaine) pour
lequel il est sensé fonctionner. Vous ne pouvez pas mettre des commentaires d’un (sous-)domaine dans le
site d’un autre (sous-)domaine.</p>
<hr />
<p><em>Source de l’image d’accroche :</em> Un groupe de travail, une personne prenant des notes. Photographie de
<a href="https://pixabay.com/users/startupstockphotos-690514/" title="Voir le profil de StartupStockPhotos, sur Pixabay">StartupStockPhotos</a> sur
<a href="https://pixabay.com/" title="Visiter le site Pixabay.com">Pixabay</a></p>nororePour une idée de projet récente qui me plaît beaucoup, je me suis imposée la mise en place d’un blog statique afin de pouvoir mettre les diffénets points sur lesquels j’ai pu avancer, ceux sur lesquels je butte, et autres. Ce blog tourne sous Pelican (Python) et est couplé au moteur de commentaire Commento.io. Comme ce projet a le bon goût d’être auto-hébergeable, je l’ai déployé sur mon serveur, avec un peu d’aide de mon #chaton. Voici ma procédure, libre à vous de l’adapter par la suite.Monter rapidement un environnement pour Python2020-05-12T00:00:00+02:002020-05-12T00:00:00+02:00/2020/05/12/monter-rapidement-un-environnement-pour-python<p>J’ai eu envie de me remettre un peu à Python, parce que ça me manque un peu. Du coup, quoi de mieux
que de se lancer dans un énième projet personnel secondaire, qui finira par pourrir dans son
coin ? Sauf que, je n’ai pas non plus envie de risquer de pourrir mon système d’exploitation avec
des paquets Python dans tous les sens. Et pour couronner le tout, ma mémoire ne se souvenait plus de
comment faire un environnement virtuel en Python ! Du coup, hop, un petit billet rapide pour que
ce soit plus rapide et facile de retrouver les informations pour un projet rapide et crade !</p>
<p><strong>Information importante : mon système d’exploitation actuel est Arch Linux !</strong> Pour ce billet,
j’utilise le shell bash.</p>
<!--more-->
<h1 id="initialisation">Initialisation</h1>
<p>Par convention personnelle, je nomme mes environnements virtuels comme les projets sur lesquels je
me lance. J’ignore si c’est écrit dans une PEP (Python Enhancement Proposals), je n’en n’ai pas
l’impression, et il est tard, donc la lecture approfondie de la
<a href="https://www.python.org/dev/peps/pep-0423/" title="Lire la PEP 423 sur le site de la fondation Python, en anglais">PEP 423</a>, en langue anglaise, ça attendra un
autre jour.</p>
<p>On va commencer dans le répertoire home, en créant un répertoire dédié aux environnements virtuels
(venv) de Python, et on créé l’environnement go_explorer pour le projet du même nom :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> .venv
python3 <span class="nt">-m</span> venv .venv/go_explorer
</code></pre></div></div>
<p>On a créé un environnement virtuel (venv) que l’on va pouvoir utiliser à loisir pour ce projet.
Vérifions maintenant que tout fonctionne. Pour cela, on va créer le répertoire du projet, s’y
déplacer et sourcer le script bash qui a été généré à la création du venv.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> /chemin/go_explorer/
<span class="nb">cd</span> /chemin/go_explorer/
<span class="nb">source</span> ~/.venv/go_explorer/bin/activate
</code></pre></div></div>
<p>Pour savoir si on a bien changé le venv, on doit observer un changement dans le terminal, au niveau
de l’invite de commande.</p>
<p>Avant :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">[</span>23:41:14] norore@landscape:go_explorer<span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"Hello world!"</span>
</code></pre></div></div>
<p>Après :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">(</span>go_explorer<span class="o">)</span> <span class="o">[</span>23:48:40] norore@landscape:go_explorer<span class="nv">$ </span><span class="nb">echo</span> <span class="s2">"Hello world!"</span>
</code></pre></div></div>
<h1 id="installer-un-ou-des-paquets">Installer un ou des paquets</h1>
<p>Notre venv est prêt, on peut commencer à installer les paquets dont on va avoir besoin pour notre
projet. Pour ma part, j’aimerai travailler sur de la conception de graphes avec la proposition d’une
interface graphique. Je vais donc installer <em>networkx</em> et <em>pyside2</em>.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip <span class="nb">install</span> <span class="nt">--upgrade</span> pip
pip <span class="nb">install </span>networkx
pip <span class="nb">install </span>pyside2
</code></pre></div></div>
<p>À tout moment il est possible de connaître la liste des paquets installés dans notre venv à l’aide de
la commande suivante :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip list
Package Version
<span class="nt">----------</span> <span class="nt">--------</span>
decorator 4.4.2
networkx 2.4
pip 20.1
PySide2 5.14.2.1
setuptools 41.2.0
shiboken2 5.14.2.1
</code></pre></div></div>
<h1 id="sauver-la-liste-des-paquets">Sauver la liste des paquets</h1>
<p>Vous pourriez être amené, un jour, je vous le souhaite, de vouloir rendre votre projet disponible
afin que de gentilles personnes puissent elles aussi y contribuer. Pour cela, il va falloir que vous
puissiez leur donner la liste des paquets Python utilisés par votre projet. pip propose justement une
commande pour « geler » la liste des paquets, en les inscrivant dans un fichier :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip freeze <span class="o">></span> requirements.txt
</code></pre></div></div>
<p>À ce stade, voici ce que contient notre fichier <em>requirements.txt</em> :</p>
<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>decorator==4.4.2
networkx==2.4
PySide2==5.14.2.1
shiboken2==5.14.2.1
</code></pre></div></div>
<p>Il y a deux paquets de moins, par rapport à la liste fournie par pip list, ce sont en fait des paquets
Python fournissant les outils de base pour votre développement ! Les autres paquets, en plus de
ceux venant des commandes d’installation qui ont été exécutées plus tôt, sont, vraisemblablement, des
paquets dont les paquets d’intérêt dépendent, et que pip a installé.</p>
<p>Ainsi, pour une installation ultérieure, ou si vous souhaitez contribuer à un projet existant et
installer la liste des paquets dont vous allez avoir besoin, il vous suffit de donner le fichier
<em>requirements.txt</em> à pip :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>pip <span class="nb">install</span> <span class="nt">-r</span> requirements.txt
</code></pre></div></div>
<h1 id="quitter-lenvironnement">Quitter l’environnement</h1>
<p>Vous avez fini de travailler sur votre environnement et vous souhaitez maintenant faire autre chose,
comme interroger la météo avec votre script shell préféré, mais vous êtes bloqué dans votre venv. Pas
de panique, le script bash qui a été sourcé, activate, fourni une fonction pour quitter votre venv :</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>deactivate
</code></pre></div></div>
<p>Et c’est tout. Vous avez maintenant les bases pour vous lancer. Et ça vous aura pris moins de temps à
le faire que moi à écrire ce petit billet !</p>
<hr />
<p><em>Source de l’image d’accroche :</em> Un terrarium décoratif posé sur un meuble. Photographie de
<a href="https://unsplash.com/@maud_boc">Maud Bocquillod</a> sur
<a href="https://unsplash.com/">Unsplash</a></p>
<p><em>Sources :</em></p>
<ul>
<li>le tutoriel officiel sur venv : <a href="https://docs.python.org/fr/3/tutorial/venv.html">https://docs.python.org/fr/3/tutorial/venv.html</a></li>
<li>la documentation sur venv : <a href="https://docs.python.org/fr/3/library/venv.html">https://docs.python.org/fr/3/library/venv.html</a></li>
</ul>nororeJ’ai eu envie de me remettre un peu à Python, parce que ça me manque un peu. Du coup, quoi de mieux que de se lancer dans un énième projet personnel secondaire, qui finira par pourrir dans son coin ? Sauf que, je n’ai pas non plus envie de risquer de pourrir mon système d’exploitation avec des paquets Python dans tous les sens. Et pour couronner le tout, ma mémoire ne se souvenait plus de comment faire un environnement virtuel en Python ! Du coup, hop, un petit billet rapide pour que ce soit plus rapide et facile de retrouver les informations pour un projet rapide et crade ! Information importante : mon système d’exploitation actuel est Arch Linux ! Pour ce billet, j’utilise le shell bash.Enregistrer une image recadrée avec Symfony et Croppie.js2020-02-19T00:00:00+01:002020-02-19T00:00:00+01:00/2020/02/19/enregistrer-une-image-recadree-avec-symfony-et-croppie-js<p>Ne vous êtes-vous jamais demandé comment faire pour cadrer et sauver une image, avec de l’interactivité
pour l’utilisateur ? Après tout, la plupart des sites le font maintenant, mais le jour où ce sera à
votre tour de le faire comment vous y prendrez-vous ? C’est une question que j’ai dû me poser pour
pouvoir avoir un trombinoscope de nos étudiants, afin de ne pas avoir un serveur qui croule sous le
poids d’images en haute définition et avec des dimensions démesurées et non adaptées pour nos besoins.
Je vous propose donc de retrouver ici la solution que j’ai adopté et adapté. Comme pour le billet sur
l’internationalisation sous Symfony, le code sera surtout posé là comme une base sur laquelle vous
pourrez travailler, sans chercher à vous apprendre comment faire tout le développement !</p>
<h1 id="préparation-du-formulaire">Préparation du formulaire</h1>
<p>Dans un premier temps, il faut préparer un formulaire Symfony qui va nous permettre de récupérer le
fichier. Voici un exemple pour mon entité Individus :</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># /src/MonBundle/Form/PhotoEtudiantType.php</span>
<span class="kn">namespace</span> <span class="nn">MonBundle\Form</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Component\OptionsResolver\OptionsResolver</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Component\Form\AbstractType</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Component\Form\FormBuilderInterface</span><span class="p">;</span>
<span class="kn">use</span> <span class="nc">Symfony\Component\Form\Extension\Core\Type\FileType</span><span class="p">;</span>
<span class="kd">class</span> <span class="nc">PhotoEtudiantType</span> <span class="kd">extends</span> <span class="nc">AbstractType</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">function</span> <span class="n">buildForm</span><span class="p">(</span><span class="kt">FormBuilderInterface</span> <span class="nv">$builder</span><span class="p">,</span> <span class="kt">array</span> <span class="nv">$options</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$builder</span><span class="o">-></span><span class="nf">add</span><span class="p">(</span><span class="s1">'photo'</span><span class="p">,</span> <span class="nc">FileType</span><span class="o">::</span><span class="n">class</span><span class="p">,</span> <span class="k">array</span><span class="p">(</span>
<span class="s1">'data_class'</span> <span class="o">=></span> <span class="kc">null</span><span class="p">,</span>
<span class="s1">'label'</span> <span class="o">=></span> <span class="s1">'label.photo.etudiant'</span><span class="p">,</span>
<span class="s1">'attr'</span> <span class="o">=></span> <span class="k">array</span><span class="p">(</span>
<span class="s1">'class'</span> <span class="o">=></span> <span class="s1">'uploadPhoto'</span><span class="p">,</span>
<span class="s1">'accept'</span> <span class="o">=></span> <span class="s1">'image/*'</span><span class="p">,</span>
<span class="p">)</span>
<span class="p">));</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="n">configureOptions</span><span class="p">(</span><span class="kt">OptionsResolver</span> <span class="nv">$resolver</span><span class="p">)</span>
<span class="p">{</span>
<span class="nv">$resolver</span><span class="o">-></span><span class="nf">setDefaults</span><span class="p">(</span><span class="k">array</span><span class="p">(</span>
<span class="s1">'data_class'</span> <span class="o">=></span> <span class="s1">'MonBundle\Entity\Individus'</span><span class="p">,</span>
<span class="p">));</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">function</span> <span class="n">getBlockPrefix</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">return</span> <span class="s1">'photoetudiant'</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Pour ce formulaire, je vais avoir besoin d’ajouter une photo au niveau du champ photo pour l’entité
Individus. Comme il s’agira d’un fichier à télécharger sur le serveur, je dois utiliser la classe
FileType dans la construction du formulaire. J’en profite pour limiter le champ de formulaire au
MIME-Type image pour éviter qu’une personne mal intentionnée en profite pour essayer d’injecter du code.</p>
<h1 id="préparation-de-la-vue">Préparation de la vue</h1>
<p>La vue va me permettre deux choses :</p>
<ul>
<li>proposer un formulaire d’envoi de la photographie ;</li>
<li>afficher un aperçu de la photo en jouant avec le système de crop (découpe) du scripts Croppie.js
que j’utilise.</li>
</ul>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"><!-- /src/MonBundle/Ressources/views/PhotoEtudiant.html.twig --></span>
{{ form_start(form_etudiant) }}
{{ form_errors(form_etudiant) }}
<span class="nt"><div</span> <span class="na">align=</span><span class="s">"center"</span><span class="nt">></span>
<span class="nt"><img</span> <span class="na">id=</span><span class="s">"photo"</span>
<span class="na">src=</span><span class="s">"{{ asset('uploads/photos/' ~ etudiant.individu.photo|e) }}"</span>
<span class="na">alt=</span><span class="s">"{{ 'texte.alt.photo.etudiant'|trans(
{
'%nom%': etudiant.individu.nom,
'%prenom%': etudiant.individu.prenom
}) }}"</span><span class="nt">></span>
<span class="nt"></div></span>
{{ form_widget(form_etudiant.photo) }}
<span class="nt"><div</span> <span class="na">class=</span><span class="s">"center-block text-warning"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">id=</span><span class="s">"prev_photo"</span><span class="nt">></div></span>
<span class="nt"><p</span> <span class="na">align=</span><span class="s">"center"</span><span class="nt">></span>{{ 'p.photo.formulaire'|trans }}<span class="nt"></p></span>
<span class="nt"><img</span> <span class="na">id=</span><span class="s">"prep_photo"</span><span class="nt">></span>
<span class="nt"></div></span>
<span class="nt"><br></span>
<span class="nt"><input</span> <span class="na">type=</span><span class="s">"hidden"</span> <span class="na">id=</span><span class="s">"photocoupee"</span> <span class="na">name=</span><span class="s">"photocoupee"</span><span class="nt">></span>
<span class="nt"><div</span> <span class="na">align=</span><span class="s">"center"</span><span class="nt">></span>
<span class="nt"><input</span> <span class="na">id=</span><span class="s">"btnLoad"</span>
<span class="na">type=</span><span class="s">"submit"</span>
<span class="na">value=</span><span class="s">"{{ 'bouton.valider'|trans }}"</span><span class="nt">></span>
<span class="ni">&nbsp;</span>
<span class="nt"><a</span> <span class="na">href=</span><span class="s">"{{ path(
'vue_etudiant',
{
'id': etudiant.id
}
) }}"</span>
<span class="na">title=</span><span class="s">"{{ 'lien.fiche.etudiant'|trans(
{
'%nom%': etudiant.individu.nom,
'%prenom%': etudiant.individu.prenom
}) }}"</span><span class="nt">></span>
{{ 'bouton.annuler'|trans }}
<span class="nt"></a></span>
{{ form_end(form_etudiant) }}
<span class="nt"></div></span>
</code></pre></div></div>
<p>Comment va se comporter la page ?</p>
<ol>
<li>la première balise d’image #photo affiche la photo déjà existante ;</li>
<li>la balise <code class="language-plaintext highlighter-rouge">div</code> #prev_photo va permettre d’afficher la prévisualisation de la photo qui sera à
découper ;</li>
<li>la deuxième balise image #prep_photo va permettre d’afficher la photo telle qu’elle sera enregistrée
dans notre application ;</li>
<li>enfin, le champ caché hidden #photocoupee contiendra les informations de la photo découpée qui
seront enregistrée.</li>
</ol>
<h1 id="préparation-du-javascript">Préparation du JavaScript</h1>
<p>Ce script va vous permettre de personnaliser la façon dont Croppie.js va interagir avec vos images
(source : <a href="https://github.com/foliotek/croppie" title="Voir le code source du script Croppie.js">https://github.com/foliotek/croppie</a>).</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// /src/MonBundle/Ressources/public/js/ajustement_photo.js</span>
<span class="kd">var</span> <span class="nx">uploadCrop</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#prev_photo</span><span class="dl">'</span><span class="p">).</span><span class="nx">croppie</span><span class="p">({</span>
<span class="na">enableExif</span><span class="p">:</span> <span class="kc">true</span><span class="p">,</span>
<span class="na">viewport</span><span class="p">:</span> <span class="p">{</span>
<span class="na">width</span><span class="p">:</span> <span class="mi">300</span><span class="p">,</span>
<span class="na">height</span><span class="p">:</span> <span class="mi">400</span>
<span class="p">},</span>
<span class="na">boundary</span><span class="p">:</span> <span class="p">{</span>
<span class="na">width</span><span class="p">:</span> <span class="mi">400</span><span class="p">,</span>
<span class="na">height</span><span class="p">:</span> <span class="mi">400</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#photoetudiant_photo</span><span class="dl">'</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">change</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">input</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">)[</span><span class="mi">0</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">files</span> <span class="o">&&</span> <span class="nx">input</span><span class="p">.</span><span class="nx">files</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">reader</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FileReader</span><span class="p">();</span>
<span class="nx">reader</span><span class="p">.</span><span class="nx">onload</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">uploadCrop</span><span class="p">.</span><span class="nx">croppie</span><span class="p">(</span><span class="dl">'</span><span class="s1">bind</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
<span class="na">url</span><span class="p">:</span> <span class="nx">e</span><span class="p">.</span><span class="nx">target</span><span class="p">.</span><span class="nx">result</span>
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">jQuery bind complete</span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="nx">reader</span><span class="p">.</span><span class="nx">readAsDataURL</span><span class="p">(</span><span class="nx">input</span><span class="p">.</span><span class="nx">files</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="nx">alert</span><span class="p">(</span><span class="dl">"</span><span class="s2">Sorry - you're browser doesn't support the FileReader API</span><span class="dl">"</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="kd">function</span> <span class="nx">showResult</span><span class="p">(</span><span class="nx">result</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">src</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">img</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">src</span><span class="p">;</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#prep_photo</span><span class="dl">'</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="dl">'</span><span class="s1">src</span><span class="dl">'</span><span class="p">,</span> <span class="nx">img</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">blob</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">img</span> <span class="o">=</span> <span class="nx">result</span><span class="p">.</span><span class="nx">blob</span><span class="p">;</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#photocoupee</span><span class="dl">'</span><span class="p">).</span><span class="nx">attr</span><span class="p">(</span><span class="dl">'</span><span class="s1">value</span><span class="dl">'</span><span class="p">,</span> <span class="nx">img</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#prev_photo</span><span class="dl">'</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">update.croppie</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">ev</span><span class="p">,</span> <span class="nx">cropData</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">uploadCrop</span><span class="p">.</span><span class="nx">croppie</span><span class="p">(</span><span class="dl">'</span><span class="s1">result</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
<span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">canvas</span><span class="dl">'</span><span class="p">,</span>
<span class="na">size</span><span class="p">:</span> <span class="dl">'</span><span class="s1">viewport</span><span class="dl">'</span><span class="p">,</span>
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">showResult</span><span class="p">({</span><span class="na">src</span><span class="p">:</span> <span class="nx">value</span><span class="p">});</span>
<span class="p">});</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#prev_photo</span><span class="dl">'</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">update.croppie</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">ev</span><span class="p">,</span> <span class="nx">cropData</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">uploadCrop</span><span class="p">.</span><span class="nx">croppie</span><span class="p">(</span><span class="dl">'</span><span class="s1">result</span><span class="dl">'</span><span class="p">,</span> <span class="p">{</span>
<span class="na">type</span><span class="p">:</span> <span class="dl">'</span><span class="s1">canvas</span><span class="dl">'</span><span class="p">,</span>
<span class="na">size</span><span class="p">:</span> <span class="dl">'</span><span class="s1">viewport</span><span class="dl">'</span><span class="p">,</span>
<span class="p">}).</span><span class="nx">then</span><span class="p">(</span><span class="kd">function</span> <span class="p">(</span><span class="nx">value</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">showResult</span><span class="p">({</span><span class="na">blob</span><span class="p">:</span> <span class="nx">value</span><span class="p">});</span>
<span class="p">});</span>
<span class="p">});</span>
</code></pre></div></div>
<p>OK, ça fait un gros pavé de code JavaScript pas forcément très simple à comprendre ou à appréhender.
Voyons ensemble quelle est la logique derrière pour que vous puissiez reproduire ou améliorer ça sur
vos projets.</p>
<p>Dans un premier temps, nous définissons la variable uploadCrop qui va nous permettre de définir, dans
la balise image #prev_photo le cadre qui va recevoir l’image à afficher dans les dimensions définies
par boundary, mais également une fenêtre d’aperçu du découpage de la photo dans les dimensions définies
par viewport. Le cadre du viewport pourra aussi être déplacé à l’aide de la souris pour ajuster la zone
qui sera à découper.</p>
<p>Ensuite, on regarde au niveau du formulaire si une photo va être envoyée par l’utilisateur par le biais
de la variable $(‘#photoetudiant_photo’). On vérifie que le navigateur supporte l’API JavaScript pour
lire le fichier, et si c’est le cas, on demande à Croppie de lier l’image à la variable uploadCrop, afin
de pouvoir continuer à interagir avec elle.</p>
<p>La fonction showResult sera appelée par interaction avec la balise #prev_photo et permettra deux
choses :</p>
<ol>
<li>afficher l’aperçu de la photo prédécoupée dans la balise image #prep_photo ;</li>
<li>envoyer les données sur la photo prédécoupée au champ caché hidden #photocoupee.</li>
</ol>
<h1 id="ajout-de-linteraction-avec-javascript">Ajout de l’interaction avec JavaScript</h1>
<p>Pour commencer, téléchargez Croppie.js et déposez-le dans le répertoire idoine de votre projet. Puis
appelez-le entre les balises head de votre application pour pré-charger ses fonctions. Une fois ceci
fait, il vous restera à appeler votre fonction de découpage ajustement_photo.js en insérant ce bout de
code juste avant la fermeture de la balise body :</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><script </span><span class="na">type=</span><span class="s">"text/javascript"</span>
<span class="na">src=</span><span class="s">"{{ asset('bundles/monbundle/js/ajustement_photo.js') }}"</span><span class="nt">></span>
<span class="nt"></script></span>
</code></pre></div></div>
<h1 id="récupération-de-la-photo-recadrée">Récupération de la photo recadrée</h1>
<p>On y est presque, c’est la dernière étape, courage !</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># /src/MonBundle/Controller/PhotoEtudiantController.php</span>
<span class="k">if</span> <span class="p">(</span><span class="nv">$form_etudiant</span><span class="o">-></span><span class="nf">isSubmitted</span><span class="p">()</span> <span class="o">&&</span>
<span class="nv">$form_etudiant</span><span class="o">-></span><span class="nf">isValid</span><span class="p">())</span> <span class="p">{</span>
<span class="nv">$file</span> <span class="o">=</span> <span class="nv">$individu</span><span class="o">-></span><span class="nf">getPhoto</span><span class="p">();</span>
<span class="nv">$base64</span> <span class="o">=</span> <span class="nv">$request</span><span class="o">-></span><span class="n">request</span><span class="o">-></span><span class="nf">get</span><span class="p">(</span><span class="s1">'photocoupee'</span><span class="p">);</span>
<span class="k">list</span><span class="p">(</span><span class="nv">$type</span><span class="p">,</span> <span class="nv">$data</span><span class="p">)</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">';'</span><span class="p">,</span> <span class="nv">$base64</span><span class="p">);</span>
<span class="k">list</span><span class="p">(,</span> <span class="nv">$data</span><span class="p">)</span> <span class="o">=</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">','</span><span class="p">,</span> <span class="nv">$base64</span><span class="p">);</span>
<span class="nv">$data</span> <span class="o">=</span> <span class="nb">base64_decode</span><span class="p">(</span><span class="nv">$data</span><span class="p">);</span>
<span class="nv">$getFlashBag</span> <span class="o">=</span> <span class="nv">$request</span><span class="o">-></span><span class="nf">getSession</span><span class="p">()</span><span class="o">-></span><span class="nf">getFlashBag</span><span class="p">();</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'/image\/.*/'</span><span class="p">,</span> <span class="nv">$file</span><span class="o">-></span><span class="nf">getClientMimeType</span><span class="p">()))</span> <span class="p">{</span>
<span class="nv">$getFlashBag</span><span class="o">-></span><span class="nf">add</span><span class="p">(</span>
<span class="s1">'danger'</span><span class="p">,</span>
<span class="s1">'Le fichier doit être une image !'</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'/^data:image\/(\w+);base64,/'</span><span class="p">,</span> <span class="nv">$base64</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$getFlashBag</span><span class="o">-></span><span class="nf">add</span><span class="p">(</span>
<span class="s1">'danger'</span><span class="p">,</span>
<span class="s1">'Les données transmises doivent avoir le bon MIME-Type !'</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'/jpg$/i'</span><span class="p">,</span> <span class="nv">$type</span><span class="p">)</span> <span class="k">and</span>
<span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'/jpeg$/i'</span><span class="p">,</span> <span class="nv">$type</span><span class="p">)</span> <span class="k">and</span>
<span class="o">!</span><span class="nb">preg_match</span><span class="p">(</span><span class="s1">'/png$/i'</span><span class="p">,</span> <span class="nv">$type</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$getFlashBag</span><span class="o">-></span><span class="nf">add</span><span class="p">(</span>
<span class="s1">'danger'</span><span class="p">,</span>
<span class="s1">'Le fichier doit être une image JPEG ou PNG !'</span> <span class="mf">.</span> <span class="nv">$type</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="k">try</span> <span class="p">{</span>
<span class="nv">$fileName</span> <span class="o">=</span> <span class="nb">md5</span><span class="p">(</span><span class="nb">uniqid</span><span class="p">())</span> <span class="mf">.</span> <span class="s1">'.'</span> <span class="mf">.</span> <span class="nb">explode</span><span class="p">(</span><span class="s1">'/'</span><span class="p">,</span> <span class="nv">$type</span><span class="p">)[</span><span class="mi">1</span><span class="p">];</span>
<span class="nb">file_put_contents</span><span class="p">(</span>
<span class="nv">$this</span><span class="o">-></span><span class="nf">getParameter</span><span class="p">(</span><span class="s1">'photos_directory'</span><span class="p">)</span><span class="mf">.</span><span class="s1">'/'</span><span class="mf">.</span><span class="nv">$fileName</span><span class="p">,</span>
<span class="nv">$data</span>
<span class="p">);</span>
<span class="nv">$individu</span><span class="o">-></span><span class="nf">setPhoto</span><span class="p">(</span><span class="nv">$fileName</span><span class="p">);</span>
<span class="nv">$em</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-></span><span class="nf">getDoctrine</span><span class="p">()</span><span class="o">-></span><span class="nf">getManager</span><span class="p">();</span>
<span class="nv">$em</span><span class="o">-></span><span class="nf">persist</span><span class="p">(</span><span class="nv">$individu</span><span class="p">);</span>
<span class="nv">$em</span><span class="o">-></span><span class="nb">flush</span><span class="p">();</span>
<span class="nv">$getFlashBag</span><span class="o">-></span><span class="nf">add</span><span class="p">(</span>
<span class="s1">'success'</span><span class="p">,</span>
<span class="s1">'Photo enregistrée.'</span>
<span class="p">);</span>
<span class="k">return</span> <span class="nv">$this</span><span class="o">-></span><span class="nf">redirectToRoute</span><span class="p">(</span>
<span class="s1">'scolarite_biologie_view'</span><span class="p">,</span>
<span class="k">array</span><span class="p">(</span>
<span class="s1">'etudiant'</span> <span class="o">=></span> <span class="nv">$etudiant</span>
<span class="p">)</span>
<span class="p">);</span>
<span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">Exception</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
<span class="nv">$msg</span> <span class="o">=</span> <span class="s2">"L'exception suivante vient d'avoir lieu :<br>"</span><span class="p">;</span>
<span class="nv">$msg</span> <span class="mf">.</span><span class="o">=</span> <span class="s2">"<pre>"</span> <span class="mf">.</span> <span class="nv">$e</span><span class="o">-></span><span class="nf">getMessage</span><span class="p">()</span> <span class="mf">.</span> <span class="s2">"</pre><br>"</span><span class="p">;</span>
<span class="nv">$msg</span> <span class="mf">.</span><span class="o">=</span> <span class="s2">"Si l'exception persiste, merci d'en informer les administrateurs."</span><span class="p">;</span>
<span class="nv">$getFlashBag</span><span class="o">-></span><span class="nf">add</span><span class="p">(</span>
<span class="s1">'warning'</span><span class="p">,</span>
<span class="nv">$msg</span>
<span class="p">);</span>
<span class="nv">$getFlashBag</span><span class="o">-></span><span class="nf">add</span><span class="p">(</span>
<span class="s1">'alert'</span><span class="p">,</span>
<span class="s2">"La photo n'a pas pu être enregistrée"</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Encore un pavé ? Oui, mais un pavé utile. C’est lui va nous permettre de récupérer la photo découpée
par Croppie.js et de l’envoyer sur le serveur ! Décortiquons un peu cette portion pour mieux
comprendre sa logique.</p>
<p>Une fois que le formulaire a été soumis et que celui-ci est validé, nous allons dans un premier temps
récupérer :</p>
<ul>
<li>le fichier $file renseigné dans l’entité Individus <em>via</em> le formulaire ;</li>
<li>la photo découpée par Croppie.js, <em>via</em> la variable d’environnement Request (cf. la documentation
officielle) dans la variable $base64 ;</li>
<li>le type de fichier $type et les données $data en éclatant la chaîne de caractères contenue dans
$base64 en se basant sur le point-virgule ‘;’ ;</li>
<li>les données $data de la photo en éclatant la chaîne de caractères $data en se basant sur la virgule
‘,’ ;</li>
<li>les données $data en décodant les données qui sont encodées en base 64 à l’aide de la fonction
base64_decode().</li>
</ul>
<p>À partir de là, on effectue différentes vérifications :</p>
<ul>
<li>Est-ce que le MIME-Type de $fichier est bien de type image ?</li>
<li>Est-ce que la variable $base64 commence bien par la chaîne de caractères data:image et est bien
en base 64 ?</li>
<li>Est-ce que le type de $type est bien du JPEG ou du PNG ?</li>
</ul>
<p>Si on a répondu oui à chacune de ces trois questions, on peut enregistrer notre image sur le serveur.</p>
<p>On définit le nom du fichier dans la variable $fileName, dans mon cas, nous avons choisi de mettre un
nom aléatoire à l’aide de la fonction md5(), vous pouvez choisir n’importe quel autre nom, sans
oublier de préciser l’extension du fichier contenu dans la variable $type.</p>
<p>On utilise la fonction file_put_contents() pour créer le fichier $fileName dans le répertoire
idoine à l’aide des données $data.</p>
<p>Enfin, on met à jour notre Individus au niveau du champ Photo avec le nom du fichier $fileName, et on
n’oublie pas de committer avec flush() !</p>
<p>Il ne vous reste plus qu’à faire vos propres essais. Il existe sûrement d’autres approches et d’autres
stratégies, mais c’est celle que j’ai mis en place il y a… Pfou, plus d’un an et demi ?</p>
<p>N’hésitez pas à me faire d’autres suggestions de stratégie pour d’éventuels futurs projets, et en
attendant : Bon code !</p>
<hr />
<p><em>Source de l’image d’accroche :</em> Un tas de papier découpé à l’emporte-pièce rond. Photographié par
<a href="https://pixabay.com/users/Monsterkoi-65294/" title="Voir le profil de Monsterkoi sur Pixabay">Monsterkoi</a>, sous licence Pixabay sur <a href="https://pixabay.com/">Pixabay</a></p>nororeNe vous êtes-vous jamais demandé comment faire pour cadrer et sauver une image, avec de l’interactivité pour l’utilisateur ? Après tout, la plupart des sites le font maintenant, mais le jour où ce sera à votre tour de le faire comment vous y prendrez-vous ? C’est une question que j’ai dû me poser pour pouvoir avoir un trombinoscope de nos étudiants, afin de ne pas avoir un serveur qui croule sous le poids d’images en haute définition et avec des dimensions démesurées et non adaptées pour nos besoins. Je vous propose donc de retrouver ici la solution que j’ai adopté et adapté. Comme pour le billet sur l’internationalisation sous Symfony, le code sera surtout posé là comme une base sur laquelle vous pourrez travailler, sans chercher à vous apprendre comment faire tout le développement !Quelques outils de travail2020-01-14T00:00:00+01:002020-01-14T00:00:00+01:00/2020/01/14/quelques-outils-de-travail<p>Pour ceux qui ont suivi ma trépidante carrière, je suis actuellement développeuse d’application dans
un institut de biologie, au sein de sa plateforme informatique. En tant que développeuse, j’utilise
différents outils pour faire mes différents programmes. Dans ce billet, je vous propose de passer en
revue quelques outils, peut-être que ça pourra aider de jeunes développeuses et développeurs à tester
et se lancer ?</p>
<h1 id="une-question-de-langage">Une question de langage</h1>
<p>Qui dit développement, dit programmation et donc, langage. Les gens qui me connaissent savent que je
suis un peu touche-à-tout et que je n’hésite pas non plus à apprendre de nouveaux langages ou de
nouvelles méthodes. Mais avant d’utiliser tel ou tel langage, il faut surtout se poser la question
suivante : ce langage me permet-il de répondre à mon besoin et est-il pertinent de l’utiliser ?</p>
<h2 id="bash-bourne-again-shell">Bash (Bourne-again shell)</h2>
<p><img src="/assets/img/posts/2020-01-14/bash.png" alt="Logo officiel de Bash, The Bourne-Again Shell" width="150px" class="float-left" /></p>
<p>Je travaille essentiellement sous GNU/Linux, ou équivalent. Même pendant mon premier emploi, bien
qu’étant sur un poste informatique avec Windows Seven, je travaillais majoritairement sur les serveurs
sous <a href="http://ubuntu-fr.org/" title="Visiter le site de l’association Ubunt-fr, sur le système d’exploitation Ubuntu">Ubuntu</a>. Par conséquent,
il a bien fallu que je sois capable de réaliser des petits scripts rapides pour des analyses de
fichiers, voire plus. Par conséquent, je ne peux que vous recommander d’apprendre le langage console
de votre système d’exploitation de base !</p>
<h3 id="les-plus">Les plus</h3>
<ul>
<li>Utilise les commandes natives du système</li>
<li>De nombreuses options de vérification du type de fichier intégrées</li>
<li>Possibilité de faire du bash en uniligne</li>
<li>Possibilité de créer des scripts et de les automatiser facilement et rapidement <em>via</em> une
tâche <a href="https://fr.wikipedia.org/wiki/Cron" title="Voir la page Wikipédia sur CRON">CRON</a></li>
</ul>
<h3 id="les-moins">Les moins</h3>
<ul>
<li>Proche du système, si vous n’êtes pas un minimum à l’aise avec la ligne de commande, vous risquez
de souffrir un peu au début</li>
<li>La gestion des scripts avec arguments est délicate à aborder</li>
</ul>
<h3 id="pour-aller-plus-loin">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) :
<a href="https://www.gnu.org/software/bash/">https://www.gnu.org/software/bash/</a></li>
<li>Documentation officielle (en anglais) :
<a href="https://www.gnu.org/software/bash/manual/html_node/index.html">https://www.gnu.org/software/bash/manual/html_node/index.html</a></li>
</ul>
<h2 id="perl">Perl</h2>
<p><img src="/assets/img/posts/2020-01-14/perl.png" alt="Logo officiel de Perl" width="100px" class="float-right" /></p>
<p>Étant bioinformaticienne de formation, je peux être amenée à manipuler des fichiers textes de
différents formats et avec différents formatages, vous n’avez pas idée du nombre de formats VCF
(Variant Call Format, un format de fichier spécifique en génétique) différents. Autant Bash peut me
permettre d’effectuer des analyses et des extractions rapides, autant Perl peut vraiment sortir du lot
pour ce qui est du traitement de fichier par lots et avec tout un tas de tests d’expressions régulières
à effectuer. Même si sed et awk sont très performants, il se peut que vous soyez un jour bloqué par
leurs limitations : pensez-y si vous manquez de temps !</p>
<p>Perl est un langage qui peut s’apprendre très vite et peut s’écrire de mille et une façons différentes.
C’est ce qui en fait sa force et son défaut. Ceux qui sont passés derrière le script d’un biologiste
ayant codé sur son coin de paillasse savent de quoi je parle.</p>
<h3 id="les-plus-1">Les plus</h3>
<ul>
<li>Très versatile</li>
<li>Une large communauté de mongueurs avec beaucoup de pragmas (package Perl, si je ne dis pas de bêtise)
existants</li>
<li>Idéal pour le traitement de gros fichiers</li>
<li>Pensé initialement pour être une extension de la commande sed, il est maintenant un des, voire le,
plus puissant langage d’expression régulière</li>
</ul>
<h3 id="les-moins-1">Les moins</h3>
<ul>
<li>Très versatile (<em>bis repetita</em>)</li>
<li>Il existe autant de façons de faire un script Perl qu’il existe de développeurs, il peut parfois
être délicat de reprendre de vieux scripts écrits sur un coin de table</li>
<li>La notion de programmation orientée objet est assez floue voire obscure, au moins pour la version
5, pour le peu que j’ai pu en faire, n’ayant pas encore eu l’occasion de tester la version 6</li>
</ul>
<h3 id="pour-aller-plus-loin-1">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) : <a href="https://www.perl.org/">https://www.perl.org/</a></li>
<li>La documentation officielle (en anglais) : <a href="https://perldoc.perl.org/">https://perldoc.perl.org/</a></li>
<li>Meta-CPAN, pour trouver tous les pragmas dont vous pouvez avoir besoin (en anglais) :
<a href="https://metacpan.org/">https://metacpan.org/</a></li>
</ul>
<h2 id="python">Python</h2>
<p><img src="/assets/img/posts/2020-01-14/python.png" alt="Logo officiel de Python" width="150px" class="float-left" /></p>
<p>Je ne peux pas parler de bioinformatique, de Perl, et passer à côté de Python. Ça ne se fait pas ! Bien que cela
fasse deux ans que je n’ai pas touché une ligne de code de ce langage, il reste un de mes outils préférés. Il peut
même être utilisé en complément de Perl. Le gros avantage de Python, c’est qu’il a une grosse communauté scientifique
qui produit beaucoup de modules ! Il est recommandé et de plus en plus utilisé pour le calcul scientifique,
notamment pour tout ce qui est intelligence artificielle et <em>blockchain</em>, puisque ce sont les termes à
la mode du moment.</p>
<h3 id="les-plus-2">Les plus</h3>
<ul>
<li>La simplicité de sa syntaxe</li>
<li>Très répandu dans le milieu scientifique</li>
<li>De très nombreux modules</li>
<li>Depuis la version 3, facilité de créer un <em>virtualenv</em> sans devoir passer par des outils tiers</li>
</ul>
<h3 id="les-moins-2">Les moins</h3>
<ul>
<li>Sa capacité à déstabiliser un système GNU/Linux si on ne fait pas attention aux modules installés
et désinstallés : toujours prendre le réflexe de faire un <em>virtualenv</em> par projet !</li>
<li>L’indentation forcée qui peut être rebutante au départ et peut occasionner des erreurs inattendues
si on est distrait</li>
</ul>
<h3 id="pour-aller-plus-loin-2">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) : <a href="https://www.python.org/">https://www.python.org/</a></li>
<li>Documentation officielle : <a href="https://docs.python.org/fr/3/">https://docs.python.org/fr/3/</a></li>
<li><strong>LE</strong> livre de référence (en anglais) :
<a href="https://diveintopython3.problemsolving.io/">https://diveintopython3.problemsolving.io/</a></li>
</ul>
<h2 id="php">PHP</h2>
<p><img src="/assets/img/posts/2020-01-14/php.tb.png" alt="Logo officiel de PHP" width="100px" class="float-right" /></p>
<p>Depuis deux ans je fais de nouveau du PHP. Le manuel de
PHP est toujours une bible pour qui se retrouve bloqué, et de nombreux commentaires émaillent chaque
page de la documentation, ce qui est un excellent point de départ si vous devez réaliser une application
web plus ou moins modeste. L’avantage c’est que vous gardez la maîtrise du langage, quoi qu’il arrive.</p>
<h3 id="les-plus-3">Les plus</h3>
<ul>
<li>Un des langages web les plus supportés sur la plupart des offres d’hébergement</li>
<li>De nombreuses fonctionnalités activables ou non sur le serveur en fonction des besoins</li>
</ul>
<h3 id="les-moins-3">Les moins</h3>
<ul>
<li>La lourdeur de sa programmation orientée objet</li>
<li>Pas de système de gestion de paquets natif, il faut passer par un outil tiers comme Composer pour
utiliser des bundles (paquet) existants</li>
</ul>
<h3 id="pour-aller-plus-loin-3">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) : <a href="https://www.php.net/">https://www.php.net/</a></li>
<li>Le manuel officiel : <a href="https://www.php.net/manual/fr/">https://www.php.net/manual/fr/</a></li>
</ul>
<h2 id="symfony">Symfony</h2>
<p><img src="/assets/img/posts/2020-01-14/symfony.png" alt="Logo officiel du framework PHP Symfony" width="150px" class="float-left" /></p>
<p>J’ai aussi dû me mettre à
<a href="https://symfony.com/" title="Voir le site officiel du framework Symfony pour PHP, en anglais">Symfony</a>
pour finir reprendre un projet terminé à 80% fini à la rache (non certifiée) façon démo. Si vous vous
lancez dans une application web qui sera amenée à évoluer et à grossir, tournez-vous plutôt du côté de
Symfony et des nombreux bundle (ou package) déjà existants. La communauté semble riche et active et
j’ai rarement été réellement dans la panade, même si j’ai parfois dû me creuser les méninges pour
réussir à faire un truc ou deux qui ne sont, de toute façon, pas forcément triviaux.</p>
<h3 id="les-plus-4">Les plus</h3>
<ul>
<li>Des mises à jour fréquentes et régulières du framework, mine de rien, ça compte niveau sécurité</li>
<li>Une documentation en ligne disponible et accessible (même s’il faut accepter certains domaines tiers si vous utilisez uMatrix)</li>
<li>De très nombreux bundles, fournis par la communauté</li>
<li>On peut faire du vrai MVC en PHP, sans devoir tout coder</li>
</ul>
<h3 id="les-moins-4">Les moins</h3>
<ul>
<li>Certaines fonctionnalités manquent parfois d’explications quant à leur utilisation (ingénierie inverse, bonjour !)</li>
<li>Il faut maîtriser aussi bien Symfony que <a href="https://www.doctrine-project.org/" title="Visiter le site officiel de l’ORM Doctrine, en anglais">Doctrine</a> et <a href="https://twig.symfony.com/" title="Visiter le site officiel du moteur de template Twig pour Symfony, en anglais">Twig</a>, respectivement un
ORM (outil pour faciliter l’interaction avec la base de données) et un moteur de template
(ou squelette de la page à afficher), non natifs mais importés par défaut, ce qui alourdit parfois la
recherche de documentation</li>
</ul>
<h3 id="pour-aller-plus-loin-4">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) : <a href="https://symfony.com/">https://symfony.com/</a></li>
<li>La documentation officielle (en anglais) :
<a href="https://symfony.com/doc/current/index.html#gsc.tab=0">https://symfony.com/doc/current/index.html#gsc.tab=0</a></li>
</ul>
<h2 id="ruby-on-rails">Ruby-On-Rails</h2>
<p><img src="/assets/img/posts/2020-01-14/rails.tb.png" alt="Logo officiel du framework Ruby Ruby-On-Rails" width="150px" class="float-right" /></p>
<p>Ne hurlez pas ! Non, Ruby-On-Rails n’est pas un langage, c’est un framework web. Mais il s’agit d’un framework pour le
langage <a href="https://www.ruby-lang.org/fr/" title="Visiter le site officiel de Ruby">Ruby</a>.</p>
<p>Connaissant déjà <a href="https://www.djangoproject.com/" title="Visiter le site officiel du projet Django, en anglais">Django</a> (framework Python) et Symfony (framework
PHP), j’ai été surprise par ma vitesse d’apprentissage et la facilité déconcertante avec laquelle j’ai
pu faire un premier jet rapide pour un projet.</p>
<p>Si vous avez besoin de réaliser rapidement une application web, et que vous êtes adepte du MVC, vous
serez plus que comblé. Le système de gem (package) de Ruby permet d’avoir rapidement les outils
nécessaires pour la construction d’un espace utilisateur, par exemple. Si vous devez interagir avec un
LDAP, un système d’annuaire informatique, je vous recommande chaudement Devise !</p>
<p>La documentation de Ruby-On-Rails est bien faite, vous pourrez, en moins d’une journée de travail,
comprendre comment faire une migration et des vues, pour faire un petit site de type blog, sans espace
utilisateur toutefois. Le tutoriel est vraiment bien fait et vous ne serez pas frustré quand vous vous
lancerez dans votre propre projet.</p>
<p>Pour le déploiement, tournez-vous du côté de puma et suivez le guide !</p>
<h3 id="les-plus-5">Les plus</h3>
<ul>
<li>Guide bien rédigé, vous serez rarement bloqué longtemps</li>
<li>Une bonne communauté de développeurs, de nombreux bundle existant pour couvrir l’ensemble des
besoins avancés</li>
</ul>
<h3 id="les-moins-5">Les moins</h3>
<ul>
<li>Peut ne pas être installé par défaut chez votre hébergeur préféré</li>
<li>Il peut être tentant d’installer plein de bundles, pensez bien votre projet avant d’en installer
qui pourraient faire de la redondance</li>
</ul>
<h3 id="pour-aller-plus-loin-5">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) : <a href="https://rubyonrails.org/">https://rubyonrails.org/</a></li>
<li>Les guides officiels (en anglais) : <a href="https://guides.rubyonrails.org/">https://guides.rubyonrails.org/</a></li>
<li>La documentation officielle (en anglais) : <a href="https://api.rubyonrails.org/">https://api.rubyonrails.org/</a></li>
</ul>
<h2 id="html-css-et-javascriptjquery">HTML, CSS et JavaScript/jQuery</h2>
<p><img src="/assets/img/posts/2020-01-14/html5.png" alt="Logo officiel de HTML5" width="50px" class="float-left" />
<img src="/assets/img/posts/2020-01-14/css3.png" alt="Logo officiel de CSS3" width="50px" class="float-left" />
<img src="/assets/img/posts/2020-01-14/javascript.png" alt="Logo officiel de Javascript" width="50px" class="float-left" />
<img src="/assets/img/posts/2020-01-14/jquery.png" alt="Logo officiel de jQuery" width="50px" class="float-left" /></p>
<p>Qui dit framework web dit, forcément, interface web. Étant donné que je travaille seul·e sur la
majorité de mes projets, je dois faire aussi bien du back que du front. Certes, ça veut dire que je
ne suis experte ni en back, ni en front, mais je dois tout de même être capable d’afficher les données
aux utilisateurs.</p>
<p>HTML et CSS sont très utiles pour ce qui est de l’affichage statique pur des données, tandis que
JavaScript (à l’aide du framework jQuery) va avoir surtout une utilité d’affichage dynamique. Une
portion de la page ne doit s’afficher que si une certaine condition est remplie ? Plutôt que de
forcer l’utilisateur à recharger la page à chaque fois, vous pouvez passer par du JavaScript pour
faire ça dynamiquement ! Et s’il y a du post-traitement à faire, laissez faire le back
(Ruby-On-Rails ou Symfony).</p>
<h3 id="les-plus-6">Les plus</h3>
<ul>
<li>Séparation du fond (HTML) de la forme (CSS) depuis des années, forte robustesse des deux langages</li>
<li>Possibilité de créer de l’interaction cliente avec JavaScript, pour pallier les limitations de
HTML et CSS</li>
<li>HTML et CSS sont des standards du web</li>
<li>Accessibilité pour les aveugles et mal voyants</li>
</ul>
<h3 id="les-moins-6">Les moins</h3>
<ul>
<li>Tous les navigateurs ne respectent pas les normes établies par le W3C</li>
<li>Apprentissage du CSS parfois délicat quand on veut faire des choses plus poussées</li>
<li>Possibilité de détériorer l’expérience utilisateur si trop de JavaScript sur la page, certaines
personnes bloquent le JS, et certains scripts cassent l’accessibilité, donc point trop n’en faut</li>
</ul>
<h3 id="pour-aller-plus-loin-6">Pour aller plus loin</h3>
<ul>
<li>Les tutoriels du W3Schools (en anglais) : <a href="https://www.w3schools.com/default.asp">https://www.w3schools.com/default.asp</a></li>
<li>Les tutoriels jQuery officiels (en anglais) : <a href="https://learn.jquery.com/">https://learn.jquery.com/</a></li>
<li>D’autres tutoriels, une fois les bases maîtrisées, chez Alsacreations : <a href="https://www.alsacreations.com/tutoriels/">https://www.alsacreations.com/tutoriels/</a></li>
</ul>
<h1 id="édition-de-code-source">Édition de code source</h1>
<h2 id="atomio">Atom.io</h2>
<p><img src="/assets/img/posts/2020-01-14/atom.png" alt="Logo officiel d’Atom.io" width="100px" class="float-left" /></p>
<p>L’éditeur de texte de GitHub. Il se veut une alternative libre au très connu
<a href="https://www.sublimetext.com/" title="Visiter le site officiel de l’éditeur de texte Sublime Text, en anglais">Sublime Text</a>. Le seul reproche que
l’on pourrait faire c’est qu’il ne semble pas être packagé pour GNU/Linux, du coup, il vous faudra
passer par le site officiel si vous souhaitez l’utiliser. Dans l’ensemble, que vous soyez sous Mac,
GNU/Linux, ou même encore Windows, vous trouverez un installateur sur le site officiel.</p>
<p>Atom.io de base est agréable au premier coup d’œil et il vous permettra de rapidement commencer à
travailler. Si vous trouvez qu’il lui manque une fonctionnalité ou deux, vous pouvez passer par le
menu des extensions pour trouver votre bonheur auprès des outils mis à la disposition par la
communauté. C’est une des fonctionnalités que j’ai trouvé des plus pratiques et agréables à prendre
en main. Ça, et le raccourci clavier pour la visualisation en direct des fichiers au format
<a href="https://fr.wikipedia.org/wiki/Markdown" title="Voir la page Wikipédia sur MarkDown">MarkDown</a> !</p>
<p>Seule véritable ombre au tableau : il est développé sous <a href="https://electronjs.org/" title="Visiter le site officiel d’Electron, en français ou en anglais selon les paramètres de votre
navigateur">Electron</a> (JavaScript), ce qui fait qu’il est plutôt long à lancer, mais c’est aussi ce qui en
fait un outil multi-plateforme largement recommandé.</p>
<h3 id="les-plus-7">Les plus</h3>
<ul>
<li>Une fenêtre de vue plus agréable à l’œil pour le MarkDown, intégrée nativement</li>
<li>Une bibliothèque de greffons intégrée, facile d’utilisation</li>
<li>Multi-plateforme</li>
</ul>
<h3 id="les-moins-7">Les moins</h3>
<ul>
<li>Lenteur au démarrage (merci Electron)</li>
<li>Pas packagé par la communauté Linux, il faut récupérer le <code class="language-plaintext highlighter-rouge">.deb</code> ou le <code class="language-plaintext highlighter-rouge">.rpm</code> pour pouvoir
l’installer et le mettre à jour.</li>
</ul>
<h3 id="pour-aller-plus-loin-7">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) : <a href="https://atom.io/">https://atom.io/</a></li>
<li>La documentation ou livre de bord (en anglais, traduction approximative) :
<a href="https://flight-manual.atom.io/">https://flight-manual.atom.io/</a></li>
</ul>
<h2 id="vim">vim</h2>
<p><img src="/assets/img/posts/2020-01-14/vim.tb.png" alt="Logo officiel de vim" width="100px" class="float-left" /></p>
<p>Un éditeur qui fait peur, surtout quand on débute sous Linux. Anecdote et instant confidence !</p>
<p>La première fois que j’ai fait un git commit, je me suis retrouvée sur une fenêtre que je ne
connaissais pas, je ne savais pas comment en sortir. Ah, si, en tuant le terminal… Non, le vrai
jour où j’ai dû sortir de ma zone de confort c’est quand je devais coder à distance sur un serveur
qui ne permettait pas de connexion SSH en mode graphique ! Du coup, mes deux ans à me dépatouiller
tant bien que mal sous <a href="https://fr.wikipedia.org/wiki/Emacs" title="Visiter la page Wikipédia sur
Emacs">Emacs</a>, envolées. J’ai pris une petite heure chez moi le soir, j’ai tapé vim tutor dans mon terminal,
et j’ai suivi les explications. C’était il y a plus de huit ans, et je l’utilise désormais
quotidiennement depuis plusieurs mois.</p>
<p>C’est un éditeur de texte qui se veut léger, multiplate-forme et personnalisable. Il propose de très
nombreuses options et fonctionnalités qui peuvent être utilisées ou non, les fonctionnalités de base
étant passées en revue dans le tutoriel et couvrant généralement la plupart des cas d’utilisation. Il
est également possible de couper sa fenêtre en deux zones tampons (:split et :vsplit, utiliser CRL+W
et une flèche directionnelle pour changer de tampon) ou de travailler sur plusieurs fichiers en
onglets (taper g+t et/ou g+T pour passer d’un fichier à l’autre). Il existe de très nombreux greffons
pour compléter ce qui pourrait vous manquer si vous faites beaucoup de développement : interfaçage
avec votre répertoire git, affichage de l’arborescence de fichiers, autocomplétion…</p>
<h3 id="les-plus-8">Les plus</h3>
<ul>
<li>Utilisable sur un large panel de système d’exploitation</li>
<li>Léger et rapide à exécuter</li>
<li>Possibilité de le customiser en commençant par l’affichage de la coloration syntaxique, pour
aller vers l’implémentation de plugin, en passant par la personnalisation des raccourcis claviers</li>
</ul>
<h3 id="les-moins-8">Les moins</h3>
<ul>
<li>L’apprentissage se fait doucement, on est un peu (beaucoup) perdu quand on est habitué à
l’utilisation massive de la souris</li>
<li>Une interface très sobre et pas du tout intuitive quand on débute</li>
<li>Brut de décoffrage quand on n’active pas certaines options, par exemple l’affichage de la coloration
syntaxique et la numérotation des lignes</li>
</ul>
<h3 id="pour-aller-plus-loin-8">Pour aller plus loin</h3>
<ul>
<li>Site officiel (en anglais) : <a href="https://www.vim.org/">https://www.vim.org/</a></li>
<li>Un jeu sérieux pour apprendre à utiliser vim (en anglais), sur navigateur :
<a href="https://vim-adventures.com/">https://vim-adventures.com/</a></li>
</ul>
<h2 id="versionnement-du-code-avec-git">Versionnement du code avec git</h2>
<p><img src="/assets/img/posts/2020-01-14/git-icon-1788c.png" alt="Logo officiel de git" width="100px" class="float-left" /></p>
<p>Qui dit développement dit production de code
source. Et qu’est-ce qui peut arriver de pire quand on passe des heures sur du code ? Perdre,
bêtement, la-version-d’avant-qui-marchait-mais-n’était-pas-finie ! Ça peut paraître idiot, mais
c’est un cas relativement fréquent, surtout quand on débute. Et même quand on a plus de dix ans
d’expérience, pouvoir revenir à la version précédente, c’est plus que du confort : c’est une
question de survie !</p>
<p>Dans le monde du développement il existe plusieurs systèmes de gestion de version :</p>
<ul>
<li><a href="https://www.nongnu.org/cvs/" title="Visiter le site officiel de CVS, en anglais">CVS</a> : pour
Concurrent Version System, créé en 1990 par Dick Grune, la dernière release remonte à 13 ans</li>
<li>(source Wikipédia) ;</li>
<li><a href="https://git-scm.com/" title="Visiter le site officiel de Git">Git</a> : très certainement l’un des
plus connus, créé en 2005 par Linus Torvalds, toujours maintenu (source Wikipédia) ;</li>
<li><a href="https://www.mercurial-scm.org/" title="Visiter le site officiel de Mercurial, en anglais">Mercurial</a> :
créé par Matt Mackall en 2005, toujours maintenu (source Wikipédia) ;</li>
<li><a href="https://subversion.apache.org/" title="Visiter le site officiel de subversion, sur le site de la
fondation Apache, en anglais">Subversion</a>, aussi abrégé SVN : fondé en 2000 par CollabNet et maintenu par la fondation Apache.</li>
</ul>
<p>Bien qu’ayant découvert les systèmes de gestion de version au cours de mes études, j’ai adopté Git
quelques années après la fin de celles-ci. Il existe de très nombreuses ressources et de nombreux
tutoriels pour apprendre facilement à créer un répertoire Git et comment l’utiliser, je n’ai pas
souvenir d’avoir eu autant de facilité avec SVN mais ma mémoire peut me jouer des tours.</p>
<p>Avec Git vous serez en mesure de :</p>
<ul>
<li>créer un nouveau dépôt ou en cloner un directement ;</li>
<li>ajouter des fichiers et les mettre à jour dans le suivi de version ;</li>
<li>créer et manipuler des branches de travail, ce qui peut s’avérer très utile si vous avez une grosse
mise à jour à faire ou si vous êtes plusieurs à développer différentes fonctionnalités et que vous ne
voulez pas pourrir le travail commun ;</li>
<li>revenir à tout moment à une version précédente de votre travail ;</li>
<li>interfacer directement Git avec votre éditeur de code ou votre IDE préféré si ce dernier vous le permet…</li>
</ul>
<h3 id="les-plus-9">Les plus</h3>
<ul>
<li>La facilité de travailler à plusieurs sur le même projet</li>
<li>La possibilité de naviguer entre différentes branches de développement, très pratique si vous faites
une refonte graphique pendant qu’une autre personne revoit le cœur applicatif !</li>
<li>Un seul fichier versionné avec la possibilité de remonter à la version de son choix, on peut revenir
à la version précédente comme à la dixième version précédente !</li>
</ul>
<h3 id="les-moins-9">Les moins</h3>
<ul>
<li>L’apprentissage peut être plus ou moins rugueux</li>
<li>En cas de conflit entre deux versions il peut être plus ou moins fastidieux de le résoudre</li>
<li>Se souvenir de faire un git fetch et non pas un git pull quand on a prit une mauvaise habitude…</li>
</ul>
<h3 id="pour-aller-plus-loin-9">Pour aller plus loin</h3>
<ul>
<li>Le site officiel (en anglais) : <a href="https://git-scm.com/" title="Visiter le site
officiel de Git, en anglais">https://git-scm.com/</a></li>
<li>La documentation officielle (en anglais) : <a href="https://git-scm.com/doc" title="Consulter la documentation officielle de Git, en anglais">https://git-scm.com/doc</a></li>
<li><strong>LE</strong> livre de référence : <a href="https://git-scm.com/book/fr/v2" title="Lire le livre sur Git, en français">https://git-scm.com/book/fr/v2</a></li>
</ul>
<h1 id="et-la-documentation">Et la documentation ?</h1>
<p>Si vous suivez ce blog depuis un moment, vous m’avez certainement déjà lu pester sur l’absence de
documentation dans certains cas, sinon, je vous invite à lire
<a href="/2016/06/07/de-l-interet-d-une-bonne-documentation.html" title="Lire le billet De l’intérêt d’une bonne documentation, sur le blog de Norore">de l’intérêt d’une bonne documentation</a>.</p>
<p>Il existe différentes pratiques pour créer une documentation. Pour cela vous pouvez :</p>
<ul>
<li>utiliser les recommandations du langage principal (<a href="https://perldoc.perl.org/perldoc.html" title="Voir la documentation officicielle de perldoc, en anglais">perldoc</a> pour Perl,
<a href="https://docs.python.org/fr/3/library/pydoc.html" title="Voir la documentation officielle sur pydoc">pydoc</a>
pour Python…) que vous utilisez et le combiner avec un outil d’auto-génération de la documentation, comme
<a href="https://fr.wikipedia.org/wiki/Doxygen" title="Voir la page Wikipédia sur Doxygen">Doxygen</a>, ou simplement
utiliser la ligne de commande adéquate dans votre terminal ;</li>
<li>créer et alimenter un wiki pour chaque outil ou application que vous développez, vous pouvez même le
mettre directement sur votre projet sous <a href="https://github.com/" title="Visiter le site officiel GitHub,
en anglais">GitHub</a> si vous ne vous sentez pas assez à l’aise pour le déployer ;</li>
<li>écrire la documentation avec votre traitement de texte préféré (coucou
<a href="https://fr.libreoffice.org/" title="Visiter le site officiel de LibreOffice">LibreOffice</a> !) ou carrément</li>
<li>le faire directement en <a href="https://www.latex-project.org/" title="Visiter le site officiel du projet
LaTeX, en anglais">LaTeX</a> !</li>
</ul>
<p>Pour ma part, je n’ai pas encore trouvé de recette miracle. Je vais même plutôt avoir tendance à faire
un petit mélange des trois méthodes :</p>
<ul>
<li>dans mon code source, j’essaie de documenter les fonctions, c’est plus facile après quand on revient
sur les sources pour savoir ce que la fonction est censée faire et ce qu’elle est sensée retourner ;</li>
<li>nous avons un wiki interne (<a href="https://www.dokuwiki.org/dokuwiki" title="Visiter le site officiel de
DokuWiki, en anglais, disponible en français">DokuWiki</a>) avec une page personnelle par personne, je remplis donc
mes pages de projet afin de garder une trace de comment sont déployées les applications et comment procéder
pour les mettre à jour. Très pratique quand vous n’avez pas mis à jour depuis plusieurs mois et que vous
avez pris les automatismes d’un autre framework !</li>
<li>pour les utilisateurs, je prends des captures d’écran, quand c’est possible, et j’écris tout ce qu’ils
doivent savoir sur l’application : sa finalité, comment l’utiliser, comment faire telle ou telle action.</li>
</ul>
<p>Bref, pour les fois où j’ai fouillé dans les internets, il ne semble pas exister de recette miracle pour
faire de la documentation facilement sans aucun effort. C’est comme pour coder, il faut se creuser les
méninges et s’y mettre, avec parfois un bon coup de pied pour se lancer !</p>
<hr />
<p><em>Source de l’image d’accroche :</em> Des outils de travail pour la mécanique dans leur mallette. Photographie
de <a href="https://unsplash.com/@neonbrand">NeONBRAND</a> sur <a href="https://unsplash.com/s/photos/tools">Unsplash</a></p>
<p><em>Source des images d’illustration :</em></p>
<ul>
<li>logo Bash : <a href="https://github.com/odb/official-bash-logo" title="Lien vers le logo officiel de Bash">https://github.com/odb/official-bash-logo</a></li>
<li>logo Perl : http://www.mongueurs.net/</li>
<li>logo Python : <a href="https://fr.wikipedia.org/wiki/Fichier:Python_logo_and_wordmark.svg">https://fr.wikipedia.org/wiki/Fichier:Python_logo_and_wordmark.svg</a></li>
<li>logo PHP : <a href="https://www.php.net/download-logos.php">https://www.php.net/download-logos.php</a></li>
<li>logo Symfony : <a href="https://symfony.com/logo">https://symfony.com/logo</a></li>
<li>logo Ruby-On-Rails : <a href="https://rubyonrails.org/">https://rubyonrails.org/</a></li>
<li>logo HTML 5 : <a href="https://www.w3.org/html/logo/">https://www.w3.org/html/logo/</a></li>
<li>logo CSS 3 : <a href="https://commons.wikimedia.org/wiki/File:CSS3_logo_and_wordmark.svg">https://commons.wikimedia.org/wiki/File:CSS3_logo_and_wordmark.svg</a></li>
<li>logo non officiel JavaScript : <a href="https://commons.wikimedia.org/wiki/File:Unofficial_JavaScript_logo_2.svg">https://commons.wikimedia.org/wiki/File:Unofficial_JavaScript_logo_2.svg</a></li>
<li>logo jQuery : <a href="https://fr.wikipedia.org/wiki/Fichier:Jquery-logo.png">https://fr.wikipedia.org/wiki/Fichier:Jquery-logo.png</a></li>
<li>logo Atom : <a href="https://upload.wikimedia.org/wikipedia/commons/8/80/Atom_editor_logo.svg">https://upload.wikimedia.org/wikipedia/commons/8/80/Atom_editor_logo.svg</a></li>
<li>logo vim : <a href="https://fr.wikipedia.org/wiki/Vim#/media/Fichier:Vimlogo.svg">https://fr.wikipedia.org/wiki/Vim#/media/Fichier:Vimlogo.svg</a></li>
<li>logo git : <a href="https://git-scm.com/images/logos/downloads/Git-Icon-1788C.png">https://git-scm.com/images/logos/downloads/Git-Icon-1788C.png</a></li>
</ul>nororePour ceux qui ont suivi ma trépidante carrière, je suis actuellement développeuse d’application dans un institut de biologie, au sein de sa plateforme informatique. En tant que développeuse, j’utilise différents outils pour faire mes différents programmes. Dans ce billet, je vous propose de passer en revue quelques outils, peut-être que ça pourra aider de jeunes développeuses et développeurs à tester et se lancer ?Fatigue2019-10-15T00:00:00+02:002019-10-15T00:00:00+02:00/2019/10/15/fatigue<p>Pour ceux qui me suivent et me connaissent, vous savez que je fais partie des bénévoles qui organisent
le festival <a href="https://passageenseine.fr/" title="Visiter le site du festival Pas Sage En Seine">Pas Sage En Seine</a>. Pour les autres, vous êtes maintenant informés.</p>
<p>Petit billet sur mon retour d’expérience, qui retrace un peu les coulisses, sans forcément m’étendre
sur certains détails et le pourquoi du choix de ce titre. Cette diatribe sera sans doute un peu,
voire beaucoup, décousue, je m’en excuse.</p>
<!--more-->
<h1 id="le-festival">Le festival</h1>
<p>Le festival Pas Sage En seine est un rendez-vous annuel dans la région parisienne depuis 10 ans. Il a
eu lieu pour la quatrième année consécutive, du 27 au 30 Juin 2019, à la médiathèque Louis Aragon de
<a href="https://www.choisyleroi.fr/" title="Visiter le site de la ville Choisy-le-Roi">Choisy-le-Roi</a>, avec le
soutien indéfectible de la mairie et du personnel de la médiathèque.</p>
<p>Comme chaque année, il a été riche en conférences, en ateliers et en stands d’associations. Lieu
incontournable du milieu geek au départ, il a toujours eu pour vocation à amener les citoyens à se
réapproprier la société, le numérique étant essentiellement là en tant qu’outil, comme point de départ
pour réapprendre à bidouiller (hacker) le système.</p>
<h2 id="lassociation">L’association</h2>
<p>Afin de faciliter l’organisation du festival, et pour gérer au mieux la partie administrative et les
impondérables de ce type d’événement, l’association White Rabbit PSES a été fondée pour répondre à ces
besoins.</p>
<p>L’association n’a pas d’autre but que d’avoir une structure minimale avec un ou des bénévoles
représentants le bureau. C’est ce bureau qui a à cœur de gérer les dépenses et les recettes du festival.
L’association n’a pas pour but de générer de l’argent, mais de s’assurer que les dépenses pourront être
couvertes <em>a minima</em> par les recettes afin d’avoir assez d’économies de côté pour régler les
fournisseurs à la fin du festival mais également de pouvoir envisager un prochain festival. Parce que
ça coûte quand même un peu de sous, même si aucun des membres du bureau n’est rémunéré pour cette
activité.</p>
<h2 id="le-bureau">Le bureau</h2>
<p>Comme déjà écrit, le bureau n’existe que pour des besoins administratifs et potentiellement juridiques.
C’est également le bureau qui est en contact avec la ville de Choisy-le-Roi qui nous prête gracieusement
sa médiathèque et ses membres du personnel, qui sont rémunérés en conséquence (surcharge horaire,
présence le soir, le week-end et le dimanche…). La cellule de communication de la ville est également
de la partie pour les visuels des t-shirts et hoodies mais également la diffusion des affiches et
d’articles dans le journal de la ville.</p>
<p>Sans l’aide de la mairie, les dépenses de location de salle seraient faramineuses, sans compter le
coût du réseau pour la diffusion en live stream des ateliers et conférences ! Et n’oublions pas de
préciser que la médiathèque est accessible aux handicapés, ce qui est encore, malheureusement, un
luxe !</p>
<h2 id="les-bénévoles">Les bénévoles</h2>
<p>Outre le ou les membres du bureau, l’association peut compter sur l’aide de personnes se proposant pour
donner un coup de main. Aider à prendre contact avec les food trucks, filer un coup de main sur
l’infrastructure du site web, jouer les community manager, répartir les tâches entre les bénévoles,
contacter les associations qui pourraient être intéressées par la démarche du festival, prévoir tout
un tas de petites choses auxquelles on ne pense pas forcément…</p>
<p>Cette année, vous avez été nombreux pour nous aider avant, pendant et après le festival. Je vous en
remercie grandement ! C’est votre festival, et vous avez assuré comme des chefs. Je pense que vous
pouvez être fiers de vous !</p>
<h2 id="le-public">Le public</h2>
<p>Dans le public, je vais prendre en compte les visiteurs et visiteuses, les conférenciers et
conférencières (conférence et atelier inclus), mais également les bénévoles des associations qui
sont venus tenir un stand.</p>
<p>C’est aussi pour vous et grâce à vous que nous avons la volonté et l’énergie de faire en sorte que tout
se passe le mieux possible ! Certes la perfection n’existe pas, mais c’est grâce à vous que nous
pouvons apprendre et évoluer. J’espère que nous n’aurons pas commis trop d’erreurs et que nous saurons
tirer une leçon de nos déconvenues.</p>
<p>C’est vous qui faites que Pas Sage En Seine existe et est ce festival que nous aimons et que nous
cherchons à faire aimer à d’autres personnes. C’est grâce à vous que des gens apprennent à découvrir
d’autres personnes, d’autres associations, d’autres luttes, que ce soit parce qu’elles se sont
déplacées ou parce qu’elles peuvent suivre l’événement depuis leur salon ou leur bureau.</p>
<p>Merci !</p>
<p>Je vous présente toutes mes excuses si le festival n’a pas répondu à toutes vos attentes ou
espérances, mais j’espère néanmoins vous revoir un jour pour échanger autour d’un verre.</p>
<h1 id="lorganisation">L’organisation</h1>
<p>Afin de pallier au plus d’imprévus possibles, l’organisation se met en branle le plus tôt possible.
Cette année, elle a commencé dès le mois de Janvier. Pour cela, il y a le traditionnel appel à
contribution, où un gentil lapin multicolore sort de son terrier pour jeter une bouteille à la mer
et croiser les pattes en espérant avoir des gens motivés pour donner un coup de main. Nous avons
un <a href="https://mattermost.com/" title="Visiter le site de Mattermost (en anglais)">Mattermost</a>, sur lequel se
passe l’ensemble des communications internes, avec différents canaux pour les différents pôles à
organiser :</p>
<ul>
<li>communication ;</li>
<li>nourriture ;</li>
<li>goodies ;</li>
<li>graphisme ;</li>
<li>logistique ;</li>
<li>régie ;</li>
<li>site.</li>
</ul>
<p>Chaque bénévole est libre de participer à l’un des pôles, ou à aucun. La seule chose qui est
attendue c’est que la personne qui se porte volontaire assume cette responsabilité et qu’elle n’ait
pas peur de demander de l’aide si elle se sent débordée ou de passer le relais si elle ne se sent
plus les épaules de le gérer.</p>
<p>Nous sommes toujours contents d’avoir des bénévoles pour prendre sur leur temps libre pour nous aider,
aussi il n’y a pas de souci à nous dire que vous ne voulez ou ne pouvez plus aider. Nous ne mordons
pas et nous comprenons parfaitement :-) ! Merci à tous les bénévoles passés, présents et à venir,
votre temps est précieux, aussi soyez milles fois remerciés de nous en avoir réservé une partie !</p>
<p>Chaque bénévole est libre dans sa tâche. Aussi, ne soyez pas surpris si un membre du bureau ne vous
tanne pas pour avancer, nous partons du principe que vous êtes grands et que vous saurez nous tenir
informés en temps voulu ! Nous avons pleinement conscience que toutes ces micro-tâches prennent
du temps pour la simple et bonne raison que nous aussi nous avons nos propres tâches, en plus des
rendez-vous avec la mairie et la médiathèque pour planifier le jour J.</p>
<p>Vous voulez être bénévole mais seulement sur la durée du festival ou même la moitié ? Bienvenue à
bord !</p>
<h1 id="post-festival">Post-festival</h1>
<p>Après le festival, le dernier soir, il y a l’incontournable séance de rangement des tables, des
chaises et des étagères de documents, la médiathèque rouvrant le mardi et le personnel ayant bien
mérité son lundi de repos ! Aussi, nous remercions chaleureusement les personnes du public qui
acceptent de se prêter au jeu. Vous êtes des bénévoles formidables !</p>
<p>Une fois rentrés chez nous, n’allez pas croire que nous passons tous à autre chose. Loin de là !
Il nous faut encore :</p>
<ul>
<li>contacter les fournisseurs pour qu’ils viennent récupérer les produits laissés en dépôt-vente ;</li>
<li>payer les fournisseurs ;</li>
<li>ramener le matériel vidéo et audio généreusement prêté par <a href="https://www.octopuce.fr/" title="Visiter le site d’Octopuce">Octopuce</a> (merci vincib !) ;</li>
<li>encoder les vidéos et les mettre en ligne ;</li>
<li>prendre rendez-vous avec la mairie et la médiathèque pour faire le point.</li>
</ul>
<p>Et l’encodage de vidéos, ça prend du temps, beaucoup de temps, surtout sans une machine dédiée. Cette
année, nous n’avons que trop traîné pour les mettre en ligne, croyez bien que nous faisons tout notre
possible pour les mettre en ligne le plus rapidement que possible !</p>
<h1 id="gérer-lingérable">Gérer l’ingérable</h1>
<p>Cette partie sera sans nulle doute la moins réjouissante de ce billet bilan. Parce que tout n’est
malheureusement pas rose dans ce genre d’événement.</p>
<p>Il y a tout d’abord la partie humaine à prendre en compte, et ça, c’est clairement un point sur lequel
je pêche tout particulièrement. Je ne suis pas quelqu’un d’hyper sociable, je dois parfois faire des
efforts démesurés (sans rires !) pour réussir à communiquer, même derrière un écran. En plus de ça,
j’ai le mauvais goût de cumuler les frustrations sans rien dire, jusqu’au moment où ça déborde et où
j’explose de différentes manières : colère, crise de larmes, panique, abattement…</p>
<p>Aussi, quand on me tait des choses et que l’on nous demande le vendredi à 16h si on peut traverser
tout Paris pour aller chercher 5 caisses de boissons le lendemain à partir de 15h alors que je pensais
passer un week-end tranquille, je tique un peu.</p>
<p>Quand le festival se prend des attaques sur, <em>a priori</em>, des faits qui sont reprochés depuis des
années alors que toute l’orga a complètement changé et cherche à s’ouvrir au plus de monde possible,
pour sortir du milieu geek, j’ai mal. Je souffre. Je me demande ce qu’il se passe et je ne comprends
pas. Ça me ronge, j’essaie de comprendre chaque position, et je me fais encore plus mal que les
premières salves. Et je sombre, me demandant si, finalement, tout cela en vaut bien la peine… J’en
fais des insomnies, des pertes d’appétit (ceux qui me connaissent savent que j’ai un bon coup de
fourchette), je n’ai plus goût à rien. Je veux juste que tout s’arrête ! Et reprendre ma vie
normale, même si j’ai l’impression d’être au pied du mur avec une chape de plomb sur les épaules.</p>
<p>Et toutes ces incompréhensions me ramènent à un passé que j’aurai aimé oublier, mes cauchemars et mes
angoisses scolaires en ayant profité pour remonter en surface.</p>
<h1 id="et-après-">Et après ?</h1>
<p>Il est prévu que le festival revienne l’année prochaine à Choisy-le-Roi. L’organisation va bientôt
reprendre. Je continue de panser mes plaies en essayant de garder en tête tous les visages souriants de
cette fin du mois de Juin, tous les remerciements que nous avons reçus, tous les échanges, nombreux et
riches, avec des personnes de tous horizons et de toute la France. Mais malgré tous ces points et ces
aspects positifs, je garde un goût amer en bouche. Est-ce que je serai toujours bénévole pour l’année
2020 ?</p>
<p>Je suis fatigué·e.</p>
<p>(Article commencé le 2 Septembre.)</p>nororePour ceux qui me suivent et me connaissent, vous savez que je fais partie des bénévoles qui organisent le festival Pas Sage En Seine. Pour les autres, vous êtes maintenant informés. Petit billet sur mon retour d’expérience, qui retrace un peu les coulisses, sans forcément m’étendre sur certains détails et le pourquoi du choix de ce titre. Cette diatribe sera sans doute un peu, voire beaucoup, décousue, je m’en excuse.