# articles

feed_id: https://shadoware.org/post/application_du_confinement
title: Ulrich Van Den Hekke : L'Application du confinement pour se déplacer
uri: Ulrich-Van-Den-Hekke-L-Application-du-confinement-pour-se-déplacer
url: https://shadoware.org/post/application_du_confinement
content:
<p>Préambule: A cause du temps de validation du PlayStore, je publie cet article avec une semaine de retard.</p>
<p>Cela fait plus d'une semaine (quand j'écris ces lignes) que le re-confinement à commencé. Quand je vais courir, je dois me cantonner à
1km autour de chez moi. Mais quand je cours j'aimerais que mon téléphone intelligent me prévienne quand j'approche du rayon de 1km ou
quand je le dépasse. Je ne souhaite pas avoir le nez sur une carte de mon téléphone.</p>
<p>Je regarde ce qui se fait. J'ai trouvé l'application suivante sur le play store : <a href="https://play.google.com/store/apps/details?id=com.BETechnology.unkm">1km</a>.
L'application m'avait l'air de répondre à mes critères mais ne fonctionnait pas lors de mon utilisation (en plus il y avait de la pub).</p>
<p>Une autre application <a href="https://play.google.com/store/apps/details?id=com.apps100101.a1km">1km</a> pourrait répondre à mon besoin mais
je ne l'ai pas testé.</p>
<p>Beaucoup d'applications ont pour but de dessiner un cercle sur une carte.</p>
<p>J'ai finalement décidé d'écrire ma propre application (en plus elle sera open source).</p>
<p>Voici ce dont j'ai besoin:</p>
<ul><li>une application open source</li>
<li>un gros bouton pour démarrer la surveillance (à partir de mon point de départ)</li>
<li>un avertissement quand on approche du rayon max des 1km.</li>
<li>un avertissement régulier qand on dépasse les 1km.</li>
</ul><h2>L'application</h2>
<p>Pour développer une application Android je vais démarrer <em>Android Studio</em> et commencer à développer le 1er écran. Je choisis le
language <em>Java</em> que je maîtrise plus que le language <em>Kotlin</em> et le SDK Minimum de <em>Android 6.0</em> pour toucher 85% des
utilisateurs (si l'application peut interesser d'autres personnes).</p>
<p>J'imagine l'application découpée en deux parties:</p>
<ul><li>L'activité<sup><a href="https://shadoware.org/#fn:1" rel="footnote">1</a></sup> principale de l'application qui contiendra mon gros bouton, la position de départ, la position courante, et la
  distance à vol d'oiseau du point de départ.</li>
<li>Un service, dont le but est quand l'application est démarrée, de surveiller les déplacements et d'informer l'utilisateur.</li>
</ul><p>Nous allons donc commencer par développer l'activité</p>
<h2>L'activité</h2>
<p>Je ne suis pas graphiste ni UI/UX designer. Le design de cette première interface va alors être très simple et très sobre. Un
gros bouton + les différentes informations dont j'ai besoin quand l'application est démarrée :</p>
<p><img alt="Screenshoot page principale" src="media/51f2fd27.screenshoot1.png" data-original-source="https://shadoware.org/public/Programmation/1kmarround/screenshoot1.png"></p>
<p>Lors du démarrage de l'application, j'ai besoin que celle-ci écoute le changement, les positions de l'utilisateur afin de
définir le point de départ. Comme ce service d'écoute me sera utile également pour le service, je développe une classe à coté.</p>
<h3>ArroundLocationManager</h3>
<p>Voici donc la classe <strong>ArroundLocationManager</strong>:</p>
<div><pre><span></span><span>class</span> <span>ArroundLocationManager</span> <span>extends</span> <span>Thread</span> <span>{</span>
    <span>private</span> <span>static</span> <span>final</span> <span>String</span> <span>TAG</span> <span>=</span> <span>"ArroundLocationManager"</span><span>;</span>

    <span>private</span> <span>LocationManager</span> <span>mLocationManager</span> <span>=</span> <span>null</span><span>;</span>
    <span>private</span> <span>static</span> <span>final</span> <span>int</span> <span>LOCATION_INTERVAL</span> <span>=</span> <span>1000</span><span>;</span>
    <span>private</span> <span>static</span> <span>final</span> <span>float</span> <span>LOCATION_DISTANCE</span> <span>=</span> <span>50</span><span>f</span><span>;</span>
</pre></div>


<p>Pour commencer définissons quelques constantes: je souhaite avoir la position, tous les 50m et au maximum toutes les secondes
(m'enfin quelqu'un qui fait plus de 50m en une seconde à pied est trop fort pour moi).</p>
<div><pre><span></span>    <span>private</span> <span>List</span><span><</span><span>ArroundLocationManager</span><span>.</span><span>ArrroundLocationListener</span><span>></span> <span>listener</span> <span>=</span> <span>new</span> <span>ArrayList</span><span><>();</span>

    <span>public</span> <span>interface</span> <span>ArrroundLocationListener</span> <span>{</span>
        <span>void</span> <span>updateLocation</span><span>(</span><span>Location</span> <span>startLocation</span><span>);</span>
    <span>}</span>

    <span>private</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>[]</span> <span>mLocationListeners</span> <span>=</span> <span>new</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>[]{</span>
            <span>new</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>(</span><span>LocationManager</span><span>.</span><span>GPS_PROVIDER</span><span>),</span>
            <span>new</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>(</span><span>LocationManager</span><span>.</span><span>NETWORK_PROVIDER</span><span>)</span>
    <span>};</span>

    <span>public</span> <span>void</span> <span>addListener</span><span>(</span><span>ArroundLocationManager</span><span>.</span><span>ArrroundLocationListener</span> <span>l</span><span>)</span> <span>{</span>
        <span>listener</span><span>.</span><span>add</span><span>(</span><span>l</span><span>);</span>
    <span>}</span>

    <span>private</span> <span>void</span> <span>callListener</span><span>(</span><span>Location</span> <span>location</span><span>)</span> <span>{</span>
        <span>for</span><span>(</span> <span>ArroundLocationManager</span><span>.</span><span>ArrroundLocationListener</span> <span>l</span> <span>:</span> <span>listener</span><span>)</span> <span>{</span>
            <span>l</span><span>.</span><span>updateLocation</span><span>(</span><span>location</span><span>);</span>
        <span>}</span>
    <span>}</span>
</pre></div>


<p>Viens ensuite la définition d'un listener pour que les applications qui s'abonnent à cette classe puissent bénéficier d'un
listener et recevoir des notifications lors de la mise à jour des positions.</p>
<p>Comme on peut le constater je fais tourner cette classe dans un thread. Lors de mon développement je me suis rendu compte que
lorsque je quittais l'application, le service était tué également. Une des raisons à cela est que le service est dans le même
thread que l'activité principale. L'ajout de ce thread (ainsi que d'autre chose) ont résolu le problème. (Mais il est possible
que ce soit plus lié aux autres choses qu'au thread lui même).</p>
<p>Voici le coeur du thread:</p>
<div><pre><span></span>    <span>public</span> <span>void</span> <span>run</span><span>()</span> <span>{</span>
        <span>Looper</span><span>.</span><span>prepare</span><span>();</span>

        <span>initializeLocationManager</span><span>();</span>

        <span>Looper</span><span>.</span><span>loop</span><span>();</span>

        <span>// Never called, loop is killed when activity or thread stopped</span>
        <span>finalizeLocationManager</span><span>();</span>
    <span>}</span>

    <span>private</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>[]</span> <span>mLocationListeners</span> <span>=</span> <span>new</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>[]{</span>
        <span>new</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>(</span><span>LocationManager</span><span>.</span><span>GPS_PROVIDER</span><span>),</span>
        <span>new</span> <span>ArroundLocationManager</span><span>.</span><span>LocationListener</span><span>(</span><span>LocationManager</span><span>.</span><span>NETWORK_PROVIDER</span><span>)</span>
    <span>};</span>

    <span>public</span> <span>void</span> <span>initializeLocationManager</span><span>()</span> <span>{</span>
        <span>try</span> <span>{</span>
            <span>mLocationManager</span><span>.</span><span>requestLocationUpdates</span><span>(</span>
                    <span>LocationManager</span><span>.</span><span>NETWORK_PROVIDER</span><span>,</span> <span>LOCATION_INTERVAL</span><span>,</span> <span>LOCATION_DISTANCE</span><span>,</span>
                    <span>mLocationListeners</span><span>[</span><span>1</span><span>]);</span>
        <span>}</span> <span>catch</span> <span>(</span><span>java</span><span>.</span><span>lang</span><span>.</span><span>SecurityException</span> <span>ex</span><span>)</span> <span>{</span>
            <span>Log</span><span>.</span><span>i</span><span>(</span><span>TAG</span><span>,</span> <span>"fail to request location update, ignore"</span><span>,</span> <span>ex</span><span>);</span>
        <span>}</span> <span>catch</span> <span>(</span><span>IllegalArgumentException</span> <span>ex</span><span>)</span> <span>{</span>
            <span>Log</span><span>.</span><span>d</span><span>(</span><span>TAG</span><span>,</span> <span>"network provider does not exist, "</span> <span>+</span> <span>ex</span><span>.</span><span>getMessage</span><span>());</span>
        <span>}</span>

        <span>try</span> <span>{</span>
            <span>mLocationManager</span><span>.</span><span>requestLocationUpdates</span><span>(</span>
                    <span>LocationManager</span><span>.</span><span>GPS_PROVIDER</span><span>,</span> <span>LOCATION_INTERVAL</span><span>,</span> <span>LOCATION_DISTANCE</span><span>,</span>
                    <span>mLocationListeners</span><span>[</span><span>0</span><span>]);</span>
        <span>}</span> <span>catch</span> <span>(</span><span>java</span><span>.</span><span>lang</span><span>.</span><span>SecurityException</span> <span>ex</span><span>)</span> <span>{</span>
            <span>Log</span><span>.</span><span>i</span><span>(</span><span>TAG</span><span>,</span> <span>"fail to request location update, ignore"</span><span>,</span> <span>ex</span><span>);</span>
        <span>}</span> <span>catch</span> <span>(</span><span>IllegalArgumentException</span> <span>ex</span><span>)</span> <span>{</span>
            <span>Log</span><span>.</span><span>d</span><span>(</span><span>TAG</span><span>,</span> <span>"gps provider does not exist "</span> <span>+</span> <span>ex</span><span>.</span><span>getMessage</span><span>());</span>
        <span>}</span>
    <span>}</span>
</pre></div>


<p>On utilise le service <code>LocationManager</code> d'android pour écouter la position de l'utilisateur. On écoute la position venant
du <em>Network</em> qui permet d'avoir une position moins fiable mais rapide, puis celle venant du <em>GPS</em> permettant d'avoir une
position fiable (mais lente à obtenir).</p>
<p>Afin d'avoir une position la plus précise aussi, je me suis inspiré du code suivant:
<a href="https://stuff.mit.edu/afs/sipb/project/android/docs/training/basics/location/currentlocation.html">Obtaining the Current Location</a>.
Le code en question permet de choisir entre deux positions la plus précise (entre la position NETWORK et la position GPS).</p>
<p>On notifie les appelants:</p>
<div><pre><span></span>    <span>private</span> <span>class</span> <span>LocationListener</span> <span>implements</span> <span>android</span><span>.</span><span>location</span><span>.</span><span>LocationListener</span> <span>{</span>
        <span>public</span> <span>LocationListener</span><span>(</span><span>String</span> <span>provider</span><span>)</span> <span>{</span>
            <span>Log</span><span>.</span><span>e</span><span>(</span><span>TAG</span><span>,</span> <span>"LocationListener "</span> <span>+</span> <span>provider</span><span>);</span>
            <span>mLocation</span> <span>=</span> <span>new</span> <span>Location</span><span>(</span><span>provider</span><span>);</span>
        <span>}</span>

        <span>@Override</span>
        <span>public</span> <span>void</span> <span>onLocationChanged</span><span>(</span><span>Location</span> <span>location</span><span>)</span> <span>{</span>
            <span>Log</span><span>.</span><span>e</span><span>(</span><span>TAG</span><span>,</span> <span>"onLocationChanged: "</span> <span>+</span> <span>location</span><span>);</span>
            <span>if</span> <span>(</span><span>isBetterLocation</span><span>(</span><span>location</span><span>,</span> <span>mLocation</span><span>))</span> <span>{</span>
                <span>mLocation</span><span>.</span><span>set</span><span>(</span><span>location</span><span>);</span>
            <span>}</span>

            <span>callListener</span><span>(</span><span>mLocation</span><span>);</span>
        <span>}</span>
        <span>...</span>
    <span>}</span>
</pre></div>


<p>Enfin on a une méthode pour calculer les distances avec Android.:</p>
<div><pre><span></span>    <span>public</span> <span>static</span> <span>float</span> <span>getDistance</span><span>(</span><span>Location</span> <span>startLocation</span><span>,</span> <span>Location</span> <span>lastLocation</span><span>)</span> <span>{</span>
        <span>float</span><span>[]</span> <span>results</span> <span>=</span> <span>new</span> <span>float</span><span>[</span><span>1</span><span>];</span>
        <span>Location</span><span>.</span><span>distanceBetween</span><span>(</span><span>startLocation</span><span>.</span><span>getLatitude</span><span>(),</span> <span>startLocation</span><span>.</span><span>getLongitude</span><span>(),</span> <span>lastLocation</span><span>.</span><span>getLatitude</span><span>(),</span> <span>lastLocation</span><span>.</span><span>getLongitude</span><span>(),</span> <span>results</span><span>);</span>
        <span>float</span> <span>distance</span> <span>=</span> <span>results</span><span>[</span><span>0</span><span>];</span>
        <span>return</span> <span>distance</span><span>;</span>
    <span>}</span>
</pre></div>


<h3>MainActivity</h3>
<p>Retournons dans notre activité principale. Je passe la création du layout qui est fort simple.</p>
<p>Dans l'activité, nous allons commencer par implémenter la phase de création du cycle de vie de notre activité:</p>
<div><pre><span></span>    <span>@Override</span>
    <span>public</span> <span>void</span> <span>onCreate</span><span>(</span><span>Bundle</span> <span>savedInstanceState</span><span>)</span> <span>{</span>
        <span>super</span><span>.</span><span>onCreate</span><span>(</span><span>savedInstanceState</span><span>);</span>
        <span>setContentView</span><span>(</span><span>R</span><span>.</span><span>layout</span><span>.</span><span>activity_main</span><span>);</span>
</pre></div>


<p>Depuis Android 6.0, il faut demander à l'utilisateur la permission d'utiliser la position de l'utilisateur. Du coup
on commence par demander la permission à l'utilisateur d'avoir accès à sa position<sup><a href="https://shadoware.org/#fn:2" rel="footnote">2</a></sup>.</p>
<div><pre><span></span>        <span>requestPermissionsIfNecessary</span><span>(</span><span>new</span> <span>String</span><span>[]{</span>
                <span>Manifest</span><span>.</span><span>permission</span><span>.</span><span>ACCESS_FINE_LOCATION</span><span>,</span>
        <span>});</span>
</pre></div>


<p>Ensuite on appelle notre location manager et on écoute les changements de positions. Pour chaque changement de position
on met à jour la position et on met à jour les textes.</p>
<div><pre><span></span>        <span>locationManager</span> <span>=</span> <span>new</span> <span>ArroundLocationManager</span><span>(</span><span>this</span><span>);</span>
        <span>locationManager</span><span>.</span><span>addListener</span><span>((</span><span>location</span><span>)</span> <span>-></span> <span>{</span>
            <span>if</span> <span>(!</span><span>isMyServiceRunning</span><span>(</span><span>ArroundService</span><span>.</span><span>class</span><span>))</span> <span>{</span>
                <span>startLocation</span> <span>=</span> <span>location</span><span>;</span>
            <span>}</span>
            <span>MainActivity</span><span>.</span><span>this</span><span>.</span><span>updateTextLocation</span><span>();</span>
        <span>});</span>
        <span>locationManager</span><span>.</span><span>start</span><span>();</span>
</pre></div>


<p>Enfin on initialise l'IHM.</p>
<div><pre><span></span>        <span>distanceText</span> <span>=</span> <span>findViewById</span><span>(</span><span>R</span><span>.</span><span>id</span><span>.</span><span>distance</span><span>);</span>
        <span>startText</span> <span>=</span> <span>findViewById</span><span>(</span><span>R</span><span>.</span><span>id</span><span>.</span><span>start</span><span>);</span>
        <span>locationText</span> <span>=</span> <span>findViewById</span><span>(</span><span>R</span><span>.</span><span>id</span><span>.</span><span>location</span><span>);</span>

        <span>goButton</span> <span>=</span> <span>findViewById</span><span>(</span><span>R</span><span>.</span><span>id</span><span>.</span><span>goButton</span><span>);</span>
        <span>stopButton</span> <span>=</span> <span>findViewById</span><span>(</span><span>R</span><span>.</span><span>id</span><span>.</span><span>stopButton</span><span>);</span>
        <span>goButton</span><span>.</span><span>setOnClickListener</span><span>(</span><span>v</span> <span>-></span> <span>{</span>
            <span>setStart</span><span>(</span><span>true</span><span>);</span>
        <span>});</span>
        <span>stopButton</span><span>.</span><span>setOnClickListener</span><span>(</span><span>v</span> <span>-></span> <span>{</span>
            <span>setStart</span><span>(</span><span>false</span><span>);</span>
        <span>});</span>
        <span>setStart</span><span>(</span><span>isMyServiceRunning</span><span>(</span><span>ArroundService</span><span>.</span><span>class</span><span>));</span>
        <span>MainActivity</span><span>.</span><span>this</span><span>.</span><span>updateTextLocation</span><span>();</span>
    <span>}</span>
</pre></div>


<p>Comme le LocationManager est un thread, nous devons faire attention à repasser dans le thread de l'UI afin de mettre
à jour les labels :</p>
<div><pre><span></span>    <span>public</span> <span>void</span> <span>updateTextLocation</span><span>()</span> <span>{</span>
        <span>runOnUiThread</span><span>(()</span> <span>-></span> <span>{</span>
            <span>if</span> <span>(</span><span>this</span><span>.</span><span>startLocation</span> <span>!=</span> <span>null</span> <span>&amp;&amp;</span> <span>this</span><span>.</span><span>runLocation</span> <span>!=</span> <span>null</span><span>)</span> <span>{</span>
                <span>distanceText</span><span>.</span><span>setText</span><span>(</span><span>getString</span><span>(</span><span>R</span><span>.</span><span>string</span><span>.</span><span>distanceLabel</span><span>,</span> <span>(</span><span>int</span><span>)</span> <span>ArroundLocationManager</span><span>.</span><span>getDistance</span><span>(</span><span>startLocation</span><span>,</span> <span>runLocation</span><span>)));</span>
            <span>}</span> <span>else</span> <span>{</span>
                <span>distanceText</span><span>.</span><span>setText</span><span>(</span><span>""</span><span>);</span>
            <span>}</span>
            <span>if</span> <span>(</span><span>this</span><span>.</span><span>startLocation</span> <span>!=</span> <span>null</span><span>)</span> <span>{</span>
                <span>startText</span><span>.</span><span>setText</span><span>(</span><span>getAddress</span><span>(</span><span>startLocation</span><span>));</span>
            <span>}</span> <span>else</span> <span>{</span>
                <span>startText</span><span>.</span><span>setText</span><span>(</span><span>""</span><span>);</span>
            <span>}</span>
            <span>if</span> <span>(</span><span>this</span><span>.</span><span>runLocation</span> <span>!=</span> <span>null</span><span>)</span> <span>{</span>
                <span>locationText</span><span>.</span><span>setText</span><span>(</span><span>getAddress</span><span>(</span><span>runLocation</span><span>));</span>
            <span>}</span> <span>else</span> <span>{</span>
                <span>locationText</span><span>.</span><span>setText</span><span>(</span><span>""</span><span>);</span>
            <span>}</span>
        <span>});</span>
    <span>}</span>
</pre></div>


<p>Pour ma part je ne connais pas la position GPS de ma maison par coeur, ni de là ou je me trouve. Cela tombe bien. Android
propose une API pour geocoder une adresse. C'est à dire que l'on transforme une position en latitude, longitude en adresse
lisible:</p>
<div><pre><span></span>    <span>String</span> <span>getAddress</span><span>(</span><span>Location</span> <span>location</span><span>)</span> <span>{</span>
        <span>Geocoder</span> <span>geocoder</span><span>;</span>
        <span>List</span><span><</span><span>Address</span><span>></span> <span>addresses</span><span>;</span>

        <span>try</span> <span>{</span>
            <span>geocoder</span> <span>=</span> <span>new</span> <span>Geocoder</span><span>(</span><span>this</span><span>,</span> <span>Locale</span><span>.</span><span>getDefault</span><span>());</span>

            <span>addresses</span> <span>=</span> <span>geocoder</span><span>.</span><span>getFromLocation</span><span>(</span><span>location</span><span>.</span><span>getLatitude</span><span>(),</span> <span>location</span><span>.</span><span>getLongitude</span><span>(),</span> <span>1</span><span>);</span>

            <span>if</span> <span>(</span><span>addresses</span><span>.</span><span>size</span><span>()</span> <span>></span> <span>0</span> <span>&amp;&amp;</span> <span>addresses</span><span>.</span><span>get</span><span>(</span><span>0</span><span>).</span><span>getMaxAddressLineIndex</span><span>()</span> <span>>=</span> <span>0</span><span>)</span> <span>{</span>
                <span>return</span> <span>addresses</span><span>.</span><span>get</span><span>(</span><span>0</span><span>).</span><span>getAddressLine</span><span>(</span><span>0</span><span>);</span>
            <span>}</span>
            <span>return</span> <span>"Unknown"</span><span>;</span>
        <span>}</span> <span>catch</span> <span>(</span><span>IOException</span> <span>e</span><span>)</span> <span>{</span>
            <span>return</span> <span>e</span><span>.</span><span>getMessage</span><span>();</span>
        <span>}</span>
    <span>}</span>
</pre></div>


<h2>Le service</h2>
<p>Le service est démarré par l'application et doit ensuite survivre à la fermeture de l'application. Pour cela nous
allons créer un <em>foreground service</em> qui, contrairement aux services en tâche de fond qui sont déclenchés sur un évènement avec
une durée de vie relativement courte, va tourner au premier plan en affichant une notification.</p>
<p>Pour démarrer le service depuis l'activité principale nous avons ajouté la méthode <code>startServer</code>:</p>
<div><pre><span></span>    <span>private</span> <span>void</span> <span>startServer</span><span>()</span> <span>{</span>
        <span>if</span> <span>(!</span><span>mBounded</span><span>)</span> <span>{</span>
            <span>Intent</span> <span>mIntent</span> <span>=</span> <span>new</span> <span>Intent</span><span>(</span><span>this</span><span>,</span> <span>ArroundService</span><span>.</span><span>class</span><span>);</span>
            <span>mIntent</span><span>.</span><span>putExtra</span><span>(</span><span>"startLocation"</span><span>,</span> <span>startLocation</span><span>);</span>
            <span>ContextCompat</span><span>.</span><span>startForegroundService</span><span>(</span><span>this</span><span>,</span> <span>mIntent</span><span>);</span>
            <span>bindService</span><span>(</span><span>mIntent</span><span>,</span> <span>mConnection</span><span>,</span> <span>BIND_AUTO_CREATE</span><span>);</span>
        <span>}</span>
    <span>}</span>
</pre></div>


<p>Ce qui est important c'est la méthode <code>startForegroundService</code> dont le but est de démarrer le service en mode <em>Foreground</em>.
Cette méthode a son pendant dans le service qui est <code>startForeground</code>. Si cette dernière n'est pas appelée dans le service
une erreur sera remontée par Android.</p>
<p>Du coup on implémente le service et on commence par l'initialisation :</p>
<div><pre><span></span>    <span>@Override</span>
    <span>public</span> <span>void</span> <span>onCreate</span><span>()</span> <span>{</span>
        <span>super</span><span>.</span><span>onCreate</span><span>();</span>
        <span>notificationManager</span> <span>=</span> <span>new</span> <span>ArroundNotificationManager</span><span>(</span><span>this</span><span>);</span>
        <span>locationManager</span> <span>=</span> <span>new</span> <span>ArroundLocationManager</span><span>(</span><span>this</span><span>);</span>
        <span>locationManager</span><span>.</span><span>addListener</span><span>(</span><span>location</span> <span>-></span> <span>{</span>
            <span>runLocation</span> <span>=</span> <span>location</span><span>;</span>
            <span>callListener</span><span>(</span><span>location</span><span>);</span>
            <span>notificationManager</span><span>.</span><span>send</span><span>(</span><span>getDistance</span><span>());</span>
            <span>speakDistance</span><span>();</span>
        <span>});</span>
        <span>locationManager</span><span>.</span><span>start</span><span>();</span>
        <span>textToSpeech</span> <span>=</span> <span>new</span> <span>TextToSpeech</span><span>(</span><span>this</span><span>,</span> <span>this</span><span>);</span>
    <span>}</span>
</pre></div>


<p>On démarre le notification manager qui a pour but de notifier l'utilisateur de l'existence d'un service qui tourne au
1er plan. La notification est d'ailleurs nécessaire pour un service foreground.</p>
<p>On écoute aussi notre <code>ArroundLocationManager</code> qui lors des modifications s'occupe de mettre à jour la nouvelle position
et communique le changement de distance à l'utilisateur par voix et par notification.</p>
<p>On retrouve un <code>callListener</code> pour avertir l'utilisateur sur l'activité principale quand cette dernière est démarrée.</p>
<p>Ensuite le service démarre:</p>
<div><pre><span></span>    <span>@Override</span>
    <span>public</span> <span>int</span> <span>onStartCommand</span><span>(</span><span>Intent</span> <span>intent</span><span>,</span> <span>int</span> <span>flags</span><span>,</span> <span>int</span> <span>startId</span><span>)</span> <span>{</span>
        <span>Log</span><span>.</span><span>e</span><span>(</span><span>TAG</span><span>,</span> <span>"onStartCommand"</span><span>);</span>

        <span>PowerManager</span> <span>powerService</span> <span>=</span> <span>(</span><span>PowerManager</span><span>)</span> <span>getSystemService</span><span>(</span><span>Context</span><span>.</span><span>POWER_SERVICE</span><span>);</span>
        <span>wakeLock</span> <span>=</span> <span>powerService</span><span>.</span><span>newWakeLock</span><span>(</span><span>PowerManager</span><span>.</span><span>PARTIAL_WAKE_LOCK</span><span>,</span> <span>"ArroundService::lock"</span><span>);</span>
        <span>wakeLock</span><span>.</span><span>acquire</span><span>();</span>

        <span>Bundle</span> <span>extras</span> <span>=</span> <span>intent</span><span>.</span><span>getExtras</span><span>();</span>
        <span>Location</span> <span>location</span> <span>=</span> <span>(</span><span>Location</span><span>)</span> <span>extras</span><span>.</span><span>get</span><span>(</span><span>"startLocation"</span><span>);</span>
        <span>if</span> <span>(</span><span>location</span> <span>!=</span> <span>null</span><span>)</span> <span>{</span>
            <span>this</span><span>.</span><span>startLocation</span> <span>=</span> <span>location</span><span>;</span>
        <span>}</span>

        <span>Notification</span> <span>notification</span> <span>=</span> <span>notificationManager</span><span>.</span><span>notifyDistance</span><span>(</span><span>0</span><span>);</span>
        <span>startForeground</span><span>(</span><span>ArroundNotificationManager</span><span>.</span><span>ARROUND_ID</span><span>,</span> <span>notification</span><span>);</span>

        <span>return</span> <span>START_STICKY</span><span>;</span>
    <span>}</span>
</pre></div>


<p>Afin qu'Android et son système de gestion d'nergie ne tuent pas notre service pendant que l'on court, nous commençons
par mettre un PARTIAL_WAKE_LOCK. Ensuite nous récupérons la position (sauf si nous sommes issus d'un redémarrage de
l'application) et appelons la méthode startForeground avec une notification persistante que nous avons créé.</p>
<p>Surtout après l'acquision du Wake Lock, il est important de le relâcher lors de la fermeture (quand l'utilisateur
clique sur stop):</p>
<div><pre><span></span>    <span>public</span> <span>void</span> <span>stop</span><span>()</span> <span>{</span>
        <span>if</span> <span>(</span><span>wakeLock</span> <span>!=</span> <span>null</span><span>)</span> <span>{</span>
            <span>if</span> <span>(</span><span>wakeLock</span><span>.</span><span>isHeld</span><span>())</span> <span>{</span>
                <span>wakeLock</span><span>.</span><span>release</span><span>();</span>
                <span>wakeLock</span> <span>=</span> <span>null</span><span>;</span>
            <span>}</span>
        <span>}</span>
        <span>stopForeground</span><span>(</span><span>true</span><span>);</span>
        <span>stopSelf</span><span>();</span>
    <span>}</span>
</pre></div>


<p>On en profite pour arrêter la notification (avec ̀<code>stopForeground</code>) et arrêter le service (avec <code>stopSelf</code>).</p>
<p>Pour lire à l'utilisateur la distance, nous utilisons <code>android.speech.tts.TextToSpeech</code>. Son utilisation
est fort simple et se fait lors de l'appel à <code>speakDistance</code>:</p>
<div><pre><span></span>    <span>private</span> <span>void</span> <span>speakDistance</span><span>()</span> <span>{</span>
        <span>int</span> <span>distance</span> <span>=</span> <span>(</span><span>int</span><span>)</span> <span>getDistance</span><span>();</span>
        <span>if</span> <span>(</span><span>Math</span><span>.</span><span>abs</span><span>(</span><span>lastDistance</span> <span>-</span> <span>distance</span><span>)</span> <span>></span> <span>100</span><span>)</span> <span>{</span>
            <span>int</span> <span>stringId</span><span>;</span>
            <span>if</span> <span>(</span><span>distance</span> <span>></span> <span>1000</span><span>)</span> <span>{</span>
                <span>stringId</span> <span>=</span> <span>R</span><span>.</span><span>string</span><span>.</span><span>speaker_meters_alert</span><span>;</span>
            <span>}</span> <span>else</span> <span>if</span> <span>(</span><span>distance</span> <span>></span> <span>900</span><span>)</span> <span>{</span>
                <span>stringId</span> <span>=</span> <span>R</span><span>.</span><span>string</span><span>.</span><span>speaker_meters_warn</span><span>;</span>
            <span>}</span> <span>else</span> <span>{</span>
                <span>stringId</span> <span>=</span> <span>R</span><span>.</span><span>string</span><span>.</span><span>speaker_meters_info</span><span>;</span>
            <span>}</span>

            <span>String</span> <span>text</span> <span>=</span> <span>getString</span><span>(</span><span>stringId</span><span>,</span> <span>distance</span><span>);</span>

            <span>if</span> <span>(</span><span>Build</span><span>.</span><span>VERSION</span><span>.</span><span>SDK_INT</span> <span>>=</span> <span>Build</span><span>.</span><span>VERSION_CODES</span><span>.</span><span>LOLLIPOP</span><span>)</span> <span>{</span>
                <span>textToSpeech</span><span>.</span><span>speak</span><span>(</span><span>text</span><span>,</span> <span>TextToSpeech</span><span>.</span><span>QUEUE_FLUSH</span><span>,</span> <span>null</span><span>,</span> <span>null</span><span>);</span>
            <span>}</span> <span>else</span> <span>{</span>
                <span>textToSpeech</span><span>.</span><span>speak</span><span>(</span><span>text</span><span>,</span> <span>TextToSpeech</span><span>.</span><span>QUEUE_FLUSH</span><span>,</span> <span>null</span><span>);</span>
            <span>}</span>

            <span>lastDistance</span> <span>=</span> <span>distance</span><span>;</span>
        <span>}</span>
    <span>}</span>
</pre></div>


<p>Enfin le dernier point concerne la création des notifications. Depuis la version Android O, l'application doit
associer une notification à un channel. Cela permet à Android de présenter à l'utilisateur une interface avec les
notifications possibles et de pouvoir désactiver/activer ces dernières au cas par cas.</p>
<p><code>AndroidNotificationManager</code> est là pour ce but. Il va créer le channel de notification et notifier la distance à
l'utilisateur.</p>
<div><pre><span></span>    <span>private</span> <span>static</span> <span>final</span> <span>String</span> <span>CHANNEL_DEFAULT_IMPORTANCE</span> <span>=</span> <span>"Running"</span><span>;</span>
    <span>public</span> <span>static</span> <span>final</span> <span>int</span> <span>ARROUND_ID</span> <span>=</span> <span>1</span><span>;</span>

    <span>private</span> <span>void</span> <span>createNotificationChannel</span><span>()</span> <span>{</span>
        <span>if</span> <span>(</span><span>Build</span><span>.</span><span>VERSION</span><span>.</span><span>SDK_INT</span> <span>>=</span> <span>Build</span><span>.</span><span>VERSION_CODES</span><span>.</span><span>O</span><span>)</span> <span>{</span>
            <span>CharSequence</span> <span>name</span> <span>=</span> <span>context</span><span>.</span><span>getString</span><span>(</span><span>R</span><span>.</span><span>string</span><span>.</span><span>channel_name</span><span>);</span>
            <span>String</span> <span>description</span> <span>=</span> <span>context</span><span>.</span><span>getString</span><span>(</span><span>R</span><span>.</span><span>string</span><span>.</span><span>channel_description</span><span>);</span>
            <span>NotificationChannel</span> <span>channel</span> <span>=</span> <span>new</span> <span>NotificationChannel</span><span>(</span><span>CHANNEL_DEFAULT_IMPORTANCE</span><span>,</span> <span>name</span><span>,</span> <span>NotificationManager</span><span>.</span><span>IMPORTANCE_DEFAULT</span><span>);</span>
            <span>channel</span><span>.</span><span>setDescription</span><span>(</span><span>description</span><span>);</span>
            <span>NotificationManager</span> <span>notificationManager</span> <span>=</span> <span>context</span><span>.</span><span>getSystemService</span><span>(</span><span>NotificationManager</span><span>.</span><span>class</span><span>);</span>
            <span>notificationManager</span><span>.</span><span>createNotificationChannel</span><span>(</span><span>channel</span><span>);</span>
        <span>}</span>
    <span>}</span>

    <span>public</span> <span>Notification</span> <span>createNotification</span><span>(</span><span>float</span> <span>distance</span><span>)</span> <span>{</span>
        <span>Intent</span> <span>notificationIntent</span> <span>=</span> <span>new</span> <span>Intent</span><span>(</span><span>context</span><span>,</span> <span>MainActivity</span><span>.</span><span>class</span><span>);</span>
        <span>PendingIntent</span> <span>pendingIntent</span> <span>=</span>
                <span>PendingIntent</span><span>.</span><span>getActivity</span><span>(</span><span>context</span><span>,</span> <span>0</span><span>,</span> <span>notificationIntent</span><span>,</span> <span>0</span><span>);</span>

        <span>return</span> <span>new</span> <span>NotificationCompat</span><span>.</span><span>Builder</span><span>(</span><span>context</span><span>,</span> <span>CHANNEL_DEFAULT_IMPORTANCE</span><span>)</span>
                <span>.</span><span>setContentTitle</span><span>(</span><span>context</span><span>.</span><span>getText</span><span>(</span><span>R</span><span>.</span><span>string</span><span>.</span><span>notification_title</span><span>))</span>
                <span>.</span><span>setContentText</span><span>(</span><span>context</span><span>.</span><span>getString</span><span>(</span><span>R</span><span>.</span><span>string</span><span>.</span><span>notification_message</span><span>,</span> <span>(</span><span>int</span><span>)</span> <span>distance</span><span>))</span>
                <span>.</span><span>setSmallIcon</span><span>(</span><span>android</span><span>.</span><span>R</span><span>.</span><span>drawable</span><span>.</span><span>ic_menu_mylocation</span><span>)</span>
                <span>.</span><span>setContentIntent</span><span>(</span><span>pendingIntent</span><span>)</span>
                <span>.</span><span>build</span><span>();</span>
    <span>}</span>

    <span>public</span> <span>void</span> <span>notifyDistance</span><span>(</span><span>float</span> <span>distance</span><span>)</span> <span>{</span>
        <span>Notification</span> <span>n</span> <span>=</span> <span>this</span><span>.</span><span>createNotification</span><span>(</span><span>distance</span><span>);</span>
        <span>NotificationManager</span> <span>notificationManager</span> <span>=</span> <span>context</span><span>.</span><span>getSystemService</span><span>(</span><span>NotificationManager</span><span>.</span><span>class</span><span>);</span>
        <span>notificationManager</span><span>.</span><span>notify</span><span>(</span><span>ARROUND_ID</span><span>,</span> <span>n</span><span>);</span>
    <span>}</span>
</pre></div>


<p>Il est important lors de l'appel à notifyDistance de toujours utiliser le même identifiant de notification afin
que cette dernière soit remplacée (et non ajouté). Cela permet de mettre à jour le contenu de la notification.</p>
<h2>Pour finir</h2>
<p>Pour finir je suis content d'avoir développé cette application qui n'est pas exempte de bug, mais qui m'a pris
très peu de temps de développement.</p>
<p>Vous pouvez retrouver le code source sur <a href="https://github.com/phoenix741/1kmarround">Github: phoenix741/1kmarround</a>
et sur le <a href="https://play.google.com/store/apps/details?id=org.shadoware.a1kmarroud">PlayStore</a> (à ce jour l'application
n'a pas encore été validé dans les stores et n'est donc pas disponible).</p>
<p>Le plus long dans ce développement aura été:</p>
<ul><li>faire l'icône (à partir d'une image se trouvant sur <a href="https://undraw.co/">undraw.co</a>)</li>
<li>faire le layout (même si elle est simple)</li>
<li>remplir la fiche du playstore pour mettre l'application dans les stores.</li>
</ul><div>
<hr><ol><li>
<p>Une activité est l'équivalent d'un écran dans Android. <a href="https://shadoware.org/#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li>
<p>Pour demander les permissions je me suis basé sur le code suivant:</p>
<div><pre><span></span>@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    ArrayList<String> permissionsToRequest = new ArrayList<>();
    for (int i = 0; i < grantResults.length; i++) {
        permissionsToRequest.add(permissions[i]);
    }
    if (permissionsToRequest.size() > 0) {
        ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

private void requestPermissionsIfNecessary(String[] permissions) {
    ArrayList<String> permissionsToRequest = new ArrayList<>();
    for (String permission : permissions) {
        if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
            // Permission is not granted
            permissionsToRequest.add(permission);
        }
    }
    if (permissionsToRequest.size() > 0) {
        ActivityCompat.requestPermissions(this, permissionsToRequest.toArray(new String[0]), REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}
</pre></div>


<p><a href="https://shadoware.org/#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol></div>
<p><img src="media/6b1ba161.4f904d3f901ea9e5debb071ada9ea38b" data-original-source="http://cdn.libravatar.org/avatar/4f904d3f901ea9e5debb071ada9ea38b" alt="Gravatar de Ulrich Van Den Hekke" class="gravatar" /><br/><i>Original post of <a href="https://shadoware.org/post/application_du_confinement" title="Visit the source">Ulrich Van Den Hekke</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>mael : <a href="">T&eacute;l&eacute;commande universelle avec arduino. 2 &ndash; Une appli android</a> (19/07/2011)</li><li>Tasse de Caf&eacute; : <a href="">D&eacute;velopper pour Android sans Eclipse : cr&eacute;er et compiler un projet</a> (12/08/2012)</li><li>Tasse de Caf&eacute; : <a href="">D&eacute;velopper pour Android sans Eclipse</a> (19/06/2012)</li><li>Tasse de Caf&eacute; : <a href="">Android sans Eclipse : tester, installer et debugger une application</a> (16/09/2012)</li><li>&reg;om : <a href="">Compiler un ex&eacute;cutable pour Android</a> (18/03/2014)</li></ul></div></p>


feed_id: https://www.blog-libre.org/2020/11/15/terminal-et-puissance/
title: blog-libre : Terminal et puissance
uri: blog-libre-Terminal-et-puissance
url: https://www.blog-libre.org/2020/11/15/terminal-et-puissance/
content:
<p>What gives people feelings of power : Ce qui donne aux gens un sentiment de puissance.</p>
<p><a href="media/dc25214e.terminal-elistisme.jpeg" data-original-source="https://www.blog-libre.org/wp-content/uploads/2020/11/terminal-elistisme.jpeg"><img loading="lazy" width="622" height="592" src="media/dc25214e.terminal-elistisme.jpeg" data-original-source="https://www.blog-libre.org/wp-content/uploads/2020/11/terminal-elistisme.jpeg" alt="" srcset="https://www.blog-libre.org/wp-content/uploads/2020/11/terminal-elistisme.jpeg 622w, https://www.blog-libre.org/wp-content/uploads/2020/11/terminal-elistisme-300x286.jpeg 300w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px"></a></p>
<h3>Meilleur et supérieur</h3>
<p>Il y a quelques années je me sentais meilleur que les autres simplement parce que j’utilisais le terminal. Un jour je m’étais trouvé con, les doigts légèrement au-dessus du clavier, je ne savais pas faire en ligne de commande ce que je voulais alors que ça aurait pu être résolu rapidement et facilement en quelques clics. J’étais bloqué intérieurement, je ne voulais pas m’abaisser à faire comme un simple utilisateur. J’utilisais le terminal pour me distinguer d’autrui.</p>
<p>Posséder ce que les autres n’ont pas ou avoir/faire mieux qu’eux permet de se démarquer, se sentir supérieur.</p>
<p>Étrangement j’avais besoin d’en parler, d’assumer mon erreur et le ridicule de cette situation. Je suppose que de manière inconsciente j’ai voulu ressembler et m’identifier à une élite technique, probablement une envie d’appartenance à un groupe, de reconnaissance. Maintenant j’assume bien plus/mieux mes différences et mes erreurs, je pense que ça vient avec l’âge et la confiance en soi.</p>
<h3>Puissance et power user</h3>
<p>J’effectue à présent une majorité d’actions en ligne de commande, je confirme efficacité, rapidité, précision (et personnalisation). Je me sens surpuissant grâce à Linux, au terminal et Bash.</p>
<p>Dans <a href="https://www.blog-libre.org/2018/08/18/humiliation-liberation-volonte-puissance/" rel="noopener noreferrer" target="_blank">Humiliation, libération, volonté, puissance</a> je disais :</p>
<blockquote><p>Je n’ai jamais été aussi puissant qu’aujourd’hui, je suis maître de mon ordinateur, je ne suis plus esclave de mon système d’exploitation. Je réfléchis à mes besoins, l’écosystème Linux me permet d’y répondre quand Windows me limitait. Je ne suis pas libre, j’ai enlevé mes chaînes. Je ne me traîne plus avec un boulet au pied, je cours. J’apprends à être libre et responsable.</p></blockquote>
<p>Quand je suis arrivé sur Linux, plus de chaînes, tout est ouvert et possible. Cependant la liberté implique de faire des choix, de comprendre ce qu’on fait, d’apprendre, c’est <strong>extrêmement coûteux</strong>. J’ai la chance d’être passionné, d’exercer un job de sysadmin Linux, j’ai bouffé de la connaissance. Je lance Firefox en ligne de commande, j’éteins et reboote mon pc avec des alias, je cherche et ouvre fichiers et dossiers avec des fonctions.</p>
<p>Le savoir est à portée de main sur Linux, on peut construire. La documentation est aussi proche que la commande <code>man</code>, le code est ouvert, les gens partagent, on peut suivre la correction des bugs, les issues, les releases dans les repos. Impossible sur Windows et macOS où nous sommes tributaires d’applications graphiques toutes différentes, limités au niveau configuration et modification du système.</p>
<p>Sur mon pc fixe, je suis en dual-boot Windows et Debian. Sur mon pc portable, chiffrement complet du disque et LVM. Grâce à Linux. </p>
<p>Je ne prône pas Linux pour tous, <strong>en tant que <a href="https://www.blog-libre.org/2017/11/18/cheminement-dun-power-user-de-windows-a-gnu-linux/" rel="noopener noreferrer" target="_blank">power user</a></strong> je témoigne de mon avancement, de ma satisfaction. Et finalement de ma puissance grâce à Linux.</p>
<p><img src="media/25c7216e.1ea6f31074367d57d77721240d30fda9" data-original-source="http://cdn.libravatar.org/avatar/1ea6f31074367d57d77721240d30fda9" alt="Gravatar de blog-libre" class="gravatar" /><br/><i>Original post of <a href="https://www.blog-libre.org/2020/11/15/terminal-et-puissance/" title="Visit the source">blog-libre</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>blog-libre : <a href="">Linux se professionnalise</a> (23/10/2016)</li><li>blog-libre : <a href="">Comme un doute</a> (28/07/2017)</li><li>blog-libre : <a href="">Cheminement d&#039;un power user : De Windows &amp;agrave; GNU/Linux</a> (18/11/2017)</li><li>blog-libre : <a href="">Linux sur le desktop</a> (07/07/2019)</li><li>blog-libre : <a href="">Lancer TeamViewer</a> (14/09/2019)</li></ul></div></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #46
uri: 2020-11-16-Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-46
feed_id:
https://blog.journalduhacker.net/index.php?article297/liens-interessants-journal-du-hacker-semaine-46-2020

url:
https://blog.journalduhacker.net/index.php?article297/liens-interessants-journal-du-hacker-semaine-46-2020

content:
<p>Pour la 46ème semaine de l'année 2020, voici <strong>12 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/k1i8ha/i_don_t_want_any_spam">« I don’t want any spam ! »</a></li>
<li><a href="https://www.journalduhacker.net/s/8iu2pl/largent_chez_les_d_veloppeur_euse_s">L'argent chez les développeur(euse)s</a></li>
<li><a href="https://www.journalduhacker.net/s/y9lwzp/un_vrai_bastion_opensource_qui_tout_pour">Un vrai bastion OpenSource qui a tout pour plaire propulsé par OVH</a></li>
<li><a href="https://www.journalduhacker.net/s/naucqb/proxmox_backup_server_1_0">Proxmox Backup Server 1.0</a></li>
<li><a href="https://www.journalduhacker.net/s/4ly4og/ik_me_une_adresse_email_gratuite_vie_d">ik.me : une adresse email gratuite à vie développée et hébergée en Suisse</a></li>
<li><a href="https://www.journalduhacker.net/s/hlylf1/mettre_en_place_un_syst_me_de_visioconf">Mettre en place un système de visioconférence avec BigBlueButton</a></li>
<li><a href="https://www.journalduhacker.net/s/wykdrv/python_sous_le_capot_chapitre_1">Python sous le capot - Chapitre 1 : Fonctionnement de la VM CPython</a></li>
<li><a href="https://www.journalduhacker.net/s/gwtakw/la_diff_rence_entre_is_et_avec_python">La différence entre is et == avec Python</a></li>
<li><a href="https://www.journalduhacker.net/s/akdmp9/la_fibre_orange_2gbps_sur_un_routeur">La fibre Orange à 2Gbps, sur un routeur MikroTik 10Gbps CCR2004, via un ONT SFP+</a></li>
<li><a href="https://www.journalduhacker.net/s/ih97al/crowdsec_la_cybers_curit_collaborative">CrowdSec : la cybersécurité collaborative, open source et gratuite pour Linux</a></li>
<li><a href="https://www.journalduhacker.net/s/sioxu3/profiler_son_application_node_js_analyse">Profiler son application Node.js : analyse de la mémoire</a></li>
<li><a href="https://www.journalduhacker.net/s/b8l6hf/mail_rss_transformer_des_mails_en_flux_rss">Mail RSS : transformer des mails en flux RSS</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://twitter.com/journalduhacker">Le compte Twitter du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article297/liens-interessants-journal-du-hacker-semaine-46-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Carl Chenet : <a href="">Liens int&eacute;ressants Journal du hacker semaine #46</a> (13/11/2015)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #46</a> (21/11/2016)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #46</a> (20/11/2017)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #46</a> (19/11/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #46</a> (18/11/2019)</li></ul></div></p>


feed_id: https://formation-logiciel-libre.com/presentation-logiciel-libre-gestion-formation-professionnelle/
title: Dimitri Robert : Présentation de mon logiciel libre de gestion de formation professionnelle
uri: Dimitri-Robert-Présentation-de-mon-logiciel-libre-de-gestion-de-for
url: https://formation-logiciel-libre.com/presentation-logiciel-libre-gestion-formation-professionnelle/
content:
<p>Vous êtes organisme de formation avec un numéro de déclaration d’activité (obtenu auprès de la Direccte), éventuellement référençable sur <a href="https://www.data-dock.fr/" title="Datadock">Datadock</a> et envisagez peut-être de vous faire certifier <a href="https://travail-emploi.gouv.fr/formation-professionnelle/acteurs-cadre-et-qualite-de-la-formation-professionnelle/qualiopi" title="Qualiopi">Qualiopi</a> ? Vous êtes à la recherche d’un logiciel qui vous aide à gérer tous les aspects administratifs autour de la formation professionnelle continue ?</p>
<p>Je vous propose une présentation du logiciel que je développe depuis bientôt trois ans et qui a pour objectif de gérer tous ces aspects administratifs. Cette présentation vous montrera l’état d’avancement, ainsi que les perspectives d’évolution.</p>
<p>Cette présentation se fera sous la forme d’un webinaire en ligne le mercredi 25 novembre à partir de 14h. Vous pourrez suivre cette présentation à l’adresse : https://visio.artefacts.coop/b/dim-edu-3uz</p>
<p>Actuellement il est possible de :</p>
<ul><li>gérer un catalogue de formations</li>
<li>programmer des sessions de formation</li>
<li>gérer les clients et les stagiaires</li>
<li>produire les documents-types</li>
<li>produire le bilan pédagogique et financier</li>
<li>chaque formateur⋅trice peut gérer ses sessions, mais un⋅e responsable de formation valide les opérations</li>
</ul><p>À court terme il sera possible de gérer les différents critères requis pour la certification Qualiopi.</p>
<p>Ce logiciel (encore en quête d’un nom sympathique) est diffusé sous licence libre (GPL v3) se présente sous la forme d’une extension pour WordPress. Il est donc possible de l’installer sur une instance existante ou déployée pour l’occasion. Il est donc possible de l’héberger soi-même sans passer par une solution SAAS. Cependant, le fait de le distribuer sous licence libre permet à quiconque de proposer de l’hébergement, y compris payant.</p>
<p>Ce webinaire sera l’occasion de poser toutes les questions que vous souhaitez. Il est prévu un créneau de trois heures pour justement laisser du temps pour répondre aux questions. Il sera également question d’aborder les aspects financiers. Je pars sur l’idée d’un financement à prix libre. Cela peut être sous la forme d’un abonnement à prix libre ou de contributions uniques.</p>
<p>Je suis moi-même formateur dans un organisme de formation (la coopérative d’activités et d’emploi Artéfacts en région Centre – Val de Loire) et suis donc le premier utilisateur de ce logiciel. J’ai ressenti le besoin il y a trois ans de mettre en place un formulaire en ligne pour saisir les informations nécessaires pour produire les documents administratifs de manière automatisée, plutôt que de passer par des modèles de document à remplir. C’était l’idée de base, simple. Depuis le projet a grossi pour permettre à tout un chacun de l’utiliser, même (surtout) sans connaissances en informatique.</p>
<p>L’idée, aujourd’hui, est de proposer une interface simple qui permette l’accompagnement des formateurs et responsables de formation pour satisfaire aux obligations légales que sont le bilan pédagogique et financier et les audits et contrôles dans le cadre de Datadock et Qualiopi. Ce logiciel s’adresse aux organismes concourant au développement des compétences (nouveau nom pour organisme de formation).</p>
<p>Vous pouvez vous inscrire sur l’événement, mais ce n’est pas obligatoire. Vous pouvez simplement venir le 25 novembre à 14h l’adresse https://visio.artefacts.coop/b/dim-edu-3uz.</p>
<p>Inscription : https://mobilizon.fr/events/0f2490d3-56e6-4e2f-9ff9-eae8cfbaf629</p>
<p>La présentation se fera via notre plateforme BigBlueButton, dont vous pourrez lire un manuel d’utilisation sur https://ma.formation-logiciel-libre.com/bbb/.</p>
<p>L’article <a rel="nofollow" href="https://formation-logiciel-libre.com/presentation-logiciel-libre-gestion-formation-professionnelle/">Présentation de mon logiciel libre de gestion de formation professionnelle</a> est apparu en premier sur <a rel="nofollow" href="https://formation-logiciel-libre.com/">Formation logiciel libre</a>.</p>
<p><img src="media/a723311b.bc7f2e519b76bc86af82809d62e1ca0a" data-original-source="http://cdn.libravatar.org/avatar/bc7f2e519b76bc86af82809d62e1ca0a" alt="Gravatar de Dimitri Robert" class="gravatar" /><br/><i>Original post of <a href="https://formation-logiciel-libre.com/presentation-logiciel-libre-gestion-formation-professionnelle/" title="Visit the source">Dimitri Robert</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Philippe Scoffoni : <a href="">Quand le logiciel propri&eacute;taire finance (un peu) le logiciel libre</a> (07/06/2011)</li><li>Jonathan Le Lous : <a href="">Charte Libre Emploi - Pour un emploi durable dans le logiciel libre</a> (19/12/2012)</li><li>Philippe Scoffoni : <a href="">OpenERP, d&eacute;couverte de la version 7 du logiciel open source de gestion d&rsquo;entreprise</a> (30/01/2013)</li><li>Philippe Scoffoni : <a href="">Comment choisir un logiciel libre ou open source ?</a> (19/03/2013)</li><li>Philippe Scoffoni : <a href="">Mutualisation et logiciel libre, les utilisateurs oseront-ils prendre le pouvoir ?</a> (19/04/2013)</li></ul></div></p>


feed_id: https://miamondo.org/2020/11/15/la-planete-archlinux-mise-a-jour-du-manuel-dinstallation/
title: miamondo : La planète Archlinux – Mise à jour du manuel d’installation
uri: miamondo-La-planète-Archlinux-Mise-à-jour-du-manuel-d-instal
url: https://miamondo.org/2020/11/15/la-planete-archlinux-mise-a-jour-du-manuel-dinstallation/
content:
<p>Bonjour,</p>



<p><strong>Je viens tout juste de terminer la mise à jour de mon <a href="https://miamondo96030527.wordpress.com/category/informatique/archlinux/">manuel d’installation d’Archlinux</a>. Celui-ci compte cinq chapitres, dont quatre pour l’installation proprement dite. Le cinquième chapitre décrit un processus de post-installation personnalisée, lequel est bien évidemment facultatif.</strong></p>



<span></span>



<ul><li><strong><a rel="noreferrer noopener" href="https://miamondo96030527.wordpress.com/2020/11/12/chapitre-1-premiers-pas-avec-archlinux/" target="_blank">Chapitre 1 – Premiers pas avec Archlinux</a></strong></li><li><strong><a rel="noreferrer noopener" href="https://miamondo96030527.wordpress.com/2020/11/13/chapitre-2-partitionner-son-disque-dur/" target="_blank">Chapitre 2 – Partitionner le disque dur</a></strong></li><li><strong><a rel="noreferrer noopener" href="https://miamondo96030527.wordpress.com/2020/11/13/chapitre-3-le-formatage-des-partitions/" target="_blank">Chapitre 3 – Le formatage des partitions</a></strong></li><li><strong><a rel="noreferrer noopener" href="https://miamondo96030527.wordpress.com/2020/11/14/chapitre-4-installer-la-base-du-systeme/" target="_blank">Chapitre 4 – Installer la base du système</a></strong></li><li><strong><a rel="noreferrer noopener" href="https://miamondo96030527.wordpress.com/2020/11/14/chapitre-5-post-installation/" target="_blank">Chapitre 5 – Post-installation sur une base Openbox</a></strong></li></ul><p>J’en ai profité pour aérer la mise en page. Ce tutoriel que j’ai baptisé <strong>la planète Archlinux</strong>, est également à votre disposition <strong><a rel="noreferrer noopener" href="media/8f1c3c3a.planet-archlinux-4.pdf" data-original-source="https://miamondo96030527.files.wordpress.com/2020/11/planet-archlinux-4.pdf" target="_blank">en version pdf</a></strong>, librement téléchargeable, cela va sans dire. Si certain(e)s d’entre vous souhaitent le recevoir en version <strong>odt</strong>, n’hésitez pas à <strong><a rel="noreferrer noopener" href="https://miamondo96030527.wordpress.com/contact/" target="_blank">me contacter</a></strong>.</p>



<p>Il n’y a pas de grands changements depuis la dernière fois. J’ai testé l’installation dans une machine virtuelle, en l’occurrence <strong><a href="https://wiki.gnome.org/Apps/Boxes">Machines</a></strong> (C’est comme ça que ça s’appelle!). Il s’agit d’une application Gnome qui fonctionne plutôt bien, et le logo me plait beaucoup. </p>



<div><figure><img data-attachment-id="888" data-permalink="https://miamondo.org/boxes/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/11/boxes.jpg" data-orig-size="433,432" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"1"}' data-image-title="boxes" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/11/boxes.jpg?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/11/boxes.jpg?w=433" src="https://miamondo96030527.files.wordpress.com/2020/11/boxes.jpg?w=433" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/11/boxes.jpg 433w, https://miamondo96030527.files.wordpress.com/2020/11/boxes.jpg?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/11/boxes.jpg?w=300 300w" sizes="(max-width: 433px) 100vw, 433px"></figure></div>



<p>Donc je disais, j’ai testé le processus d’installation et aussi la post-installation. Verdict: Tout s’est très bien passé. Si toutefois, vous trouvez une erreur ou une approximation, merci de me le préciser en commentaires.</p>



<p>Bon dimanche et à bientôt.</p>
<p><img src="media/848c13f4.27be241458674ac3359b0353fdc37c4a" data-original-source="http://cdn.libravatar.org/avatar/27be241458674ac3359b0353fdc37c4a" alt="Gravatar de miamondo" class="gravatar" /><br/><i>Original post of <a href="https://miamondo.org/2020/11/15/la-planete-archlinux-mise-a-jour-du-manuel-dinstallation/" title="Visit the source">miamondo</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://blog.genma.fr/?Mettre-a-jour-le-firmware-de-sa-Nitrokey-FIDO2
title: genma : Mettre à jour le firmware de sa Nitrokey FIDO2
uri: genma-Mettre-à-jour-le-firmware-de-sa-Nitrokey-FIDO2
url: https://blog.genma.fr/?Mettre-a-jour-le-firmware-de-sa-Nitrokey-FIDO2
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2922.png?1605273507" width="150" height="77"><div><p><strong>Introduction</strong></p>
<p>En juillet 2020 je publiais un article sur les<a href="https://blog.genma.fr/?Nitrokey-clefs-USB-opensource-comme-2nd-facteurs-d-authentification" title="Nitrokey, clefs USB opensource comme 2nd facteurs d'authentification">Nitrokey, clefs USB opensource comme 2nd facteurs d'authentification</a>. Depuis cet article, je continue de suivre l'actualité autour des Nitrokey, j'utilise depuis ma clef Nitrokey FIDO2 comme second facteur d'authentification pour certaines de mes instances Nexctcloud.</p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nitrokey_nextcloud.png?1605273560" width="500" height="152" alt=""></span></p>
<p><strong>Une nouvelle version du firmware</strong></p>
<p>Une nouvelle version du firmware est sortie et a été annoncée sur le site de Nitrokey <a href="https://www.nitrokey.com/news/2020/nitrokey-fido2-firmware-20-update" title="Nitrokey FIDO2 Firmware 2.0 Update">Nitrokey FIDO2 Firmware 2.0 Update</a> ainsi que sur le dépôt Githun dans la section correspondant : <a href="https://github.com/Nitrokey/nitrokey-fido2-firmware/releases/tag/2.0.0.nitrokey" title="Github de Nitrokey - nitrokey-fido2-firmware">Github de Nitrokey - nitrokey-fido2-firmware</a>.</p>
<p><i><br>
Afin de pouvoir utiliser encore mieux le Nitrokey FIDO2, nous avons développé un nouveau firmware 2.0 avec les nouvelles fonctionnalités suivantes :
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Meilleure intégration avec Microsoft Azure Active Directory, en utilisant AAGUID dans le certificat d'appareil.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Prise en charge d'OpenSSH (à partir de la version 8.3), par ex. pour l'administration des serveurs Linux.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Gestion du code PIN et des clés via Google Chromes Security Manager.</i></p>
<p>Vous trouverez plus de détails techniques dans nos notes de publication <a href="https://github.com/Nitrokey/nitrokey-fido2-firmware/releases/tag/2.0.0.nitrokey" title="https://github.com/Nitrokey/nitrokey-fido2-firmware/releases/tag/2.0.0.nitrokey">https://github.com/Nitrokey/nitrokey-fido2-firmware/releases/tag/2.0.0.nitrokey</a><br></p>
<p>Un message d'avertissement figure aussi sur le site :<br><i>Note : this update clears all the resident keys saved on the device. While FIDO U2F and FIDO2 registrations were tested to work after the update, please make sure you have alternative way of confirming identity on all registered services before making the update.</i></p>
<p>que je traduirai par</p>
<p><i><br>
Remarque : cette mise à jour efface toutes les clés résidentes enregistrées sur l'appareil. Bien que les enregistrements FIDO U2F et FIDO2 aient été testés pour fonctionner après la mise à jour, veuillez vous assurer que vous disposez d'un autre moyen de confirmer l'identité de tous les services enregistrés avant d'effectuer la mise à jour.<br></i></p>
<p>Par précaution, j'avais désactivé la clef de mes instances Nextcloud comme 2nd facteur avant de le réactiver suite à la mise à jour du firmware.</p>
<p><strong>Procédure de mise à jour</strong></p>
<p>C'est assez simple. Il faut se rendre sur le site <a href="https://update.nitrokey.com/" title="update.nitrokey.com">update.nitrokey.com</a>, suivre les instructions (<strong>uniquement en anglais</strong>). Je mets ci-dessous quelques captures d'écrans des étapes les plus marquantes de cette mise à jour de firmware.</p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nitrokey_webupdate_00.png?1605273566" width="500" height="267" alt=""></span></p>
<p>On branche la clef, on la touche quand elle clignote (conformément aux instructions), on attend sans rien faire sur le PC et on voit la progression de la mise à jour.</p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nitrokey_webupdate_01.png?1605273570" width="500" height="159" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nitrokey_webupdate_02.png?1605273575" width="500" height="248" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nitrokey_webupdate_03.png?1605273578" width="500" height="220" alt=""></span></p>
<p>Si on rebranche la clef et qu'on relance la mise à jour, la clef étant à la dernière version, il ne se passe rien.</p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nitrokey_webupdate_04.png?1605273584" width="500" height="223" alt=""></span></p>
<p>L'interface web propose également des informations techniques complémentaires :</p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nitrokey_webupdate_05.png?1605273590" width="500" height="163" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L494xH364/nitrokey_webupdate_06-904af.png?1605513601" width="494" height="364" alt=""></span></p>
<p><strong>Disponibilités des codes sources</strong></p>
<p>Opensource oblige (le concept du produit), le code source du firmware est disponible sur Github <a href="https://github.com/Nitrokey/nitrokey-fido2-firmware/" title="https://github.com/Nitrokey/nitrokey-fido2-firmware/">https://github.com/Nitrokey/nitrokey-fido2-firmware/</a>.</p>
<p>Le code source de l'application qui fait les mises à jour derrière l'adresse <a href="https://update.nitrokey.com/" title="https://update.nitrokey.com">https://update.nitrokey.com</a> est également disponible sur Github <a href="https://github.com/Nitrokey/nitrokey-webupdate" title="Nitrokey - Github - nitrokey-webupdate">Nitrokey - Github - nitrokey-webupdate</a>.</p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Mettre-a-jour-le-firmware-de-sa-Nitrokey-FIDO2" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://www.ezvan.fr/apple-arm-et-plateforme-ouverte.html
title: Paul Ezvan : Apple, ARM et plateforme ouverte
uri: Paul-Ezvan-Apple-ARM-et-plateforme-ouverte
url: https://www.ezvan.fr/apple-arm-et-plateforme-ouverte.html
content:
<p>Les nouveaux ordinateurs Apple basés sur le processeur M1 commencent à être testés par différents sites spécialisés en hardware. Le verdict est sans appel : c'est une claque de performance et efficacité sans précédent pour ses vénérables concurrents.</p>
<h2>Une révolution ?</h2>
<p>Est-ce l'avènement d'une nouvelle ère où nos smartphones et ordinateurs personnels utiliseront tous la même technologie <a href="https://www.ezvan.fr/futur-arm.html">ARM</a>, que les smartphones utilisent depuis leurs débuts ?</p>
<p>Les smartphones ont envahi notre monde. Ils sont partout, et nécessaires pour de plus en plus d'opérations : validation d'opérations bancaires, paiements, tickets de transports, services de transports urbain, etc.</p>
<p>C'est une révolution encore plus forte que celle de l'ordinateur personnel, qui a généralisé l'accès à l'informatique et à Internet.</p>
<h2>L'histoire bégaie</h2>
<p>Il y a pourtant une différence majeure avec les ordinateurs personnels.</p>
<p>Au début de ceux-ci, de nombreux fabricants étaient en compétition, comme Amiga, Apple et Atari, avec des architectures et systèmes différents. Il n'y avait que peu d'interopérabilité entre les différents ordinateurs disponibles. Puis a emergé la plateforme PC, qui devint rapidement un standard de facto.</p>
<p>La grosse force de cette plateforme est son ouverture. Un système fonctionnant sur PC peut fonctionner sur tous les ordinateurs compatibles PC. La majorité des ordinateurs sont compatibles PC à l'exception notable des machines Apple.</p>
<p>Cela a permis le succès de Windows puis Linux. D'autres systèmes compatibles PC pourtant moins répandus peuvent ainsi fonctionner sur de nombreux ordinateurs, comme les différents Unix et BSD.</p>
<h2>Un monde fermé</h2>
<p>Le monde ARM est très différent, car il n'y a pas de plateforme définie. Il est très difficile voire impossible de faire fonctionner le système d'un iPhone sur un téléphone Android, et vice-versa. Il est de même très difficile de faire fonctionner le système d'un téléphone Samsung sur un téléphone d'une autre marque.</p>
<p>C'est une grande difficulté pour créer des systèmes alternatifs fonctionnant sur des smartphones. Il existe des projets comme <a href="https://lineageos.org/">LineageOS</a> proposant des systèmes Android alternatifs pouvant remplacer celui fourni par le constructeur, mais ils nécessitent un important travail de portage pour chaque téléphone.</p>
<p>De même il existe des initiatives telles que <a href="https://postmarketos.org/">postmarketOS</a> permettant de faire fonctionner un vrai système Linux sur son smartphone, mais de grandes difficultés de portage ne permettent de le faire que sur une liste réduite de téléphones pour lesquels un long travail a été nécessaire.</p>
<h2>Pour un futur verrouillé ?</h2>
<p>Apple avec ses Macbook s'est engagé dans la même voie, fournissant matériel et logiciel dans une plateforme liée. Installer un autre système sur un Macbook récent est possible, mais requiert beaucoup d'efforts.</p>
<p>Ses Iphones sont complètements verrouillés. Impossible d'y installer un autre système. Impossible d'y installer des applications non autorisées par Apple. Apple va-t-il profiter du passage à ARM sur ses Macbook pour y imposer les mêmes contraintes ?</p>
<p>S'il le fait, échangerons-nous de meilleures performances contre la liberté de choisir ses logiciels ? Le modèle du smartphone fermé finira-t-il par vaincre celui du PC ouvert ?</p>
<p>Laisserons-nous des systèmes complètement fermés être des outils indispensables à nos vies ?</p>
<p><img src="media/b247c897.bb95714d3ea200b7450465f3e1097d18" data-original-source="http://cdn.libravatar.org/avatar/bb95714d3ea200b7450465f3e1097d18" alt="Gravatar de Paul Ezvan" class="gravatar" /><br/><i>Original post of <a href="https://www.ezvan.fr/apple-arm-et-plateforme-ouverte.html" title="Visit the source">Paul Ezvan</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Planet Libre : <a href="">Br&egrave;ves du Planet Libre - Sunday 28, October 2012</a> (28/10/2012)</li><li>Planet Libre : <a href="">Br&egrave;ves du Planet Libre - Monday 08, April 2013</a> (08/04/2013)</li><li>Planet Libre : <a href="">Br&egrave;ves du Planet Libre - lundi 29, ao&ucirc;t 2016</a> (29/08/2016)</li></ul></div></p>


feed_id: https://www.ezvan.fr/apple-arm-plateforme-ouverte.html
title: Paul Ezvan : Apple, ARM et plateforme ouverte
uri: 2020-11-19-Paul-Ezvan-Apple-ARM-et-plateforme-ouverte
url: https://www.ezvan.fr/apple-arm-plateforme-ouverte.html
content:
<p>Les nouveaux ordinateurs Apple basés sur le processeur M1 commencent à être testés par différents sites spécialisés en hardware. Le verdict est sans appel : c'est une claque de performance et efficacité sans précédent pour ses vénérables concurrents.</p>
<h2>Une révolution ?</h2>
<p>Est-ce l'avènement d'une nouvelle ère où nos smartphones et ordinateurs personnels utiliseront tous la même technologie <a href="https://www.ezvan.fr/futur-arm.html">ARM</a>, que les smartphones utilisent depuis leurs débuts ?</p>
<p>Les smartphones ont envahi notre monde. Ils sont partout, et nécessaires pour de plus en plus d'opérations : validation d'opérations bancaires, paiements, tickets de transport, services de transport urbain, etc.</p>
<p>C'est une révolution encore plus forte que celle de l'ordinateur personnel, qui a généralisé l'accès à l'informatique et à Internet.</p>
<h2>L'histoire bégaie</h2>
<p>Il y a pourtant une différence majeure avec les ordinateurs personnels.</p>
<p>Au début de ceux-ci, de nombreux fabricants étaient en compétition, comme Amiga, Apple et Atari, avec des architectures et systèmes différents. Il n'y avait que peu d'interopérabilité entre les différents ordinateurs disponibles. Puis a emergé la plateforme PC, qui devint rapidement un standard de facto.</p>
<p>La grosse force de cette plateforme est son ouverture. Un système fonctionnant sur PC peut fonctionner sur tous les ordinateurs compatibles PC. La majorité des ordinateurs sont compatibles PC à l'exception notable des machines Apple.</p>
<p>Cela a permis le succès de Windows puis Linux. D'autres systèmes compatibles PC pourtant moins répandus peuvent ainsi fonctionner sur de nombreux ordinateurs, comme les différents Unix et BSD.</p>
<h2>Un monde fermé</h2>
<p>Le monde ARM est très différent, car il n'y a pas de plateforme définie. Il est très difficile voire impossible de faire fonctionner le système d'un iPhone sur un téléphone Android, et vice-versa. Il est de même très difficile de faire fonctionner le système d'un téléphone Samsung sur un téléphone d'une autre marque.</p>
<p>C'est une grande difficulté pour créer des systèmes alternatifs fonctionnant sur des smartphones. Il existe des projets comme <a href="https://lineageos.org/">LineageOS</a> proposant des systèmes Android alternatifs pouvant remplacer celui fourni par le constructeur, mais ils nécessitent un important travail de portage pour chaque téléphone.</p>
<p>De même il existe des initiatives telles que <a href="https://postmarketos.org/">postmarketOS</a> permettant de faire fonctionner un vrai système Linux sur son smartphone, mais de grandes difficultés de portage ne permettent de le faire que sur une liste réduite de téléphones pour lesquels un long travail a été nécessaire.</p>
<h2>Pour un futur verrouillé ?</h2>
<p>Apple avec ses Macbook s'est engagé dans la même voie, fournissant matériel et logiciel dans une plateforme liée. Installer un autre système sur un Macbook récent est possible, mais requiert beaucoup d'efforts.</p>
<p>Ses Iphones sont complètements verrouillés. Impossible d'y installer un autre système. Impossible d'y installer des applications non autorisées par Apple. Apple va-t-il profiter du passage à ARM sur ses Macbook pour y imposer les mêmes contraintes ?</p>
<p>S'il le fait, échangerons-nous de meilleures performances contre la liberté de choisir ses logiciels ? Le modèle du smartphone fermé finira-t-il par vaincre celui du PC ouvert ?</p>
<p>Laisserons-nous des systèmes complètement fermés être des outils indispensables à nos vies ?</p>
<p><img src="media/b247c897.bb95714d3ea200b7450465f3e1097d18" data-original-source="http://cdn.libravatar.org/avatar/bb95714d3ea200b7450465f3e1097d18" alt="Gravatar de Paul Ezvan" class="gravatar" /><br/><i>Original post of <a href="https://www.ezvan.fr/apple-arm-plateforme-ouverte.html" title="Visit the source">Paul Ezvan</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Planet Libre : <a href="">Br&egrave;ves du Planet Libre - Sunday 28, October 2012</a> (28/10/2012)</li><li>Planet Libre : <a href="">Br&egrave;ves du Planet Libre - Monday 08, April 2013</a> (08/04/2013)</li><li>Planet Libre : <a href="">Br&egrave;ves du Planet Libre - lundi 29, ao&ucirc;t 2016</a> (29/08/2016)</li></ul></div></p>


uri: Simon-Vieille-Le-PDG-de-FaceBook-Mark-Zuckerberg-malmené-lors-de
feed_id:
https://www.deblan.io/post/592/le-pdg-de-facebook-mark-zuckerberg-malmene-lors-de-son-audition-au-senat-americain-17-11-20

title:
Simon Vieille : Le PDG de FaceBook, Mark Zuckerberg, malmené lors de son audition au Sénat américain (17/11/20)

url:
https://www.deblan.io/post/592/le-pdg-de-facebook-mark-zuckerberg-malmene-lors-de-son-audition-au-senat-americain-17-11-20

content:
<p>Le PDG de FaceBook, Mark Zuckerberg, malmené par le sénateur Josh Hawley lors de son audition au Sénat américain.
le 17 novembre 2020.</p>
<p><img src="media/f6ec4698.a99922fd1c4e000d5911b8c88280938e" data-original-source="http://cdn.libravatar.org/avatar/a99922fd1c4e000d5911b8c88280938e" alt="Gravatar de Simon Vieille" class="gravatar" /><br/><i>Original post of <a href="https://www.deblan.io/post/592/le-pdg-de-facebook-mark-zuckerberg-malmene-lors-de-son-audition-au-senat-americain-17-11-20" title="Visit the source">Simon Vieille</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://127.0.0.1:8000/articles/nouveau-blog-nouvelle-aventure
title: citizenz7 : Nouveau blog, nouvelle aventure
uri: citizenz7-Nouveau-blog-nouvelle-aventure
url: https://127.0.0.1:8000/articles/nouveau-blog-nouvelle-aventure
content:
nouveau-blog-nouvelle-aventure
<p><img src="media/81133586.d3d22ade032c891f4b97588788975fc6" data-original-source="http://cdn.libravatar.org/avatar/d3d22ade032c891f4b97588788975fc6" alt="Gravatar de citizenz7" class="gravatar" /><br/><i>Original post of <a href="https://127.0.0.1:8000/articles/nouveau-blog-nouvelle-aventure" title="Visit the source">citizenz7</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://www.citizenz.info/articles/nouveau-blog-nouvelle-aventure
title: citizenz7 : Nouveau blog, nouvelle aventure
uri: 2020-11-21-citizenz7-Nouveau-blog-nouvelle-aventure
url: https://www.citizenz.info/articles/nouveau-blog-nouvelle-aventure
content:
nouveau-blog-nouvelle-aventure
<p><img src="media/81133586.d3d22ade032c891f4b97588788975fc6" data-original-source="http://cdn.libravatar.org/avatar/d3d22ade032c891f4b97588788975fc6" alt="Gravatar de citizenz7" class="gravatar" /><br/><i>Original post of <a href="https://www.citizenz.info/articles/nouveau-blog-nouvelle-aventure" title="Visit the source">citizenz7</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://libre-ouvert.tuxfamily.org/index.php?article235/joyeux-anniversaire-a-moi-15-ans-gnulinux
title: antistress : Joyeux anniversaire à moi : 15 ans de GNU/Linux
uri: antistress-Joyeux-anniversaire-à-moi-15-ans-de-GNU-Linux
url: https://libre-ouvert.tuxfamily.org/index.php?article235/joyeux-anniversaire-a-moi-15-ans-gnulinux
content:
<a href="https://www.flickr.com/photos/21756912@N00/5045502202"><p><img src="media/489e42a9.birthday-cake-will-clayton-cc-by-2.0_400x265.jpg" data-original-source="https://libre-ouvert.tuxfamily.org/data/images/birthday-cake-will-clayton-cc-by-2.0_400x265.jpg" alt="Gâteau d'anniversaire avec bougies" height="265" width="400"></p></a>

<p>Cela faisait quelques mois que je me disais que, lorsque viendra novembre (on dirait du Cabrel), j'aurais ce billet à écrire pour fêter mes 15 ans sous GNU/Linux.</p>

<p>Notez que je n'ai aucun mérite à me souvenir de la date de cet anniversaire puisque j'ai débuté avec une distribution dont le numéro de version correspond à la date de publication… Ubuntu 5.10 a été, en effet, mon premier <abbr lang="en" title="Operating System">OS</abbr> libre.</p><p>--</p>

<p>J'ai déjà retracé mes 10 premières années dans un précédent billet. Avec émotion <a href="https://libre-ouvert.tuxfamily.org/?article219/joyeux-anniversaire-a-moi-10-ans-de-gnu-linux">je m'étais souvenu</a> des avancées technologiques qui avaient permis, avec le temps, à mon système de répondre à presque tous mes besoins.</p>

<p>Finalement, il ne m'a manqué qu'une chose pendant toutes ces années : un logiciel de montage vidéo libre digne de ce nom.</p>

<p>J'ai longtemps attendu la version 1.0 de Pitivi. Entre-temps, j'ai effectué mes montages avec une version piratée de Vegas Vidéo sur un poste Windows XP obsolète…  Puis, un beau jour, mon beau caméscope DV Canon est devenu caduc. Quant à moi, en vieillissant, j'ai arrêté d'avoir du temps à consacrer au montage vidéo (vous pouvez définitivement mettre une chanson de Cabrel en fond sonore : ce billet respire manifestement la joie).</p>

<p>Ironie du calendrier, <a href="https://linuxfr.org/news/pitivi-1-0-en-fait-2020-09-est-sorti-apres-16-ans-de-developpement">Pitivi 1.0 vient de sortir, après 16 ans de développement</a>. Tant mieux pour ceux qui en auront besoin, c'est une pièce importante d'un système pour un certain nombre d'utilisateurs.</p>

<p>--</p>

<p>À la fin du billet consacré à mes 10 ans de GNU/Linux, je passe en revue les technos qui semblent alors s'imposer, comme Wayland, Btrfs et ce projet né au sein de GNOME d'un format d'applications qui permette leur isolation et qui soit indépendant des distributions.</p>

<p>S'agissant de Wayland tout d'abord, j'ai définitivement basculé dessus depuis, mais toutes mes applications ne tournent pas encore nativement sous Wayland : Firefox <em xml:lang="en" lang="en">Upstream</em> et surtout Thunderbird, sont à la traîne. C'est casse-pieds car cela ôte dans mon cas tout intérêt à la fonctionnalité de GNOME Shell <a href="https://linuxfr.org/news/gnome-3-34#toc-exp%C3%A9rimental-gnome-coupe-le-cordon-avecx11">qui permet d'ouvrir une session Wayland indépendamment de X.Org</a>, dans la mesure où Firefox et Thunderbird sont toujours lancés sur mon système.</p>

<p>Btrfs, ensuite, n'a pas été le raz-de-marée annoncé semble t-il, même s'il finit par être adopté ici (OpenSuse) ou, plus récemment, là (Fedora 33). De mon côté je suis resté sous ext4.</p>

<p>Enfin Flatpak, puisque c'est le nom définitif du projet qui n'était encore qu'en gestation il y a cinq ans, est à présent une réalité. Pour ma part, c'est devenu une des deux jambes de mon système comme je le détaille dans <a href="https://libre-ouvert.tuxfamily.org/?article205/au-revoir-debian-bonjour-debian-avec-flatpak-mise-jour">ce billet</a>, l'autre étant Debian <em xml:lang="en" lang="en">Testing</em>.</p>

<p>--</p>

<p>Autre évènement marquant de ces dernières années, la transformation de Firefox qui a non seulement rattrapé sa dette technique avec le projet Quantum (<a href="https://linuxfr.org/news/firefox-quantum-premiere-partie-du-projet-quantum-de-mozilla-est-disponible">chapitre I</a> il y a trois ans et <a href="https://linuxfr.org/news/firefox-67-introduit-l-acte-ii-du-projet-quantum">chapitre II</a> il y a un an et demi), mais a aussi enfin sauté le pas, il y a un an, <a href="https://linuxfr.org/news/firefox-69">en proposant par défaut pour tous ses utilisateurs un mécanisme de protection poussée de la vie privée</a> !</p>

<p>Pourtant l'avenir de cette pièce essentielle du Web et de nos systèmes est aujourd'hui incertain :/</p>

<p>--</p>

<p>Qu'attends-je à présent pour la suite ?</p>

<p>Et bien surtout que toutes les pièces finissent de s'assembler, par exemple que je puisse bénéficier d'un Firefox tournant nativement sous Wayland, dans sa version Flatpak, avec tous les procédés d'accélération activés (principalement WebRender et décodage vidéo). Actuellement il faut encore choisir, le temps que tout soit débogué.</p>

<p>À part ça GTK 4 ne devrait plus tarder, et j'ai une curiosité relative quant à savoir ce qu'il permettra pour les prochaines versions de GNOME.</p>

<p>Un peu plus loin de nous, les développeurs de GIMP (<a href="https://www.gimp.org/donating/">donnez</a> !) travaillent d'arrache-pied au portage vers GTK+ 3 qui lui permettra notamment de tourner nativement sous Wayland.</p>

<p>De la même façon les développeurs de Firefox travaillent sur le projet Fission, <a href="https://www.generation-nt.com/firefox-site-isolation-securite-memoire-actualite-1981520.html">une refonte majeure du fonctionnement interne du navigateur pour une meilleure sécurité</a>.</p>

<p>Mais je dirais qu'à part pour le premier item (la finalisation des chantiers en cours de Firefox sous GNU/Linux), je manque un peu d'excitation.</p>

<p>À la réflexion, un truc qui pourrait me rendre un peu d'excitation serait la démocratisation de matériel libre compétitif à base de processeurs d’architecture <a href="https://fr.wikipedia.org/wiki/RISC-V">RISC-V</a>. Mais j'aimerais bien ne pas avoir à attendre 15 ans pour voir cela arriver...</p>
<p><img src="media/4839f6a5.470c5e17640a289d1e99b26d2dec9f54" data-original-source="http://cdn.libravatar.org/avatar/470c5e17640a289d1e99b26d2dec9f54" alt="Gravatar de antistress" class="gravatar" /><br/><i>Original post of <a href="https://libre-ouvert.tuxfamily.org/index.php?article235/joyeux-anniversaire-a-moi-15-ans-gnulinux" title="Visit the source">antistress</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>antistress : <a href="">Joyeux anniversaire &agrave; moi : 10 ans de GNU/Linux</a> (22/12/2015)</li></ul></div></p>


feed_id: https://www.blog-libre.org/2020/11/22/luminosite-et-brightnessctl/
title: blog-libre : Luminosité et brightnessctl
uri: blog-libre-Luminosité-et-brightnessctl
url: https://www.blog-libre.org/2020/11/22/luminosite-et-brightnessctl/
content:
<p>La luminosité est la première chose que je règle sur un écran. L’occasion de faire un point avec l’arrivée du XPS 13.</p>
<h3>Documentation et recherche</h3>
<p>Avant tout lisez <a href="https://sebsauvage.net/wiki/doku.php?id=pour_vos_yeux" rel="noopener noreferrer" target="_blank">Réduire la fatigue visuelle sur écran</a> du Wiki de Sebsauvage puis <a href="https://wiki.openbsd.fr.eu.org/doku.php/system/misc/redshift" rel="noopener noreferrer" target="_blank">Redshift : ajustement automatique de la température de couleur</a> du Wiki OpenBSD. Merci à eux.</p>
<p>Si vous voulez faire des recherches en Anglais les termes utilisés sont brightness et backlight, comme souvent le Wiki Arch est un bon <a href="https://wiki.archlinux.org/index.php/Backlight" rel="noopener noreferrer" target="_blank">point de départ</a>.</p>
<h3>Raccourcis clavier, GUI et CLI</h3>
<p>Sur un écran externe, il faudra régler la luminosité avec les boutons sur l’écran. Sur pc portable, le moyen le plus simple/rapide est d’utiliser les raccourcis clavier. En général il s’agit d’une combinaison avec la touche FN et une autre. Sur le Dell XPS, FN+F6 réduit la luminosité et FN+F7 l’augmente. Je les trouve très mal placés personnellement, je préférais la disposition de mon précédent pc (FN+Gauche/Droite). Surtout sur le XPS, je confondais régulièrement FN+F5 (allumer les touches du clavier) avec FN+F6.</p>
<p>Suivant l’environnement utilisé (Gnome, KDE, Xfce…), vous pouvez régler la réduction de la luminosité automatiquement après un certain délai (en cas d’inactivité). Sur Xfce il faut aller dans Paramètres, Gestionnaire d’alimentation Xfce, onglet Écran.</p>
<p><a href="media/3a354998.brightness_001.png" data-original-source="https://www.blog-libre.org/wp-content/uploads/2021/11/brightness_001.png"><img loading="lazy" width="826" height="588" src="media/3a354998.brightness_001.png" data-original-source="https://www.blog-libre.org/wp-content/uploads/2021/11/brightness_001.png" alt="" srcset="https://www.blog-libre.org/wp-content/uploads/2021/11/brightness_001.png 826w, https://www.blog-libre.org/wp-content/uploads/2021/11/brightness_001-300x214.png 300w, https://www.blog-libre.org/wp-content/uploads/2021/11/brightness_001-768x547.png 768w, https://www.blog-libre.org/wp-content/uploads/2021/11/brightness_001-640x456.png 640w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px"></a></p>
<p>En ligne de commande pour afficher la valeur actuelle de la luminosité <code>cat /sys/class/backlight/*/brightness</code>, pour la modifier <code>echo 9600 | sudo tee /sys/class/backlight/*/brightness</code> et connaître la valeur max <code>cat /sys/class/backlight/*/max_brightness</code>. </p>
<h3>brightnessctl</h3>
<p><a href="https://github.com/Hummer12007/brightnessctl" rel="noopener noreferrer" target="_blank">brightnessctl</a> s’installe sur Debian/Ubuntu/Mint avec <code>sudo apt install brightnessctl</code> en simplifiant la gestion de la luminosité, la légère difficulté est sur les <a href="https://github.com/Hummer12007/brightnessctl#permissions" rel="noopener noreferrer" target="_blank">permissions</a> soit vous utilisez sudo soit une des méthodes préconisées. J’ai opté pour ajouter mon utilisateur aux groupes video et input : <code>sudo usermod -aG video cascador; sudo usermod -aG input cascador</code>. À partir de là les commandes suivantes ne nécessitent plus sudo.</p>
<p><code>brightnessctl</code> # Afficher les infos (notamment le device, la luminosité actuelle et max)<br><code>brightnessctl get</code> # Afficher la luminosité actuelle<br><code>brightnessctl --quiet set +10%</code> # Augmenter la luminosité de 10%<br><code>brightnessctl --quiet set 20%-</code> # Baisser la luminosité de 20%<br><code>brightnessctl --quiet set 5%</code> # Mettre la luminosité à 5%<br><code>brightnessctl --quiet set 0</code> # Mettre la luminosité à 0<br><code>brightnessctl --quiet set 10000</code> # Mettre la luminosité à 10000<br><code>brightnessctl --quiet set +5000</code> # Augmenter la luminosité de 5000<br><code>brightnessctl --quiet set 2000-</code> # Baisser la luminosité de 2000<br><code>brightnessctl -l</code> # Lister les devices<br><code>brightnessctl -d 'input0::capslock' set 1</code> # Allumer la LED de la touche Verr Maj sur le XPS (inutile mais rigolo)<br><code>brightnessctl -d 'dell::kbd_backlight' set 2</code> # Allumer les touches du clavier sur le XPS<br><code>brightnessctl -d 'dell::kbd_backlight' set 0</code> # Éteindre les touches du clavier sur le XPS</p>
<p><code>man brightnessctl</code> est explicite. Sur Debian Testing Xfce je vais ajouter des raccourcis clavier dans Paramètres, Clavier, onglet Raccourcis d’applications : Super+Droite <code>brightnessctl --quiet set +5%</code> et Super+Gauche <code>brightnessctl --quiet set 5%-</code>.</p>
<h3>Un service systemd avec brightnessctl</h3>
<p>J’utilise lightdm comme écran de connexion, light-locker s’occupant de verrouiller l’écran. Un truc pénible lorsqu’on rabat l’écran du pc portable, à la sortie de veille (en le réouvrant) la luminosité est au max. On va régler ça avec un service systemd. </p>
<p></p><pre>sudo nano /etc/systemd/system/brightness-resume.service
[Unit]
Description=Set brightness after resume
After=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/bin/brightnessctl --quiet set 5%</pre><p> </p>
<p>On l’active <code>sudo systemctl enable brightness-resume.service</code> et c’est du passé.</p>
<h3>Interrogation</h3>
<p>La luminosité max du XPS est de 96000, quasiment tout le temps (sauf au soleil et dans le noir) je suis à 5% soit 4800. J’en viens à me demander si je suis pas « bizarre », il est rare que je règle plus de 20% sur mes écrans sans quoi j’ai l’impression que l’écran sert davantage de lampe torche et m’éclate les yeux. Je suis le seul ?</p>
<p><img src="media/25c7216e.1ea6f31074367d57d77721240d30fda9" data-original-source="http://cdn.libravatar.org/avatar/1ea6f31074367d57d77721240d30fda9" alt="Gravatar de blog-libre" class="gravatar" /><br/><i>Original post of <a href="https://www.blog-libre.org/2020/11/22/luminosite-et-brightnessctl/" title="Visit the source">blog-libre</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://blog.kulakowski.fr/post/openwrt-derriere-une-freebox-ipv6-dmz-et-bridge
title: Guillaume Kulakowski : OpenWRT derrière une Freebox: IPv6, DMZ et Bridge
uri: Guillaume-Kulakowski-OpenWRT-derrière-une-Freebox-IPv6-DMZ-et-Bri
url: https://blog.kulakowski.fr/post/openwrt-derriere-une-freebox-ipv6-dmz-et-bridge
content:
<p>Bien que je sois le très récent et heureux possesseur d’une Freebox Pop, j’ai fait le choix de continuer à déléguer la gestion de mon réseau ainsi que de mon partage Wi-Fi, non pas à la Pop, mais à OpenWRT. Les avantages pour moi sont les suivants : Plus de contrôle au niveau des règles […]</p>
<p>Cet article <a rel="nofollow" href="https://blog.kulakowski.fr/post/openwrt-derriere-une-freebox-ipv6-dmz-et-bridge">OpenWRT derrière une Freebox: IPv6, DMZ et Bridge</a> est apparu en premier sur <a rel="nofollow" href="https://blog.kulakowski.fr/">Guillaume Kulakowski's blog</a>.</p>
<p><img src="media/9719583b.7e5813be2b1eaef89d90a5b456bb1970" data-original-source="http://cdn.libravatar.org/avatar/7e5813be2b1eaef89d90a5b456bb1970" alt="Gravatar de Guillaume Kulakowski" class="gravatar" /><br/><i>Original post of <a href="https://blog.kulakowski.fr/post/openwrt-derriere-une-freebox-ipv6-dmz-et-bridge" title="Visit the source">Guillaume Kulakowski</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Guillaume Vaillant : <a href="">OpenWRT, Freebox et IPv6</a> (20/03/2013)</li><li>Guillaume Kulakowski : <a href="">OpenWRT dans mon r&eacute;seau domestique</a> (20/07/2020)</li></ul></div></p>


feed_id: https://www.citizenz.info/articles/debuter-avec-symfony-5-le-fichier-env
title: citizenz7 : Débuter avec Symfony 5 : le fichier .env
uri: citizenz7-Débuter-avec-Symfony-5-le-fichier-env
url: https://www.citizenz.info/articles/debuter-avec-symfony-5-le-fichier-env
content:
debuter-avec-symfony-5-le-fichier-env
<p><img src="media/81133586.d3d22ade032c891f4b97588788975fc6" data-original-source="http://cdn.libravatar.org/avatar/d3d22ade032c891f4b97588788975fc6" alt="Gravatar de citizenz7" class="gravatar" /><br/><i>Original post of <a href="https://www.citizenz.info/articles/debuter-avec-symfony-5-le-fichier-env" title="Visit the source">citizenz7</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #47
uri: 2020-11-23-Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-47
feed_id:
https://blog.journalduhacker.net/index.php?article298/liens-interessants-journal-du-hacker-semaine-47-2020

url:
https://blog.journalduhacker.net/index.php?article298/liens-interessants-journal-du-hacker-semaine-47-2020

content:
<p>Pour la 47ème semaine de l'année 2020, voici <strong>10 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/atqjxg/les_passages_secrets_du_web">Les passages secrets du web</a></li>
<li><a href="https://www.journalduhacker.net/s/tprq8p/google_tag_manager_la_nouvelle_arme_anti">Google Tag Manager, la nouvelle arme anti adblock</a></li>
<li><a href="https://www.journalduhacker.net/s/bvonvi/et_si_vim_avait_raison">Et si Vim avait raison ?</a></li>
<li><a href="https://www.journalduhacker.net/s/1jqkga/bien_d_buter_avec_manjaro_linux">Bien débuter avec Manjaro Linux</a></li>
<li><a href="https://www.journalduhacker.net/s/wnubf5/arr_tons_d_crire_du_code_naus_abond">Arrêtons d’écrire du code nauséabond</a></li>
<li><a href="https://www.journalduhacker.net/s/8cvhrt/20_salles_de_20_ordinateurs_en_2020_au_togo">20 salles de 20 ordinateurs en 2020 au Togo – Emmabuntüs</a></li>
<li><a href="https://www.journalduhacker.net/s/xn6xgn/sites_statiques_et_jamstack_la_r_volution">Sites statiques et Jamstack : la révolution frontend</a></li>
<li><a href="https://www.journalduhacker.net/s/slzxpu/entropie_quantit_d_information">Entropie, quantité d’information</a></li>
<li><a href="https://www.journalduhacker.net/s/du8vj6/la_plan_te_archlinux_mise_jour_du_manuel">La planète Archlinux - Mise à jour du manuel d'installation</a></li>
<li><a href="https://www.journalduhacker.net/s/tjzgp7/dyndns_ovh_avec_ddclient">DynDNS OVH avec ddclient</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://twitter.com/journalduhacker">Le compte Twitter du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article298/liens-interessants-journal-du-hacker-semaine-47-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Carl Chenet : <a href="">Liens int&eacute;ressants Journal du hacker semaine #47</a> (19/11/2015)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #47</a> (28/11/2016)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #47</a> (27/11/2017)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #47</a> (26/11/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #47</a> (25/11/2019)</li></ul></div></p>


feed_id: https://blog.kulakowski.fr/post/openwrt-et-mise-en-place-du-wi-fi-802-11r
title: Guillaume Kulakowski : OpenWRT et mise en place du Wi-Fi 802.11r
uri: Guillaume-Kulakowski-OpenWRT-et-mise-en-place-du-Wi-Fi-802-11r
url: https://blog.kulakowski.fr/post/openwrt-et-mise-en-place-du-wi-fi-802-11r
content:
<p>On continue l’aventure autour d’OpenWRT avec ce coup-ci, la mise en place du Wi-Fi 802.11r. Tout d’abord, qu’est ce que le Wi-Fi 802.11r ? Si on simplifie à l’extrême, c’est pouvoir passer d’une borne Wi-Fi à une autre sans coupure. En image : je suis dans mon salon, je suis connecté à la borne la […]</p>
<p>Cet article <a rel="nofollow" href="https://blog.kulakowski.fr/post/openwrt-et-mise-en-place-du-wi-fi-802-11r">OpenWRT et mise en place du Wi-Fi 802.11r</a> est apparu en premier sur <a rel="nofollow" href="https://blog.kulakowski.fr/">Guillaume Kulakowski's blog</a>.</p>
<p><img src="media/9719583b.7e5813be2b1eaef89d90a5b456bb1970" data-original-source="http://cdn.libravatar.org/avatar/7e5813be2b1eaef89d90a5b456bb1970" alt="Gravatar de Guillaume Kulakowski" class="gravatar" /><br/><i>Original post of <a href="https://blog.kulakowski.fr/post/openwrt-et-mise-en-place-du-wi-fi-802-11r" title="Visit the source">Guillaume Kulakowski</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>ephase : <a href="">Turris Omnia : se connecter en ssh avec une&nbsp;cl&eacute;</a> (26/10/2020)</li></ul></div></p>


title: genma : Une alternative à Framadate ? Opensondage dans Yunohost et Polls dans Nextcloud
uri: genma-Une-alternative-à-Framadate-Opensondage-dans-Yunohost-et-Po
feed_id:
https://blog.genma.fr/?Une-alternative-a-Framadate-Opensondage-dans-Yunohost-et-Polls-dans-Nextcloud

url:
https://blog.genma.fr/?Une-alternative-a-Framadate-Opensondage-dans-Yunohost-et-Polls-dans-Nextcloud

content:
<img alt="" src="https://blog.genma.fr/IMG/arton2924.png?1606315853" width="150" height="99"><div><p><strong>Framadate ?</strong></p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L446xH300/framadate-8c93e.jpg?1606316277" width="446" height="300" alt=""></span></p>
<p><i>Framadate est un service en ligne permettant de planifier un rendez-vous ou prendre des décisions rapidement et simplement. Aucune inscription préalable n'est nécessaire.</i><br><a href="https://framadate.org/" title="https://framadate.org/">https://framadate.org/</a></p>
<p>Certains <i>services Framasoft</i> vont fermer (cf <a href="https://framablog.org/2019/09/24/deframasoftisons-internet/" title="Déframasoftisons Internet ! sur le Framablog">Déframasoftisons Internet ! sur le Framablog</a>), il est possible de connaitre et d'installer les logiciels derrière ces services, les tutoriels sont sur <a href="https://framacloud.org/fr/" title="https://framacloud.org/fr/">https://framacloud.org/fr/</a> ou de faire appel aux services d'un Chaton (<a href="https://chatons.org/" title="https://chatons.org/">https://chatons.org/</a>).</p>
<p>Même si Framadate ne fait pas partie de cette liste, il est toujours bon d'avoir en tête une alternative...</p>
<p><strong>Yunohost ?</strong></p>
<p>Framadate fait partie des logiciels packagés et donc disponibles pour Yunohost : <a href="https://yunohost.org/#/app_opensondage_fr" title="https://yunohost.org/#/app_opensondage_fr">https://yunohost.org/#/app_opensondage_fr</a> et <a href="https://github.com/YunoHost-Apps/opensondage_ynh" title="https://github.com/YunoHost-Apps/opensondage_ynh">https://github.com/YunoHost-Apps/opensondage_ynh</a> Voir à ce sujet <a href="https://yunohost.org/#/apps_framasoft_fr" title="Yunohost - Équivalence avec les applications Framasoft">Yunohost - Équivalence avec les applications Framasoft</a></p>
<p><strong>Nextcloud pour certains services, et donc Polls pour les sondages</strong></p>
<p>Nextcloud et son écosystème peut être une alternative à certains services du projet Degooglisons de Framasoft. Framadrive, Framagenda repose sur Nextcloud par exemple. Dans ce billet, je voudrais me focaliser sur une alternative pour Framadate, à savoir <a href="https://apps.nextcloud.com/apps/polls" title="Polls dans l'app store Nextcloud"> Polls dans Nextcloud</a>.</p>
<p>Les images valant mieux qu'un long discours, je vous mets quelques captures d'écrans qui parleront d'elles-mêmes et feront office de tutoriel (cela me semble assez intuitif pour ne pas rédiger un tutoriel complet).</p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nextcloud_polls_003.png?1606315934" width="500" height="493" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L442xH840/nextcloud_polls_004-dd517.png?1606316277" width="442" height="840" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L444xH455/nextcloud_polls_005-beefb.png?1606316277" width="444" height="455" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L442xH322/nextcloud_polls_006-c4f4f.png?1606316277" width="442" height="322" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L444xH352/nextcloud_polls_008-05143.png?1606316277" width="444" height="352" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L308xH207/nextcloud_polls_001-430f9.png?1606316277" width="308" height="207" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nextcloud_polls_002.png?1606315927" width="500" height="192" alt=""></span></p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Une-alternative-a-Framadate-Opensondage-dans-Yunohost-et-Polls-dans-Nextcloud" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>genma : <a href="">2016 ann&amp;eacute;e de l&#039;autoh&amp;eacute;bergement ?</a> (04/01/2016)</li><li>genma : <a href="">Miroirs de ce blog - Migration du blog</a> (31/08/2016)</li><li>Max Koder : <a href="">Yunohost : Nextcloud sur un disque dur externe</a> (19/07/2017)</li><li>genma : <a href="">De Framasoft &agrave; Yunohost, r&eacute;approprions nous le cloud</a> (12/11/2016)</li></ul></div></p>


title: antistress : Ma configuration de Firefox en cette fin 2020
uri: antistress-Ma-configuration-de-Firefox-en-cette-fin-2020
feed_id:
https://libre-ouvert.tuxfamily.org/index.php?article230/ma-configuration-de-firefox-en-cette-fin-2020

url:
https://libre-ouvert.tuxfamily.org/index.php?article230/ma-configuration-de-firefox-en-cette-fin-2020

content:
<p><a href="https://secure.flickr.com/photos/pierrelardinois/3780216113"><img src="media/71804802.panda-roux-pierre-lardinois-cc-by-2.0_400x266.jpg" data-original-source="https://libre-ouvert.tuxfamily.org/data/images/panda-roux-pierre-lardinois-cc-by-2.0_400x266.jpg" alt="Panda roux à l'affut" height="266" width="400"></a><br>Firefox se purgeant</p>

<p>Occasionnellement je fais une remise à zéro de mon panda roux, l'occasion de ré-évaluer ce que je garde et ce que je jette.</p>

<p>Voilà ma configuration en cette fin novembre, tandis que je roule la version 83.</p><p>Certaines modifications concernent les fonctionnalités, d'autres la vie privée, d'autres encore la sécurité ou les performances.</p>

<h3>Réglages basiques via les Préférences</h3>

<p>Après une remise à zéro (fonction « Réparer Firefox… » de la page about:support), je cours cocher « Restaurer la session précédente » dans les Préférences / section Général pour <strong>ne pas perdre tous mes onglets au redémarrage</strong>.</p>

<p>Plus anecdotique, au titre des raccourcis clavier pour naviguer dans les onglets, dans les Préférences / onglet Général / section Onglets, je décoche « Ctrl+Tab fait défiler vos onglets en les classant selon leur dernière utilisation ». <a href="https://support.mozilla.org/fr/kb/parametres-preferences-onglets">Ce comportement a été changé récemment</a>, et je préfère l'ancien comportement qui me permet de <strong>naviguer au clavier à travers mes onglets dans l'ordre dans lequel ils sont affichés</strong>.</p>

<p>Pour <strong>paramétrer un résolveur <abbr lang="en" title="DNS over HTTPS">DoH</abbr></strong>, en l’occurrence <a href="https://www.bortzmeyer.org/doh-bortzmeyer-fr-policy.html">celui de Stéphane Bortzmeyer</a> : toujours dans les Préférences / onglet Général, tout en bas à la rubrique Paramètres réseau je clique sur le bouton « Paramètres » puis je coche  « Activer le DNS via HTTPS » (si ce n'est déjà fait). Je sélectionne ensuite « Utilisez le fournisseur : personnalisé » et spécifie à la ligne du dessous : doh.bortzmeyer.fr</p>

<p>Dans les Préférences, cette fois à l'onglet Recherche, je coche « <strong>Ajouter la barre de recherche à la barre d’outils</strong> » (je trouve cette configuration plus pratique pour utiliser mes multiples moteurs de recherche – cf ci-après).</p>

<p>On finit le tour des Préférences en allant à l'onglet Vie privée et sécurité pour <strong>passer la Protection renforcée contre le pistage en mode « Stricte »</strong> (<ins>contre le pistage <em xml:lang="en" lang="en">Third-Party</em></ins>) puis pour sélectionner tout en bas de la page « <strong>Activer le mode HTTPS uniquement</strong> dans toutes les fenêtres ».</p>

<h3>Réglages avancés via la page about:config</h3>

<p>Ayant un processeur Intel avec cœur graphique intégré et un écran de définition modeste, j'aurais tort de me priver de <strong>l’accélération matérielle du rendu des pages via WebRender</strong> : je passe simplement la valeur <code>gfx.webrender.all</code> à <code>true</code> et relance le navigateur (à la page about:support, la ligne Composition doit maintenant indiquer WebRender).</p>

<p>Je demande ensuite <strong>l'accélération matérielle du décodage vidéo</strong> (nécessite que WebRender soit activé – cf ci-dessus) en passant la valeur <code>media.ffmpeg.vaapi.enabled</code> à <code>true</code>.<br>
Puis, <a href="https://wiki.libav.org/Hardware/vaapi">comme mon processeur ne prend pas en charge le décodage matériel de VP8 ni VP9</a> qui sont utilisés dans le format WebM, je passe la clé <code>media.webm.enabled</code> à <code>false</code> pour que les sites qui proposent à la fois du H264 et du WebM me servent le premier (vous pouvez préférer utiliser une extension comme  <a href="https://addons.mozilla.org/fr/firefox/addon/h264ify/">celle-ci</a> ou <a href="https://addons.mozilla.org/fr/firefox/addon/enhanced-h264ify/">celle-là</a> mais j'essaye de limiter le nombre d'extensions que j'installe).</p>

<p><a href="https://libre-ouvert.tuxfamily.org/?article72/ssd-crucial-m4-64-go-linux-trim-ext4-noatime#tmpfs">Pour économiser mon SSD</a>, je demande de <strong>stocker les fichiers temporaires en mémoire vive</strong> en passant <code>browser.cache.disk.enable</code> à <code>false</code>.</p>

<p>Pour <strong>supprimer tous les popups et les rediriger vers les onglets</strong>, je passe <code>browser.link.open_newwindow.restriction</code> à <code>0</code>.</p>

<p>Pour <strong>désactiver le punycode</strong> (<a href="https://blogmotion.fr/internet/firefox-desactiver-url-ascii-punycode-17521">en savoir plus</a>), je passe <code>network.IDN_show_punycode</code> à <code>true</code>.</p>

<p><strong><ins>Contre le pistage <em xml:lang="en" lang="en">First-Party</em></ins></strong>, j'active la fonction <em xml:lang="en" lang="en">First-Party Isolation</em> en passant <code>privacy.firstparty.isolate</code> à <code>true</code>.</p>

<p>Et pour renforcer la <strong>protection générale contre la prise d'empreinte numérique</strong> (objectif probablement impossible à atteindre malheureusement), je passe <code>privacy.resistFingerprinting</code> à <code>true</code>.</p>

<h3>Les huit extensions que je réinstalle</h3>

<p>Par ordre alphabétique :</p>

<ul><li><a href="https://addons.mozilla.org/fr/firefox/addon/copy-plaintext/">
Copy PlainText</a> : copie le texte sans son formatage ;</li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/decentraleyes/">Decentraleyes</a> : intercepte un grand nombre de requêtes de téléchargement de scripts JavaScript depuis des sites tiers et les redirige vers son stock interne (si vous utilisez uBlock Origin en mode avancé, suivez <a href="https://git.synz.io/Synzvato/decentraleyes/-/wikis/Frequently-Asked-Questions">ce conseil</a>) ;</li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/default-bookmark-folder/">Default Bookmark Folder</a> : parce que je veux que mes marque-pages soient ajoutés dans le menu des marque-pages et qu'il faut une extension pour ça, sans blague ;</li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/in-my-pocket/">In My Pocket</a> : pour accéder directement aux éléments « pocketisés » (sans quoi le truc est à peu près inutilisable) ;</li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/open-with/">Open With</a> : j'en parle <a href="https://libre-ouvert.tuxfamily.org/index.php?article232/lextension-jour-open-with-pour-firefox">ici</a>. Permet d'envoyer le lien courant vers un autre programme ;</li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/simple-context-search/">Simple Context Search</a> : j'en parle <a href="https://libre-ouvert.tuxfamily.org/index.php?article28/l-extension-jour-context-search-pour-firefox">là</a>. Permet de consommer sans modération des moteurs de recherche pour toute occasion (recherche sur le Web, sur un site marchand, de définitions, de conjugaisons, de traductions, d'images etc. etc. etc.) ;</li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/tab-tally/">Tab Tally</a> : indique en permanence le nombre de vos onglets ouverts (pour tenter de conjurer leur accroissement indéfini) ;</li>
<li><a href="https://addons.mozilla.org/fr/firefox/addon/ublock-origin/">uBlock Origin</a> : je pensais pouvoir m'en passer grâce à la Protection renforcée contre le pistage intégrée à Firefox, mais les publicités dans les vidéos YouTube toutes les cinq minutes, c'est pas possible.</li>
</ul><h3>Moteurs de recherche</h3>

<p>En attendant <a href="https://blog.mozilla.org/addons/2019/10/15/search-engine-add-ons-to-be-removed-from-addons-mozilla-org/">la fin programmée des moteurs de recherche OpenSearch</a>, je me gave des moteurs disponibles <a href="https://mycroftproject.com/search-engines.html">sur Mycroft Projet</a>.</p>
<p><img src="media/4839f6a5.470c5e17640a289d1e99b26d2dec9f54" data-original-source="http://cdn.libravatar.org/avatar/470c5e17640a289d1e99b26d2dec9f54" alt="Gravatar de antistress" class="gravatar" /><br/><i>Original post of <a href="https://libre-ouvert.tuxfamily.org/index.php?article230/ma-configuration-de-firefox-en-cette-fin-2020" title="Visit the source">antistress</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Jonathan Ernst : <a href="">Partage de donn&eacute;es et de configuration entre Windows et Linux</a> (07/05/2009)</li><li>Blogmotion : <a href="">Ajenti, l&rsquo;alternative &agrave; webmin &eacute;crite en python</a> (08/03/2014)</li><li>archi02 : <a href="">Read it Later : pour les lectures en attente</a> (14/03/2009)</li><li>Hyla project : <a href="">Hyla_Tpl passe en version 0.5 et vous souhaite de joyeuses f&amp;ecirc;tes de fin d&#039;ann&amp;eacute;e</a> (28/12/2009)</li><li>Pascal Chevrel : <a href="">Installer une version de Firefox du tronc de d&eacute;veloppement en fran&ccedil;ais !</a> (18/12/2009)</li></ul></div></p>


feed_id: https://blog.kulakowski.fr/post/ttl-pour-les-dns-locaux-sur-openwrt
title: Guillaume Kulakowski : TTL pour les DNS locaux sur OpenWRT
uri: Guillaume-Kulakowski-TTL-pour-les-DNS-locaux-sur-OpenWRT
url: https://blog.kulakowski.fr/post/ttl-pour-les-dns-locaux-sur-openwrt
content:
<p>Récemment, je me suis un peu amusé avec AdGuard Home sur mon routeur OpenWRT. J’y ai rapidement constaté que mon serveur NAS ainsi que ma box domotique faisaient énormément d’appels au DNS. En effet, avec l’utilisation systématique de baux statiques et de noms de domaine locaux, j’ai remplacé les IPs de certain composant par leur […]</p>
<p>Cet article <a rel="nofollow" href="https://blog.kulakowski.fr/post/ttl-pour-les-dns-locaux-sur-openwrt">TTL pour les DNS locaux sur OpenWRT</a> est apparu en premier sur <a rel="nofollow" href="https://blog.kulakowski.fr/">Guillaume Kulakowski's blog</a>.</p>
<p><img src="media/9719583b.7e5813be2b1eaef89d90a5b456bb1970" data-original-source="http://cdn.libravatar.org/avatar/7e5813be2b1eaef89d90a5b456bb1970" alt="Gravatar de Guillaume Kulakowski" class="gravatar" /><br/><i>Original post of <a href="https://blog.kulakowski.fr/post/ttl-pour-les-dns-locaux-sur-openwrt" title="Visit the source">Guillaume Kulakowski</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://fortintam.com/blog/cones-oranges-du-libre-et-chantiers-technologiques/
uri: Kiddo-Les-cônes-oranges-du-libre-du-ramollissement-de-l-enthousi
url: https://fortintam.com/blog/cones-oranges-du-libre-et-chantiers-technologiques/
title:
Kiddo : Les cônes oranges du libre: du ramollissement de l’enthousiasme face aux chantiers technologiques

content:
<p>Dans <a rel="noreferrer noopener" href="https://libre-ouvert.tuxfamily.org/index.php?article235/joyeux-anniversaire-a-moi-15-ans-gnulinux" target="_blank">ce billet</a>, l’ami “Antistress” (Thibaut) fait un état des lieux des grands changements technologiques du libre autour de la plateforme GNU+Linux depuis une quinzaine d’années, lorsque plusieurs d’entre nous ont commencé à utiliser cette plateforme plus intensivement. Il y laisse également transpirer un certain épuisement, ou “manque d’excitation”, qui est probablement ressenti par plusieurs d’entre nous.</p>


<span></span>


<p>Pour ma part j’ai commencé à bidouiller avec Linux en 2003, mais ce n’est qu’avec la première version d’Ubuntu, 4.10, que j’ai pu y coller à plein temps (note: je suis passé à Fedora <a href="https://fortintam.com/blog/pourquoi-je-quitte-ubuntu-pour-fedora/" data-type="post" data-id="1826">depuis 2010</a>). Et depuis, ça a été une histoire de patience. Beaucoup, beaucoup de patience.</p>



<p>Je vois souvent des parallèles entre le monde du logiciel libre et la ville de Montréal. Comme les chantiers dans les rues de Montréal qui semblent éternels (au point où nous avons <a rel="noreferrer noopener" href="https://minyaka.com/ponto/" target="_blank">un cône orange qui nous sert de mascotte informelle</a>), on a l’impression de ne pas voir le bout de nos chantiers technologiques.</p>



<figure><img loading="lazy" width="1024" height="655" src="media/9f84063f.montreal-cones-oranges-le-devoir-1024x655.jpg" data-original-source="https://fortintam.com/blog/wp-content/uploads/montreal-cones-oranges-le-devoir-1024x655.jpg" alt="" srcset="https://fortintam.com/blog/wp-content/uploads/montreal-cones-oranges-le-devoir-1024x655.jpg 1024w, https://fortintam.com/blog/wp-content/uploads/montreal-cones-oranges-le-devoir-500x320.jpg 500w, https://fortintam.com/blog/wp-content/uploads/montreal-cones-oranges-le-devoir-768x492.jpg 768w, https://fortintam.com/blog/wp-content/uploads/montreal-cones-oranges-le-devoir-1536x983.jpg 1536w, https://fortintam.com/blog/wp-content/uploads/montreal-cones-oranges-le-devoir-1320x845.jpg 1320w, https://fortintam.com/blog/wp-content/uploads/montreal-cones-oranges-le-devoir.jpg 1656w" sizes="(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px"><figcaption>Les cônes oranges typiques du paysage montréalais, une photo du Devoir (pour mes besoins de parodie)</figcaption></figure><p>La tâche de modernisation technologique de notre système d’opération favori est colossale, a impliqué nombre d’individus et de compagnies (qui sont venues et parties à divers moments des “desktop wars” et “mobile wars”), et nombres de rebondissements et apprentissages en cours de route. On peut penser notamment:</p>



<ul><li>à Xorg et ses multiples tentatives d’avoir du compositing qui tienne la route (incluant XGL, AIGLX, Compiz/Beryl, Metacity vs Mutter, GNOME Shell, KWin) et l’éventuel ras-le-bol-on-recommence-avec-une-architecture-qui-ne-date-pas-des-années-70 qu’est Wayland (visionnement obligatoire: cette <a rel="noreferrer noopener" href="https://www.youtube.com/watch?v=GWQh_DmDLKQ" target="_blank">merveilleuse présentation</a> de Daniel Stone);</li><li>au chantier du multimédia avec GStreamer et PulseAudio (et maintenant/prochainement: PipeWire);</li><li>au long combat de modernisation de la technologie de Firefox pour survivre face à l’<a rel="noreferrer noopener" href="https://idlewords.com/talks/website_obesity.htm" target="_blank">épidémie d’obésité du web</a> et rattraper les performances de Chrome/Chromium;</li><li>à l’attente de pilotes graphiques libres, performants et stables pour les cartes graphiques AMD (depuis leur changement de stratégie circa 2010 où AMD s’est mise à publier de la documentation pour soutenir les pilotes libres, et quelques années plus tard aller plus loin et rationaliser leurs pilotes propriétaires avec les pilotes libres);</li><li>à l’interminable migration de l’écosystème d’applications GTK2 vers GTK3 (juste à temps pour GTK4, tiens!), idem pour Python 2 vs Python 3;</li><li>à l’interminable attente, de 2010 à 2019, pour que des gens compétents se penchent de manière concertée sur la question de l’optimisation de performances de GNOME Shell (depuis 3.36 et 3.38, c’est le pur bonheur);</li><li>etc.</li></ul><p>Dans le monde du libre, nous sommes tous un peu sado-masos. Masochistes pour ce qui est de la patience dont nous devons faire preuve, et sadiques dans notre relation amour-haine envers nos logiciels favoris (je ne me suis pas gêné, par le passé, pour être assez critique sur mon blog concernant les performances de Firefox; critiques qui sont, une décennie plus tard, enfin résolues), de la même façon que les Montréalais(e)s ont <a rel="noreferrer noopener" href="https://www.ledevoir.com/societe/transports-urbanisme/524276/a-force-d-autoderision-le-cone-orange-est-devenu-une-icone-aimee-des-quebecois" target="_blank">une relation amour-haine avec les cônes oranges</a> (même sans être fans de VLC). Et c’est sans compter la déprimante hégémonie de Google et Apple dans le monde du mobile au sein de la population, ce qui confine notre impact au monde du “desktop”.</p>



<p>Alors effectivement, après toutes ces années, on devient un peu moins excités que dans notre jeunesse où on se faisait fervents évangélistes du libre. Thibaut est assez clair lorsqu’il écrit ceci:</p>



<blockquote><p>[…] je dirais qu’à part pour le premier item (la finalisation des chantiers en cours de Firefox sous GNU/Linux), je manque un peu d’excitation.</p></blockquote>



<p>Pour expliquer ce phénomène, je crois que je dirais ceci: du côté “desktop Linux” il y a eu beaucoup de progrès un peu partout au fil des années, et <strong>une des raisons pour laquelle nous sommes peut-être moins excités par rapport aux nouveautés sur nos ordinateurs, c’est aussi parce que “globalement, ça marche maintenant”</strong> (vous souvenez-vous de l’époque pré-Xorg où on devait s’attendre à ce que l’interface graphique ne fonctionne pas au premier démarrage? et l’époque 2004-2012 où on devait se battre pour avoir du WiFi qui fonctionne? Heureusement je n’ai plus croisé de Broadcom dans les dernières années…).</p>



<p>Donc, il ne reste plus <em>tant</em> de choses criantes que ça à régler. Et ce qui reste à régler… remplace souvent des choses qui “fonctionnent”. De 2003 à 2013 environ, j’ai eu plusieurs situations où mon <a rel="noreferrer noopener" href="https://fr.wikipedia.org/wiki/Ext4" target="_blank">système de fichiers ext4</a> s’est spontanément corrompu “par lui-même”, sans explication (alors que ext4 était supposément stable et largement testé depuis des années). Depuis 2013-2014, ça ne m’est plus arrivé. Alors, pour reprendre le constat d’Antistress concernant l’adoption modeste de Btrfs, <em>excusez-moi,</em> mais je n’ai aucun intérêt ni enthousiasme à reformatter mon disque dur 2 teraoctets (détenant mon /home) de ext4 vers Btrfs. Ni l’empressement de passer à <a rel="noreferrer noopener" href="https://getfedora.org/fr/silverblue/" target="_blank">Fedora Silverblue</a> au lieu de <a rel="noreferrer noopener" href="https://getfedora.org/fr/workstation/" target="_blank">Fedora Workstation</a>. Je vais laisser les nouveaux jeunes s’amuser avec ça!</p>
<p><img src="media/bb18a5c3.ca9664d6eee3bdf362c3741adb83e4bb" data-original-source="http://cdn.libravatar.org/avatar/ca9664d6eee3bdf362c3741adb83e4bb" alt="Gravatar de Kiddo" class="gravatar" /><br/><i>Original post of <a href="https://fortintam.com/blog/cones-oranges-du-libre-et-chantiers-technologiques/" title="Visit the source">Kiddo</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Kiddo : <a href="">R&eacute;seau pare-balles</a> (22/07/2009)</li><li>Kiddo : <a href="">Lissage sous-pixel dans Ubuntu 9.04</a> (29/03/2009)</li><li>Kiddo : <a href="">SSH vs VPN</a> (17/03/2009)</li><li>Kiddo : <a href="">Killer Feature de Network Manager 0.7</a> (14/03/2009)</li><li>Kiddo : <a href="">Quelques agr&eacute;ables nouveaut&eacute;s de GNOME 2.28 et Ubuntu 9.10</a> (31/10/2009)</li></ul></div></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #48
uri: 2020-11-30-Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-48
feed_id:
https://blog.journalduhacker.net/index.php?article299/liens-interessants-journal-du-hacker-semaine-48-2020

url:
https://blog.journalduhacker.net/index.php?article299/liens-interessants-journal-du-hacker-semaine-48-2020

content:
<p>Pour la 48ème semaine de l'année 2020, voici <strong>10 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/cikgjm/ils_cherchent_les_trucs_bizarres_qu_il_y">Ils cherchent “les trucs bizarres qu’il y a dans vos téléphones” : rencontre avec des traqueurs de trackers</a></li>
<li><a href="https://www.journalduhacker.net/s/lcimwd/la_liste_des_alternatives_lets_encrypt">La liste des alternatives à Let's Encrypt offrant des certificats gratuits via ACME s'agrandit</a></li>
<li><a href="https://www.journalduhacker.net/s/efaqq5/hauts_et_bas_du_courrier_du_hacker_au_150_me">Hauts et bas du Courrier du hacker au 150ème numéro</a></li>
<li><a href="https://www.journalduhacker.net/s/kshttj/devenir_plus_confiant_en_tant_que_d">Devenir plus confiant en tant que développeur(euse)</a></li>
<li><a href="https://www.journalduhacker.net/s/n7a9ay/sortie_de_gcompris_1_0_et_joyeux">Sortie de GCompris 1.0 (et joyeux anniversaire !)</a></li>
<li><a href="https://www.journalduhacker.net/s/k96r8i/je_ne_suis_pas_bien_dans_la_teams_billet">Je ne suis pas bien dans la Teams, billet ouvert à la présidence de l'université Lyon2</a></li>
<li><a href="https://www.journalduhacker.net/s/cgxaor/keepass_ou_apprendre_g_rer_correctement">KeePass, ou apprendre à gérer correctement ses mots de passe</a></li>
<li><a href="https://www.journalduhacker.net/s/votlns/quelques_r_flexions_sur_la_sauvegarde">Quelques réflexions sur la sauvegarde</a></li>
<li><a href="https://www.journalduhacker.net/s/u54wyt/construire_un_clavier_m_canique_pour_le">Construire un clavier mécanique pour le fun (2017)</a></li>
<li><a href="https://www.journalduhacker.net/s/jqxi6y/installation_de_debian_sur_des_machines">Installation de Debian sur des machines ARM</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://twitter.com/journalduhacker">Le compte Twitter du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article299/liens-interessants-journal-du-hacker-semaine-48-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #48</a> (05/12/2016)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #48</a> (04/12/2017)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #48</a> (03/12/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #48</a> (02/12/2019)</li></ul></div></p>


feed_id: https://shadoware.org/post/creation-api-3
title: Ulrich Van Den Hekke : Comment créer une bonne API Web - Partie 3
uri: Ulrich-Van-Den-Hekke-Comment-créer-une-bonne-API-Web-Partie-3
url: https://shadoware.org/post/creation-api-3
content:
<p>Bonjour,</p>
<p>Cet article fait partie d'un ensemble:</p>
<ul><li><a href="https://shadoware.org/2020-09-26_creation-api-1.md">Généralités sur l'écriture d'une bonne API</a></li>
<li><a href="https://shadoware.org/2020-09-26_creation-api-2.md">Qu'est ce qu'une API REST</a></li>
<li><a href="https://shadoware.org/2020-09-26_creation-api-3.md">Qu'est ce qu'une API GraphQL</a></li>
</ul><p>Il y a quelques années de cela, j'ai souhaité résoudre un problème que j'ai depuis longtemps avec les API REST: comment bien
normaliser les tris, les projections, et les filtres. En effectuant mes recherches je suis tombé sur deux frameworks qui permettent
de résoudre le problème des projections.</p>
<h2>Qu'est qu'une API Falcor</h2>
<p>Je ne vais parler que succinctement de Falcor. C'est un framework que je n'ai pas utilisé mais j'ai tout de même été très intéressé
par ce dernier et je vais écrire quelques lignes sur ce Framework.</p>
<p>Pour plus d'informations, vous pourrez vous référer à la <a href="https://netflix.github.io/falcor/starter/what-is-falcor.html">documentation</a>.</p>
<p>Pour reprendre les explications de la documentation, Falcor est un middleware de votre application qui permet d'interroger des ressources
au format JSON sur le serveur, comme votre application le ferait sur des données en mémoire.</p>
<p><img alt="Falcor" src="media/a445137b.network-diagram.png" data-original-source="https://netflix.github.io/falcor/documentation/network-diagram.png"></p>
<p>La requête envoyée alors au serveur ne contient que les champs demandés par le client, ce qui permet au serveur de sélectionner les champs
et de ne retourner que ces champs. De plus le serveur peut n'exposer qu'un seul modèle contenant toutes les ressources (que ce soit pour
retourner des listes ou des items particuliers).</p>
<p>En une seule requête, le client peut alors demander l'ensemble des données dont il a besoin, et l'afficher.</p>
<p>Nous n'avons plus alors le dilemne "faut-il créér une sous-resource, ou l'intégrer dans la ressource actuelle ?". Du point de vue du client:
plus besoin d'effectuer plusieurs requêtes complexes pour récupérer plusieurs ressources, un seul appel suffit.</p>
<div><pre><span></span><span>/model.json?paths=["user.name", "user.surname", "user.address"]</span>

<span>GET</span> <span>/</span><span>model</span><span>.</span><span>json</span><span>?</span><span>paths</span><span>=</span><span>[</span><span>"user.name"</span><span>,</span> <span>"user.surname"</span><span>,</span> <span>"user.address"</span><span>]</span>
<span>{</span>
  <span>user</span><span>:</span> <span>{</span>
    <span>name</span><span>:</span> <span>"Frank"</span><span>,</span>
    <span>surname</span><span>:</span> <span>"Underwood"</span><span>,</span>
    <span>address</span><span>:</span> <span>"1600 Pennsylvania Avenue, Washington, DC"</span>
  <span>}</span>
<span>}</span>
</pre></div>


<p>Le <code>Router</code> falcor côté serveur, s'occupe alors de dispatcher les différentes parties demandées par le client à différents backends, qui peuvent
alors répondre indépendament les uns des autres.
Falcor va s'occuper alors d'aggréger le résultat.</p>
<p><img alt="Diagramme de service" src="media/5d87a4d5.services-diagram.png" data-original-source="https://netflix.github.io/falcor/images/services-diagram.png">.</p>
<p>Pour récupérer des données depuis le front:</p>
<div><pre><span></span><span>// ask for name and age of user with id = 5</span>
<span>model</span><span>.</span><span>get</span><span>(</span><span>"users[5]['name','age']"</span><span>);</span><span>// which will eventually return something like</span>
<span>{</span>
  <span>"users"</span><span>:</span> <span>{</span>
    <span>"5"</span><span>:</span> <span>{</span>
      <span>"name"</span><span>:</span> <span>"John Doe"</span><span>,</span>
      <span>"age"</span><span>:</span> <span>33</span>
    <span>}</span>
  <span>}</span>
<span>}</span><span>// you can also ask for ranges</span>
<span>model</span><span>.</span><span>get</span><span>(</span><span>"users[5..7].name);// which eventually returns the following</span>
<span>{</span>
<span>  "</span><span>users</span><span>": {</span>
<span>    "</span><span>5</span><span>": { "</span><span>name</span><span>": "</span><span>John</span> <span>Doe</span><span>" },</span>
<span>    "</span><span>6</span><span>": { "</span><span>name</span><span>": "</span><span>Jane</span> <span>Doe</span><span>" },</span>
<span>    "</span><span>7</span><span>": { "</span><span>name</span><span>": "</span><span>Mary</span> <span>Poppins</span><span>"</span> <span>}</span>
  <span>}</span>
<span>}</span>
</pre></div>


<p>L'avantage de ce framework, est qu'il permet de simplifier l'écriture des projections et de la partie lecture d'une API.</p>
<p>Ce pourquoi je n'ai pas choisi ce framework vient en deux choses:</p>
<ul><li>Il est disponible principalement pour Javascript (NodeJS + Front) ; Il existe une version Java même qui n'a pas été mise à jour
  depuis 2018 et donc je ne retrouve pas les sources.</li>
<li>J'ai trouvé mieux en GraphQL.</li>
</ul><h2>Qu'est qu'une API GraphQL</h2>
<p>Venant du constat que Falcor répondait à mon besoin de pouvoir normaliser la projection mais avec quelques limites, j'ai continué mes
recherches et je suis tombé sur GraphQL.</p>
<p>GraphQL répond à la même problèmatique: pouvoir laisser au client choisir la projection qu'il souhaite des données. Comme Falcor,
GraphQL permet de ramener plusieurs ressources en une requête. Et comme Falcor, GraphQL permet d'aggréger le résultat côté serveur
de façon asynchrone.</p>
<p>L'avantage de GraphQL sur Falcor est que GraphQL est une norme écrite par Facebook alors que Falcor est une librairie Javascript.
De la norme GraphQL, découle une implémentation officielle en Javascript mais aussi dans plein d'autres languages.</p>
<p>Par contre GraphQL n'est qu'un language de requête. Il ne décrit pas comment doit être transportée la requête sur le réseau, ni
comment doit être transférée la réponse. Seul le contenu est normalisé. Les frameworks sont tout de même compatibles entre eux.</p>
<p>Par contre cela permet d'utiliser GraphQL pour autre chose que des requêtes réseaux. On pourrait envisager de faire un service qui
ne répond qu'à des requêtes GraphQL. Ce service est alors rattaché au contrôleur pour une exposition mais aussi directement
appelable en interne par d'autres services. Cela pourrait permettre de faire une couche d'abstraction interne.</p>
<p>Il existe plusieurs frameworks ajoutant la couche de transport à GraphQL. Dans la suite je parlerai d'une des implémentations qui se
nomme <a href="https://www.apollographql.com/">Apollo</a>.</p>
<p>Maintenant passons au vif du sujet.</p>
<h3>Query - Introduction</h3>
<p>Le système de requête de graphql permet au client de décrire ce qu'il souhaite récupérer. C'est au client de décider des éléments
qu'il souhaite et de construire sa requête.</p>
<p>Voici un exemple de requête de requête:</p>
<div><pre><span></span>query Dashboard {
  queueStats {
    waiting
    active
    failed
    lastExecution
    nextWakeup
  }
  diskUsageStats {
    currentRepartition {
      host
      total
    }
    currentSpace {
      size
      used
    }
  }
}
</pre></div>


<p>Derrière chaqu'un des membres ci-dessus, on peut retrouver un resolver. Un resolver c'est l'équivalent du contrôleur pour une API REST.
C'est le resolver qui va récupérer les informations demandées par le client (arguments, projection, ...) et les transférer au service.</p>
<p>Il nous faudra alors faire un lien entre le schéma et ces resolvers. Pour le client, peu importe qu'il faille, pour une requête, exécuter
en tâche de fond 1 resolver ou 10 resolver. Le client n'a pas besoin de le savoir.</p>
<p>Imaginons que dans l'exemple ci-dessous le champs <code>nextWakeup</code> nécessite un calcul complexe. Il suffit de créer un resolver qui
effectue ce calcul.
Si jamais le client n'a pas besoin de l'afficher et du coup, ne le demande pas, alors ce calcul complexe ne sera pas fait et c'est du temps
de traitement gagné sur le serveur.</p>
<p>En REST, un champ qui nécessite un calcul complexe et soit</p>
<ul><li>inclus dans la resource et donc toujours effectué quelque soit le besoin du client</li>
<li>séparé dans une ressource séparée, au risque de complexifier l'API et de demander au client de faire plusieurs requêtes si nécessaire (surtout si
  on a plus d'un champ calculé).</li>
</ul><h3>Nommer ces requêtes</h3>
<p>Dans l'exemple ci-dessus, on peut remarquer que la requête possède un nom. C'est une bonne pratique de toujours nommer l'opération
(ici <code>Dashboard</code>). Nommer les opérations permet de :</p>
<ul><li>mettre plusieurs opérations nommées dans une seule requête.</li>
<li>mais aussi de mieux tracer et débugger les requêtes côté serveur dans les logs.</li>
</ul><h3>Query - Coté serveur</h3>
<p>Côté serveur nous allons commencer par décrire le schéma que pourra alors utiliser le client pour effectuer ces requêtes. Par exemple :</p>
<div><pre><span></span>scalar Date

"""
Define the state of the queue
"""
type QueueStats {
  """
  Number of task waiting in queue
  """
  waiting: Int!
  """
  Number of task active in queue
  """
  active: Int!
  """
  Number of task that have failed
  """
  failed: Int!
  """
  Date of the last execution
  """
  lastExecution: Date!
  """
  Date of the next wakeup
  """
  nextWakeup: Date!
}

type DiskCurrentRepartition {
  host: Int!
  total: Int!
}

type DiskCurrentSpace {
  size: Int!
  used: Int!
}

type DiskUsageStats {
  currentRepartition: [DiskCurrentRepartition!]!
  currentSpace: DiskCurrentSpace!
}

type Query {
  queueStats: QueueStats!
  diskUsageState: DiskUsageStats!
}
</pre></div>


<p>On peut remarquer plusieurs choses:</p>
<ul><li>Tous les champs ont un type (String, Int, Float, Array, Date)</li>
<li>Il est possible de créer de nouveaux types simples, scalaires: par exemple champ de type Date.</li>
<li>Il est possible de créer de nouveaux types complexes, ce qui en fait nos structures.</li>
<li>Le point d'exclamation permet d'indiquer que le champ retourné ne sera jamais null (et donc le client peut compter dessus s'il le souhaite).</li>
<li>Il est possible de mettre de la documentation au niveau de chaque champ mais aussi au niveau des types.</li>
</ul><p>Ce schéma (qui peut aussi être généré à l'aide d'annotations en Typescript, <a href="https://docs.nestjs.com/graphql/resolvers#code-first-resolver">par exemple</a>)
sert également de documentation (un peu comme swagger).</p>
<p>Il est alors possible d'utiliser des outils comme</p>
<ul><li><a href="https://2fd.github.io/graphdoc/">Graph Doc</a>,</li>
<li><a href="https://docql.io/">DocQL</a>,</li>
<li><a href="https://github.com/APIs-guru/graphql-voyager">GraphQL Voyager</a>, et</li>
<li><a href="https://github.com/wayfair/dociql">Doc iQL</a></li>
</ul><p>pour générer de la documentation mais aussi des outils comme</p>
<ul><li><a href="https://github.com/graphql/graphql-playground">GraphQL Playground</a></li>
<li><a href="https://github.com/graphql/graphiql">GraphiQL</a> qui sont des IDE permettant de faire des requêtes (avec documentation et auto-completion).</li>
</ul><p>Une fois le schéma écrit, il peut être communiqué aux équipes front (si les équipes sont séparées). Pendant que l'on développe alors le front, côté
serveur on peut alors implémenter le schéma.</p>
<p>Pour implémenter le schéma ci-dessus, nous allons écrire un resolver (en Javascript pour l'exemple).</p>
<div><pre><span></span><span>const</span> <span>resolvers</span> <span>=</span> <span>{</span>
  <span>Query</span><span>:</span> <span>{</span>
    <span>queueStats</span><span>()</span> <span>{</span>
      <span>return</span> <span>getQueueStats</span><span>();</span>
    <span>},</span>
    <span>async</span> <span>diskUsageState</span><span>()</span> <span>{</span>
      <span>return</span> <span>await</span> <span>getDiskUsageState</span><span>();</span>
    <span>},</span>
  <span>},</span>
<span>};</span>
</pre></div>


<p>Un resolver peut pour un champ:</p>
<ul><li>retourner une valeur</li>
<li>retourner une fonction qui retourne la valeur</li>
<li>retourner une fonction qui retourne une promesse avec la valeur</li>
</ul><p>Ainsi imaginons que la méthode <code>getQueueStats()</code> retourne l'objet suivant, dans lequel il manque <code>nextWakeup</code> et <code>lastExecution</code> :</p>
<div><pre><span></span><span>{</span>
  <span>"waiting"</span><span>:</span> <span>0</span><span>,</span>
  <span>"active"</span><span>:</span> <span>2</span><span>,</span>
  <span>"failed"</span><span>:</span> <span>0</span>
<span>}</span>
</pre></div>


<p>Il est possible d'écrire un resolver :</p>
<div><pre><span></span><span>const</span> <span>resolvers</span> <span>=</span> <span>{</span>
  <span>Query</span><span>:</span> <span>{</span>
    <span>queueStats</span><span>()</span> <span>{</span>
      <span>return</span> <span>getQueueStats</span><span>();</span>
    <span>},</span>
    <span>async</span> <span>diskUsageState</span><span>()</span> <span>{</span>
      <span>return</span> <span>await</span> <span>getDiskUsageState</span><span>();</span>
    <span>},</span>
  <span>},</span>
  <span>QueueStats</span><span>:</span> <span>{</span>
    <span>lastExecution</span><span>(</span><span>parent</span> <span>/*: QueueStats */</span><span>)</span> <span>{</span>
      <span>const</span> <span>{</span> <span>active</span> <span>}</span> <span>=</span> <span>parent</span><span>;</span> <span>// Ici pour l'exemple on peut récuperer un attribut de parent.</span>
      <span>return</span> <span>getLastExecution</span><span>();</span>
    <span>},</span>
    <span>nextWakeup</span><span>()</span> <span>{</span>
      <span>return</span> <span>getNextWakup</span><span>();</span>
    <span>},</span>
  <span>},</span>
<span>};</span>
</pre></div>


<p>Il est alors possible de créer son schéma en pensant à comment le client va intéroger ce dernier, et lors de l'implémentation ajouter des structures
complexes qui sont issues du calcul synchrone ou asynchrone des données.</p>
<h3>Query - Nullable</h3>
<p>On a vu précédement qu'on pouvait utiliser le point d'exclamation pour indiquer qu'un champ ne sera jamais NULL. Cela peut avoir des avantages pour le client
mais cela a aussi de grandes implications côté serveur.</p>
<p>Par défaut pour GraphQL, tous les champs sont nullable par défaut. En effet, si un resolver n'arrive pas à récupérer la donnée (erreur côté serveur, back HS, problème
de base de données, problème réseau, droits d'accès différents selon les champs ...), le serveur pourra retourner NULL à la place de la valeur (et une erreur en
parallèle du json). Cela permet au client une vue partielle même si certains services ne sont pas disponibles.</p>
<p>Si le champ ne peut pas être null, alors le json ne pourra pas du tout être envoyé et c'est la requête complète qui est en ereur.</p>
<p>C'est pour cela qu'en GraphQL chaque champ peut, par défaut, obtenir la valeur null.</p>
<p>Lors de la conception d'un schéma GraphQL, il faut utiliser la possibilité de rendre le champ non nullable avec réflexion et uniquement pour les champs dont on
souhaite garantir la non nullité.</p>
<h3>Query - Ajout d'arguments</h3>
<div><pre><span></span>query HeroNameAndFriends($episode: Episode) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}
</pre></div>


<p>Il est possible en GraphQL de définir certain champs comme ayant des paramètres. Ils seront alors passés au resolver. Il est également possible d'avoir
des paramètres à différents niveaux du schéma (pas seulement au niveau le plus haut).</p>
<p>Le passage de paramètres permet d'écrire son opération une fois et ensuite de l'appeler avec des paramètres. C'est important de définir les saisie utilisateurs
comme des paramètres pour éviter les injections GraphQL (comme en SQL, ou autre).</p>
<p><strong>Règle n°1</strong>: Ne jamais faire confiance à l'utilisateur.</p>
<h3>Query - Création d'alias</h3>
<p>Si on souhaite récupérer plusieurs valeurs d'un attribut en fonction de ses paramètres, il est possible de le demander plusieurs fois et de lui associer
un alias.</p>
<div><pre><span></span>query aliasQuery {
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}
</pre></div>


<p>Dans le JSON résultant, on retrouve alors les deux attributs <code>empireHero</code> et <code>jediHero</code> qui sont tous les deux issus du membre <code>hero</code> avec un paramètre
différent. Cela peut aussi être utilisé pour simplement renommer un champ.</p>
<h4>Query - Fragment</h4>
<p>Les fragments permettent de factoriser et de créer des morceaux de requêtes réutilisables.</p>
<div><pre><span></span><span># Dans le fichier FragmentJob.graphql</span>

<span>fragment</span> <span>FragmentJob</span> <span>on</span> <span>Job</span> <span>{</span>
  <span>id</span>
  <span>state</span>
  <span>failedReason</span>
  <span>data</span> <span>{</span>
    <span>host</span>
  <span>}</span>
<span>}</span>

<span># Dans le fichier QueueTasks.graphql</span>

<span>#import "./FragmentJob.graphql"</span>

<span>query</span> <span>QueueTasks</span><span>(</span><span>$</span><span>state</span><span>:</span> <span>[</span><span>String</span><span>!</span><span>])</span> <span>{</span>
  <span>queue</span><span>(</span><span>state</span><span>:</span> <span>$</span><span>state</span><span>)</span> <span>{</span>
    <span>...</span><span>FragmentJob</span>
  <span>}</span>
<span>}</span>
</pre></div>


<p>Le Fragment <code>FragmentJob</code> peut alors être réutilisé dans différentes requêtes, voir même plusieurs fois dans la même requête.</p>
<h3>Query - Gestion de version</h3>
<p>J'en parlais dans les articles précédents, il existe plusieurs manières de versionner une API. GraphQL n'y échappe pas. On peut:</p>
<ul><li>ajouter un numéro de version dans le path de l'url, dans le nom de l'hôte, dans un header http.</li>
<li>ou décider de gérer une seule API rétro-compatible où on décommissionne au fur et à mesure les champs.</li>
</ul><p>Les créateurs de GraphQL partagent <a href="https://graphql.org/learn/best-practices/#versioning">leur opinions</a>. Comme c'est le client qui décide
des champs qu'il souhaite rappatrier, toute évolution du schéma ajoutant de nouveaux attributs ne pose aucun problème et ne surchargera pas
plus le client.
Les suppressions doivent passer par une phase d'obsolescence ou les attributs sont marqués avec l'annotation <code>@deprecated</code> et leur décommissionnement
automatique.</p>
<p>Afin de pouvoir facilement décommissionner des attributs, le mieux est de savoir quels attributs sont utilisés ou non. La librairie Apollo permet de
se connecter au <a href="https://studio.apollographql.com/">studio d'appolo</a> et de visualiser l'utilisation des attributs. Savoir qu'un attribut n'est pas
utilisé permet de le décommissionner ou de le modifier. Bien sûr et malheureusement cette partie n'est pas open source. Je n'ai pas encore trouvé de
dashboard OpenSource permettant d'analyser l'utilisation d'un champ.</p>
<p>Ce qui est important c'est d'avoir une politique de versionning.</p>
<h3>Query - Pagination</h3>
<p>GraphQL n'a pas défini de règle concernant la pagination car il y a plein de manières de la gérer. Pour des listes contenant peu d'éléments, il n'y a
par exemple pas lieu de gérer la pagination.</p>
<p>Quand on envisage la pagination, on peut en faire une par page avec un nombre d'éléments à passer (skip), ou une basée sur l'id du premier élément
à afficher.</p>
<p>Il existe également des patterns que l'on peut utiliser pour ne pas réinventer une nouvelle facon de faire.</p>
<p>Par exemple l'un de ses patterns s'appele <code>Connections</code> et des librairies comme <code>Relay</code> savent comment gérer automatiquement ce pattern.</p>
<p>Dans le pattern <code>Connections</code>, nous retrouvons les notions:</p>
<ul><li>
<p>En entrée</p>
</li>
<li>
<p>nombre d'éléments à récupérer</p>
</li>
<li>
<p>le curseur à partir duquel retourner les données</p>
</li>
<li>
<p>En sortie</p>
</li>
<li>Le nombre d'éléments total</li>
<li>Les informations sur la page comme le prochain curseur et si on a une page suivante</li>
<li>Les différents éléments de la page (avec le curseur associé)</li>
</ul><div><pre><span></span>{
  hero {
    name
    friendsConnection(first: 2, after: "Y3Vyc29yMQ==") {
      totalCount
      edges {
        node {
          name
        }
        cursor
      }
      pageInfo {
        endCursor
        hasNextPage
      }
    }
  }
}
</pre></div>


<p>On peut retrouver la spécification de ce modèle de pagination sur le site de <a href="https://relay.dev/graphql/connections.htm">relay.dev</a></p>
<h3>Query - Cache - Control</h3>
<p>Contrairement au REST où on peut peut utiliser les header HTTP, pour contrôler le cache, en GraphQL une requête peut avoir des limites d'âge différentes sur les différentes resources
appelées. Il faut donc trouver d'autres moyens de gérer le cache.</p>
<p>C'est pour moi un des points les plus gênants de GraphQL.</p>
<p>Sur le serveur, il y a plusieurs manières complémentaires (à différentes fins) de gérer le cache. Nous allons nous concentrer sur la librairie <code>apollo-server</code>.</p>
<p>La 1ère manière s'apparentant au cache-control des requêtes HTTP peut être utilisée avec la directive <code>@cacheControl</code> ou au niveau du resolver. Elle ne permet pas de cacher directement la donnée
mais de donner une indication au client sur combien de temps cette donnée peut-être cachée. Si la librairie utilisée côté client est également <code>apollo</code> elle utilisera alors ces indications pour
gérer le cache de la donnée (et donc ne pas ré-effectuer la requête.)</p>
<div><pre><span></span>scalar Date

"""
Define the state of the queue
"""
type QueueStats @cacheControl(maxAge: 60) {
  """
  Number of task waiting in queue
  """
  waiting: Int!
  """
  Number of task active in queue
  """
  active: Int!
  """
  Number of task that have failed
  """
  failed: Int!
  """
  Date of the last execution
  """
  lastExecution: Date! @cacheControl(maxAge: 3600)
  """
  Date of the next wakeup
  """
  nextWakeup: Date! @cacheControl(maxAge: 3600)
}
</pre></div>


<p>Je vous invite à lire la <a href="https://www.apollographql.com/docs/apollo-server/performance/caching/">documentation d'apollo</a> qui contient énormément d'informations. Cette méthode permet d'ajouter
des header http pour cacher les requêtes dans un CDN intérmédiaire, ou dans une base redis attachée au serveur, ou dans le cache navigateur, voir également au niveau même du client.</p>
<h3>Query - Cache - DataLoader</h3>
<p>La 2nd méthode de cache consiste à l'utilisation de <a href="https://github.com/graphql/dataloader">DataLoader</a>. L'ajout d'un dataloader a pour but de cacher le temps d'une requête les différents éléments pour éviter de multiplier les appels.
Le but n'étant pas de réellement faire du cache mais plutôt de pouvoir traiter une requête batch le plus rapidement possible.</p>
<p>Imaginons par exemple la requête suivante :</p>
<div><pre><span></span>query TestDataLoader {
  backups {
    id
    startDate
    endDate
    user {
      firstName
      lastName
    }
  }
}
</pre></div>


<p>Dans le cas présent, on souhaite récupérer les backups, mais également pour chaque backup récupérer l'utilisateur. Si l'utilisateur est le même pour chaque backup, on se retouve alors à charger
l'utilisateur plusieurs fois. Le fait d'utiliser un dataloader permettra dans le cas présent de ne les charger qu'une fois.</p>
<p>Pour utiliser le système de data loader, on peut utiliser la bibliothèque du même nom: <a href="github:%20graphql/dataloader">https://github.com/graphql/dataloader</a>. Il nous faut alors créer un dataloader pour
un type d'objet.</p>
<div><pre><span></span><span>import</span> <span>DataLoader</span> <span>from</span> <span>"dataloader"</span><span>;</span>

<span>const</span> <span>userLoader</span> <span>=</span> <span>new</span> <span>DataLoader</span><span>((</span><span>keys</span><span>)</span> <span>=></span> <span>service</span><span>.</span><span>getUsers</span><span>(</span><span>keys</span><span>));</span>
</pre></div>


<p>Ensuite dans les resolvers, au lieu de récupérer les utilisateurs directement à partir du service, on utilise le data loader pour récupérer la valeur :</p>
<div><pre><span></span><span>const</span> <span>resolvers</span> <span>=</span> <span>{</span>
  <span>async</span> <span>backups</span><span>()</span> <span>{</span>
    <span>return</span> <span>service</span><span>.</span><span>find</span><span>();</span>
  <span>},</span>
  <span>Backup</span><span>:</span> <span>{</span>
    <span>async</span> <span>user</span><span>(</span><span>ctx</span><span>,</span> <span>{</span> <span>id</span> <span>})</span> <span>{</span>
      <span>return</span> <span>await</span> <span>userLoader</span><span>.</span><span>load</span><span>(</span><span>id</span><span>);</span>
    <span>},</span>
  <span>},</span>
<span>};</span>
</pre></div>


<p><code>Dataloader</code> n'est par contre pas fait pour être utilisé en tant que cache applicatif et ne remplace donc pas un memcached ou un redis.</p>
<h3>Query - Batch</h3>
<p><code>Apollo</code> côté client propose de pouvoir faire du batching de requêtes. Cela consiste à attendre un léger laps de temps pour regrouper en une seule requête plusieurs requêtes.</p>
<p>Attention néanmoins, mettre en place le batching de requêtes implique:</p>
<ul><li>qu'on attend (pas très longtemps) pour envoyer les requêtes</li>
<li>qu'on attend l'aggrégat des réponses avant de les recevoir</li>
<li>qu'on ne bénéficie pas du multiplexing des requêtes de HTTP/2.</li>
</ul><p>Il est alors conseillé d'abord de faire d'autres types d'optimisations (comme utiliser les requêtes persistentes, un cache dans un CDN des réponses, utiliser HTTP/2 jusqu'au NodeJS)
avant de mettre en place le système de batch.</p>
<p>Si vous voulez le mettre tout de même en place, vous pouvez regarder la <a href="https://www.apollographql.com/docs/link/links/batch-http/">documentation d'Apollo sur ce sujet</a>.</p>
<h3>Query - Transfert réseau</h3>
<p>Pour une API Web, les requêtes et les réponses sont transférées en utilisant le protocole HTTP. Pour améliorer les performances il est
possible d'utiliser plusieurs méthodes:</p>
<ul><li>Comme en REST, activer la compression GZIP coté serveur, permet de réduire les flux réseaux</li>
<li>Utiliser les requêtes persistentes (stocké coté serveur) : <a href="https://www.apollographql.com/docs/apollo-server/performance/apq/">https://www.apollographql.com/docs/apollo-server/performance/apq/</a></li>
<li>Utiliser les fragments pour réutiliser certaines parties des requêtes qui peuvent se répéter.</li>
<li>Utiliser HTTP/2 et le multiplexing des requêtes. Faire une seule grosse requête peut être contre-productif avec HTTP/2. En effet il faut attendre la fin de la résolution de l'ensemble des resolvers
  côté serveur avant d'avoir la réponse. Faire plusieurs requêtes peut permettre d'avoir certaines parties de la requête plus vite. De plus HTTP/2 permet de mieux paralléliser les requêtes. Il faut donc
  trouver le bon nombre de requêtes à executer pour avoir les meilleurs performances.</li>
</ul><h3>Mutation</h3>
<p>Nous avons énormément parlé de toute la partie requête de GraphQL. GraphQL permet également de faire des modifications via des <code>mutations</code>.</p>
<p>Une mutation est similaire à une requête :</p>
<div><pre><span></span>mutation CreateBackup($backup: CreateBackupInput!) {
  createBackup(backup: $backup) {
    statusCode
    message
    error
    errorCode
    backup {
      id
      state
      user {
        id
      }
    }
  }
</pre></div>


<p>Nous retrouvons la partie input, et la partie query (sur la réponse). Alors que généralement sur query on va retrouver des types primitifs en paramètres, on va plutôt retrouver
en paramètre d'une mutation un objet de type Input. Sur le résultat le fonctionnement est lui le même que sur une Query.</p>
<p>Nous pouvons d'ailleurs utiliser les mêmes resolvers sur les réponses que dans les queries (et ainsi récupérer l'utilisateur de la backup de la même manière).</p>
<p>En bonne pratique, ce que nous pouvons retrouver sur les mutations sont:</p>
<ul><li>Ne pas renvoyer l'objet créé/modifié directement. Renvoyer un objet permettant à l'utilisateur de récupérer l'erreur fonctionnelle ou l'objet selon le cas. Cela permettra de faire
  évoluer plus facilement le résultat si nécessaire.</li>
<li>De la même manière, <strong>même</strong> si la mutation a besoin de très peu de paramètres en entrée, il vaut mieux créer un objet de type <code>input</code> afin de passer les paramètres. Ceci également
  afin de pouvoir évoluer facilement avec l'API au fur et à mesure des évolutions.</li>
<li>Eviter pour le paramètre principal ou la sortie principale de réutiliser un objet. Il vaut mieux en créer un propre à la <code>mutation</code>.</li>
<li>Contrairement à REST, les <code>mutations</code> GraphQL ressemblent plus à du RPC. Il vaut mieux alors éviter de penser ressources mais plutôt actions. Quels sont les actions que l'on souhaite
  pouvoir faire depuis l'IHM.</li>
</ul><p>Il ne faut pas hésiter à découper ces actions en petites actions que l'utilisateur peut choisir d'appeler ou non (il est possible d'appeler plusieurs <code>mutations</code> en un seul appel).</p>
<ul><li>Penser les <code>mutations</code> en fonction des appels de vos clients.</li>
</ul><p>Si on reprend le schéma suivant:</p>
<div><pre><span></span>input InputUser {
  name: String!
}

input CreateBackupInput {
  host: String!
  user: InputUser!
}

type Backup {
  host: String!
  id: Int!
  startDate: Date
  endDate: Date
  user: User
}

type User {
  name: String
  backups: [Backup!]
}

type CreateBackupResponse {
  statusCode: Int!
  message: String
  error: String
  errorCode: String
  backup: Backup
}
</pre></div>


<p>Contrairement aux paramètres de sortie, il n'est pas possible sur les <code>input</code> de faire des dépendances circulaires. Un input doit donc être lié à l'action faite
par la mutation.
Cela veux dire aussi qu'il n'est pas possible de réutiliser un type de sortie en input pour l'entrée. Le point d'exclamation n'est plus un indicateur de non nullité
mais un indicateur de paramètre obligatoire.</p>
<p>Lors de la conception des ces inputs il faut d'ailleurs penser à plusieurs choses:</p>
<ul><li>Certain champs en sortie dans un type sont là pour representer un calcul ou un état qui fait sens mais que l'utilisateur ne peut pas modifier. Il ne faut donc pas
  le mettre en entrée.</li>
<li>Un paramètre qui peut être non nul en sortie n'est pas forcément obligatoire en entrée (et inversement).</li>
</ul><p>Pour une application possédant beaucoup de formulaires et d'écrans de modifications ou d'actions, il peut être donc compliqué d'écrire les requêtes et les mutations associées.</p>
<p>Il peut peut-être être intéressant d'utiliser un transpiler comme <a href="https://www.npmjs.com/package/graphql-s2s">graphql-s2s</a> qui permet de simplifier certaines choses
dans l'écriture du schéma.
Lors de son utilisation sur un projet possédant un gros schéma, il a permis la reprise d'une API Rest existante plus facilement.</p>
<p>Il permet entre autres:</p>
<ul><li>de ne pas répéter les champs de l'interface lors de l'héritage d'un type.</li>
<li>de définir des types génériques (qui à la compilation créeront des vrais types).</li>
</ul><h3>Subscription</h3>
<p>Un des points que j'adore avec GraphQL c'est la facilité d'implémentation qu'apporte Apollo avec les <code>Subscritpions</code>. Quand on souhaite remonter des informations
du serveur au client, on peut mettre en place des WebSockets ou des Server-Side-Events. Il faut alors définir un potocole entre le client et le serveur.</p>
<p>GraphQL utilise de façon transparente une WebSocket dans le cadre des souscriptions. L'avantage c'est que le protocole est le même que pour les query. On effectue une
demande et au lieu d'avoir une réponse, une fois, on reçois les mise à jours sur la souscription.</p>
<p>Cela permet de mettre en place facilement des pages dynamiques qui évoluent sans actions utilisateurs (progression, chat, ...) sans se casser la tête.</p>
<p>Pour définir une souscription on peut utiliser une requête comme celle-ci:</p>
<div><pre><span></span><span>#import "./FragmentJob.graphql"</span>

<span>subscription</span> <span>QueueTasksJobUpdated</span> <span>{</span>
  <span>jobUpdated</span> <span>{</span>
    <span>...</span><span>FragmentJob</span>
  <span>}</span>
<span>}</span>
</pre></div>


<p>Dans l'exemple ci-dessous je réutilise le fragment d'un job défini dans une query. La souscription dans apollo va automatiquement mettre à jour le résultat et
rafraichir l'IHM.</p>
<p>Par exemple avec vue cela donne (cf la doc de <a href="https://apollo.vuejs.org/guide/apollo/subscriptions.html#subscribe-to-more">vue-apollo</a>):</p>
<div><pre><span></span><span>apollo</span><span>:</span> <span>{</span>
  <span>tags</span><span>:</span> <span>{</span>
    <span>query</span><span>:</span> <span>TAGS_QUERY</span><span>,</span>
    <span>subscribeToMore</span><span>:</span> <span>{</span>
      <span>document</span><span>:</span> <span>gql</span><span>`subscription name($param: String!) {</span>
<span>        itemAdded(param: $param) {</span>
<span>          id</span>
<span>          label</span>
<span>        }</span>
<span>      }`</span><span>,</span>
      <span>// Variables passed to the subscription. Since we're using a function,</span>
      <span>// they are reactive</span>
      <span>variables</span> <span>()</span> <span>{</span>
        <span>return</span> <span>{</span>
          <span>param</span><span>:</span> <span>this</span><span>.</span><span>param</span><span>,</span>
        <span>}</span>
      <span>},</span>
      <span>// Mutate the previous result</span>
      <span>updateQuery</span><span>:</span> <span>(</span><span>previousResult</span><span>,</span> <span>{</span> <span>subscriptionData</span> <span>})</span> <span>=></span> <span>{</span>
        <span>// Here, return the new result from the previous with the new data</span>
      <span>},</span>
    <span>}</span>
  <span>}</span>
<span>}</span>
</pre></div>


<p>La requête initiale est faite grâce à <code>TAG_QUERY</code>, puis toutes les mises à jours se font via la souscription. L'IHM est alors automatiquement mise à jour.</p>
<h3>Conclusion</h3>
<p>GraphQL est super puissant et facilite l'écriture d'API et son utilisation par des clients. Par contre la montée en compétence pour faire du GraphQL est un
peu plus élevée que pour faire du REST (Bien qu'il n'est pas facile de faire du bon REST).</p>
<p>Il peut toujours être utile de proposer des API Rest en plus des API GraphQL. Pour par exemple permettre au client de choisir ce qu'il souhaite utiliser ou
même par exemple pour des cas d'usage particuliers. (Par exemple le téléchargement/l'upload d'un document binaire est plus facile en REST que en GraphQL).</p>
<h3>Références</h3>
<ul><li><a href="https://graphql.org/learn/queries/">GraphQL</a></li>
<li><a href="https://www.apollographql.com/docs/apollo-server/data/resolvers/">Apollo</a>.</li>
<li><a href="https://www.moesif.com/blog/technical/api-design/Best-Practices-for-Versioning-REST-and-GraphQL-APIs/">Best Practices for Versioning REST and GraphQL APIs</a></li>
<li><a href="https://graphql.org/learn/best-practices/#versioning">GraphQL Versioning</a></li>
<li><a href="https://towardsdatascience.com/graphql-best-practices-3fda586538c4">GraphQL Best Practices</a></li>
<li>https://www.moesif.com/blog/technical/api-design/Best-Practices-for-Versioning-REST-and-GraphQL-APIs/</li>
<li>https://graphql.org/learn/best-practices/#versioning</li>
</ul>
<p><img src="media/6b1ba161.4f904d3f901ea9e5debb071ada9ea38b" data-original-source="http://cdn.libravatar.org/avatar/4f904d3f901ea9e5debb071ada9ea38b" alt="Gravatar de Ulrich Van Den Hekke" class="gravatar" /><br/><i>Original post of <a href="https://shadoware.org/post/creation-api-3" title="Visit the source">Ulrich Van Den Hekke</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Ulrich Van Den Hekke : <a href="">Comment cr&eacute;er une bonne API Web - Partie 1</a> (11/10/2020)</li><li>Ulrich Van Den Hekke : <a href="">Comment cr&eacute;er une bonne API Web - Partie 2</a> (02/11/2020)</li><li>theClimber : <a href="">R&eacute;cup&eacute;rer les tweets d&#039;une instance statusnet en live avec javascript</a> (02/02/2011)</li><li>Damien Pobel : <a href="">Veille de la semaine #19 de 2018</a> (10/05/2018)</li><li>Littlewing : <a href="">Tracer (facilement) les entr&eacute;es sorties d&rsquo;une API REST</a> (01/12/2018)</li></ul></div></p>


feed_id: https://blog.remirepo.net/post/2020/11/30/Installer-PHP-8.0-sur-CentOS-RHEL-ou-Fedora
title: Remi Collet : Installer PHP 8.0 sur CentOS, RHEL ou Fedora
uri: Remi-Collet-Installer-PHP-8-0-sur-CentOS-RHEL-ou-Fedora
url: https://blog.remirepo.net/post/2020/11/30/Installer-PHP-8.0-sur-CentOS-RHEL-ou-Fedora
content:
<p>Voici un guide rapide pour mettre à jour le <a href="http://php.net/">PHP</a> fournit par <a href="http://fedoraproject.org/">Fedora</a>, <a href="https://www.redhat.com/fr/technologies/linux-platforms/enterprise-linux">RHEL</a> ou <a href="https://www.centos.org/">CentOS</a> par la dernière version <strong>8.0</strong>.</p>

<p>Vous pouvez aussi suivre les instructions de l'<a href="https://rpms.remirepo.net/wizard/">assistant de configuration</a>.</p>    <p> </p>

<h1>Configuration des dépôts:</h1>

<p>Sur <strong>Fedora</strong>, les dépôts standards sont suffisant, sur <strong>Enterprise Linux</strong> (RHEL, CentOS) il est aussi nécessaire de configurer le dépôt <strong>Extra Packages for Enterprise Linux</strong> (<a href="https://fedoraproject.org/wiki/EPEL">EPEL</a>), et sur RHEL 7 d'activer le canal <strong>optional</strong>.</p>

<h2>Fedora 33</h2>

<pre>
dnf install https://rpms.remirepo.net/fedora/remi-release-33.rpm</pre>

<h2>Fedora 32</h2>

<pre>
dnf install https://rpms.remirepo.net/fedora/remi-release-32.rpm</pre>

<h2>RHEL version 8.3</h2>

<pre>
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
</pre>

<h2>RHEL version 7.9</h2>

<pre>
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
wget https://rpms.remirepo.net/enterprise/remi-release-7.rpm
rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm
subscription-manager repos --enable=rhel-7-server-optional-rpms</pre>

<h2>CentOS version 8</h2>

<pre>
dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
dnf install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
</pre>

<h2>CentOS version 7</h2>

<pre>
wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
wget https://rpms.remirepo.net/enterprise/remi-release-7.rpm
rpm -Uvh remi-release-7.rpm epel-release-latest-7.noarch.rpm
</pre>

<p> </p>

<h1>Utilisation du module php</h1>

<p>Pour <strong>Fedora modular</strong> et <strong>RHEL / CentOS 8,</strong> il suffit d'utiliser le flux <strong>remi-8.0</strong> du module <strong>php</strong></p>

<pre>
dnf module reset php
dnf module install php:remi-8.0</pre>

<p> </p>

<h1>Activation du dépôt remi-php80</h1>

<p>Les paquets sont dans les dépôts <strong>remi-safe</strong> (activé par défaut) et <strong>remi-php80 </strong>qui n'est pas activé par défaut (choix de l'administrateur en fonction de la version de PHP souhaitée).</p>

<h2>RHEL et CentOS 7</h2>

<pre>
yum install yum-utils
yum-config-manager --enable remi-php74</pre>

<h2>Fedora</h2>

<pre>
dnf config-manager --set-enabled remi-php80</pre>

<p> </p>

<h1>Mise à jour de PHP</h1>

<p>Par choix, les paquets ont le même nom que les paquets fournit par défaut avec le système, une simple mise à jour est donc suffisante :</p>

<pre>
yum update</pre>

<p>Et c'est tout :)</p>

<pre>
$ php -v
PHP 8.0.0 (cli) (built: Nov 24 2020 17:04:03) ( NTS gcc x86_64 )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.0, Copyright (c), by Zend Technologies
</pre>

<p> </p>

<h1>Problèmes connus</h1>

<p>La mise à jour peut échouer (c'est voulu) lorsque certaines extensions présentes ne sont pas encore compatibles avec PHP 8.0.</p>

<p>Voir la liste des compatibilités : <a href="https://blog.remirepo.net/pages/PECL-extensions-RPM-status">PECL extensions RPM status</a></p>

<p>Si elles ne sont pas indispensables, vous pouvez les désinstaller avant la mise à  jour, sinon, il faudra patienter.</p>

<p>Attention : quelques extensions sont encore en phase de développement, mais il m'a semblé utile de les fournir afin de permettre la mise à jour au plus grand nombre, et aussi permettre leur test et des retours vers les auteurs.</p>

<p> </p>

<h1>Plus d'informations</h1>

<p>Si vous souhaitez une <strong>installation en parallèle</strong> de la version par défaut de <strong>PHP</strong>, cela est possible en utilisant les paquets préfixés <strong>php80</strong> Voir le billet <a href="https://blog.remirepo.net/post/2020/04/10/PHP-8.0-en-Software-Collection">PHP 8.0 en Software Collection</a>.</p>

<p>Vous pouvez aussi utiliser <a href="https://rpms.remirepo.net/wizard/">l'assistant de configuration</a>.</p>

<p>Les paquets présents dans le dépôt seront utilisés comme sources pour <strong>Fedora 35</strong> (si la demande de changement est acceptée).</p>

<p>En fournissant une pile complète, environ <strong>130</strong> extensions disponibles, 7 versions de PHP, paquets de base et SCL, pour Fedora et Enterprise Linux, et avec <strong>300 000</strong> téléchargements par jour, le dépôt <strong>remi</strong> est devenu en <a href="https://blog.remirepo.net/post/2015/04/27/10-ans">15 ans</a> une référence pour les utilisateurs de PHP sur les distributions RPM, maintenu par un contributeur actif aux différents projets (<a href="https://admin.fedoraproject.org/pkgdb/packager/remi/">Fedora</a>, <a href="https://github.com/php/php-src/graphs/contributors">PHP</a>, <a href="https://pecl.php.net/user/remi">PECL</a>...).</p>

<p>Et aussi :</p>

<ul><li><a href="https://blog.remirepo.net/feed/fr/rss2">Flux RSS des billets</a> (annonces des versions)</li>
	<li><a href="https://blog.remirepo.net/feed/fr/rss2/comments">Flux RSS des commentaires</a></li>
	<li><a href="http://rpms.remirepo.net/enterprise/8/php80/x86_64/repoview/latest-feed.xml">Flux RSS du dépôt</a> (ex EL-8, php 8.0)</li>
	<li><a href="https://blog.remirepo.net/post/2019/12/03/Installer-PHP-7.4-sur-CentOS-RHEL-ou-Fedora">Installer PHP 7.4 sur CentOS, RHEL ou Fedora</a></li>
	<li><a href="https://blog.remirepo.net/post/2018/12/10/Installer-PHP-7.3-sur-CentOS-RHEL-ou-Fedora">Installer PHP 7.3 sur CentOS, RHEL ou Fedora</a></li>
	<li><a href="https://blog.remirepo.net/post/2017/12/04/Installer-PHP-7.2-sur-CentOS-RHEL-ou-Fedora">Installer PHP 7.2 sur CentOS, RHEL ou Fedora</a></li>
</ul>
<p><img src="media/3d2d1a35.2665280f5ed66efe5e772da3f0403a2c" data-original-source="http://cdn.libravatar.org/avatar/2665280f5ed66efe5e772da3f0403a2c" alt="Gravatar de Remi Collet" class="gravatar" /><br/><i>Original post of <a href="https://blog.remirepo.net/post/2020/11/30/Installer-PHP-8.0-sur-CentOS-RHEL-ou-Fedora" title="Visit the source">Remi Collet</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Remi Collet : <a href="">Installer PHP 7.3 sur CentOS, RHEL ou Fedora</a> (10/12/2018)</li><li>Remi Collet : <a href="">Installer PHP 7.4 sur CentOS, RHEL ou Fedora</a> (03/12/2019)</li><li>Remi Collet : <a href="">Red Hat va fournir PHP 7.0 pour RHEL</a> (07/11/2016)</li><li>Remi Collet : <a href="">Red Hat va fournir PHP 7.1 pour RHEL (et CentOS)</a> (05/10/2017)</li><li>Remi Collet : <a href="">Astuces de configuration de PHP</a> (28/10/2017)</li></ul></div></p>


feed_id: https://www.elementaryos-fr.org/les-nouvelles-de-novembre2020/
title: elementary OS : Les nouvelles de #Novembre2020
uri: elementary-OS-Les-nouvelles-de-Novembre2020
url: https://www.elementaryos-fr.org/les-nouvelles-de-novembre2020/
content:
<p>Après un petit moment d’absence, on fait le tour des nouvelles de elementary OS.</p>
<h2>Les actualités depuis Juillet,</h2>
<p>L’équipe elementary n’a pas sorti d’Update depuis juillet mais plusieurs articles de blog. L’équipe est très occupé sur le développement de la prochaine itération, de ce fait nous ne recevons que des mises à jour de maintenance.</p>
<p>Voici une petite liste des articles paru sur le blog de elementray :</p>
<p><a href="https://blog.elementary.io/leaving-google-analytics-is-finally-plausible/">Leaving Google Analytics is Finally Plausible</a> – L’équipe elementary a fait le choix de migrer les statistiques du site de Google Analytics vers l’outil open-source <a href="https://plausible.io/">Plausible</a>, le service peut-être auto-héberger via docker.</p>
<p><a href="https://blog.elementary.io/elementary-os-on-pinebook-pro/">elementary OS on Pinebook Pro</a> – PINE64 a permis à l’équipe elementary de profiter de plusieurs Pinebook Pro pour entamer le développement de elementary OS sur des machine à base ARM.</p>
<p><a href="https://blog.elementary.io/devices-slimbook/">Slimbook Joins the elementary OS Retailer Program</a> – Pour annoncer que l’entreprise Slimbook rejoins les 2 autres entreprises (Laptop with Linux &amp; Star Labs), pour proposer eOS directement installé à l’achat du PC.</p>
<p><a href="https://blog.elementary.io/revitalize-mac-windows-computer/">How to Revitalize Your Mac or Windows PC</a> – Qui explique pourquoi choisir elementary OS sur votre Mac ou PC.</p>
<p><a href="https://blog.elementary.io/platform-changes-in-elementary-os-6/">Platform Changes in elementary OS 6</a> – Détaille les nombreux changements que elementary OS 6 va bénéficié.</p>
<p><a href="https://blog.elementary.io/privacy-and-elementary-os/">Privacy and elementary OS</a> – Ils parlent de la vie privée et de l’importance que cela a dans le distribution.</p>
<p><a href="https://blog.elementary.io/dark-style-progress/">Dark Style Progress for elementary OS 6</a> – Explique fonctionnement et l’intégration du thème sombre et des accentuations, c’est la plus grosse fonctionnalité de cette futur itération, et l’une des mieux intégré à un bureau linux.</p>
<div><iframe title="elementary OS Dark Style Preview (Live and Unedited!)" width="1140" height="641" src="https://www.youtube.com/embed/yU72B-AQqjQ?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>
<p><em>Une vidéo YouTube par Cassidy James sur le thème sombre.</em></p>
<p><img loading="lazy" src="media/e210ba4a.card.png" data-original-source="https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card.png" alt="" width="2560" height="1440" srcset="https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card.png 2560w, https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card-300x169.png 300w, https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card-1024x576.png 1024w, https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card-768x432.png 768w, https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card-1536x864.png 1536w, https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card-2048x1152.png 2048w, https://www.elementaryos-fr.org/wp-content/uploads/2020/11/card-600x338.png 600w" sizes="(max-width: 2560px) 100vw, 2560px"></p>
<h2>On en parle sur les réseaux sociaux</h2>
<p>Vous trouverez quelques liens des différents réseaux sociaux qui parle de elementary OS :<br><em>(Cela va surtout être centré sur ce que l’on va avoir dans la prochaine itération de elementary OS.)</em></p>
<ul><li>Daniel Foré travaille actuellement sur l’<a href="https://twitter.com/DanielFore/status/1331400109238624256">intégration des gestes du pavé tactile</a> sur pour elementary OS 6 Odin avec <strong><span>Touchégg</span></strong> et cela avance bien. (<a href="https://twitter.com/Jose__Exposito/status/1330508290850230278">tweet1</a> &amp; <a href="https://twitter.com/DanielFore/status/1328761801450741760">tweet2</a>)</li>
<li>La société TUXEDO qui <a href="https://twitter.com/TUXEDOComputers/status/1331224199080407040">veut faire des PC portable elementary OS</a> avec un peu plus de personnalisation visuel.</li>
</ul><h2>Quelques applications elementary OS…</h2>
<p><span data-controller="core.front.core.moderation"><span title="(Cliquer et maintenir pour modifier le titre)" data-role="editableTitle">Voici également un tutoriel pour les </span></span><a href="https://forum.elementaryos-fr.org/topic/2998-gestes-multitouche-pav%C3%A9-tactile/"><span data-controller="core.front.core.moderation"><span title="(Cliquer et maintenir pour modifier le titre)" data-role="editableTitle">gestes multitouche sur le pavé tactile</span></span></a> avec eOS 5.1 Hera en attendant Odin et l’intégration de Touchégg.</p>
<p>C’est tout pour le moment, pas de rendez-vous au mois prochain en attendant un peu plus d’informations sur Odin et avec un peu d’espoir la sortie le mois prochain ou début 2021.</p>
<p>N’hésitez pas à faire un tour sur le forum et également sur notre serveur matrix : #elementaryOS_fr:matrix.org</p>
<p>Si vous souhaitez aider elementary OS, vous pouvez financer le projet le sponsor de Github à <a href="https://github.com/sponsors/elementary">cette page</a> et qui vous permettra à partir de 10$/mois de pouvoir tester la version Odin.</p>
<p>Vous pouvez en discuter sur le forum en suivant ce lien.</p>
<p>Le billet <a rel="nofollow" href="https://www.elementaryos-fr.org/les-nouvelles-de-novembre2020/">Les nouvelles de #Novembre2020</a> a été publié sur le site de la <a rel="nofollow" href="https://www.elementaryos-fr.org/">elementary OS - </a></p>
<p><img src="media/7e20f332.e363a9ed45733fa3aec7c3a0361380c6" data-original-source="http://cdn.libravatar.org/avatar/e363a9ed45733fa3aec7c3a0361380c6" alt="Gravatar de elementary OS" class="gravatar" /><br/><i>Original post of <a href="https://www.elementaryos-fr.org/les-nouvelles-de-novembre2020/" title="Visit the source">elementary OS</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>elementary OS : <a href="">Les nouvelles de #Juin2020</a> (30/06/2020)</li><li>elementary OS : <a href="">Les nouvelles de #Avril2020</a> (30/04/2020)</li><li>elementary OS : <a href="">Isis, c&#039;est aussi... Ubuntu !</a> (01/05/2014)</li><li>elementary OS : <a href="">Le futur Installer d&rsquo;elementary OS re&ccedil;oit de nouvelles mises &agrave; jour.</a> (01/05/2018)</li><li>elementary OS : <a href="">Mise &agrave; jour de Aout</a> (25/09/2019)</li></ul></div></p>


feed_id: https://blog.genma.fr/?Pourquoi-utiliser-Firefox-par-Timothee-Jourde
title: genma : Pourquoi utiliser Firefox par Timothée Jourde
uri: genma-Pourquoi-utiliser-Firefox-par-Timothée-Jourde
url: https://blog.genma.fr/?Pourquoi-utiliser-Firefox-par-Timothee-Jourde
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2928.jpg?1606746583" width="150" height="79"><div><p>Sur Twitter, en août 2020, Timothée Jourde @timjrd publiait un ensemble de twitts enchainés, <i>un thread</i> très intéressant. Twitter étant un réseau social de l'instantané, de l'éphémère, avec son accord, je souhaite republier ici l'entierté de son propos, car il me semble pertinent et très intéressant (et je suis d'accord avec lui).</p>
<p><strong>DEBUT DE CITATION</strong></p>
<p><i>Lorsque vous naviguez sur le Web, au quotidien, vous dépendez d'un navigateur. Le choix de ce logiciel peux paraître anodin mais il donne en réalité beaucoup de poids à l'organisation qui le contrôle.</i></p>
<p><i>Le Web gagne en potentiel chaque jour : une part croissante d'applications mobiles (comme pour ordinateur de bureau) sont en réalité des applications Web cachés. Le Web est une plateforme unique et porteuse d'espoir concernant de nombreux enjeux du numérique grand publique comme la protection de la vie privée ou la libre concurrence. Le Web offre en effet à l'utilisateur un haut degré de contrôle grâce à un environnent d'exécution isolé et sécurisé, tout en reposant sur des standards ouverts.</i></p>
<p><i>La pérennité du Web dépend de ces standards et de l'adhésion de l'industrie à ceux-ci. En 2020 la grande majorité des internautes utilisent Google Chrome ou Safari (Apple), sur mobile comme sur ordinateur de bureau. Chaque part de marché conquise par une entreprise dans ce secteur se traduit par un gain d'influence de celle-ci au seins du W3C (World Wide Web Consortium) : l'organisation chargée de mettre d'accord les grands acteurs du numérique sur les standards du Web.</i></p>
<p><i>Il existe un acteur de poids dans cette industrie dont le rôle est de défendre vos intérêts. La fondation Mozilla ne se limite pas au militantisme : elle se veux un acteur à part entière de l'industrie du Web en proposant des produits logiciels innovants au service des utilisateurs. Vous connaissez sans-doutes le logiciel phare de la fondation : Firefox est le seul navigateur Web compétitif dont le développement est intégralement contrôlé par une organisation à but non lucratif.<br></i></p>
<p><i>À chaque connexion, les sites web identifient votre navigateur. En utilisant Firefox au quotidien, sur votre ordinateur de bureau ou votre mobile Android, vous envoyez un signal à l'industrie. À chaque utilisation de Firefox, vous donnez un peu plus de poids à Mozilla et vous obligez les grands acteurs du numérique comme Google ou Apple à négocier avec la fondation lors de l'élaboration des standards du Web.</i></p>
<p><i>En 2010, alors que le Web sur mobile était encore anecdotique, Firefox disposait d'environ 30% de part de marché : il était alors difficile d'ignorer les propositions de Mozilla au risque de se priver d'une large part des internautes.</i></p>
<p><i>En 2010, alors que le Web sur mobile était encore anecdotique, Firefox disposait d'environ 30% de part de marché : il était alors difficile d'ignorer les propositions de Mozilla au risque de se priver d'une large part des internautes. Aujourd'hui la fondation perd de l'influence et a récemment licencié le quart de ses effectifs. Vous pouvez aider Mozilla à défendre vos intérêts et à regagner la part d'influence qu'elle a perdue en utilisant Firefox : un navigateur Web innovant, performant, et respectueux de votre vie privée.</i></p>
<p>Firefox pour Android : <a href="https://play.google.com/store/apps/details?id=org.mozilla.firefox" title="Firefox pour Android">https://play.google.com/store/apps/details?id=org.mozilla.firefox</a></p>
<p>Firefox pour Windows, macOS et Linux : <a href="https://www.mozilla.org/fr/firefox/new" title="Firefox pour Windows, macOS et Linux">https://www.mozilla.org/fr/firefox/new</a></p>
<p><strong>FIN DE CITATION</strong></p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Pourquoi-utiliser-Firefox-par-Timothee-Jourde" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://www.citizenz.info/articles/lier-deux-select-avec-jquery-chained
title: citizenz7 : Lier deux select avec Jquery chained
uri: citizenz7-Lier-deux-select-avec-Jquery-chained
url: https://www.citizenz.info/articles/lier-deux-select-avec-jquery-chained
content:
lier-deux-select-avec-jquery-chained
<p><img src="media/81133586.d3d22ade032c891f4b97588788975fc6" data-original-source="http://cdn.libravatar.org/avatar/d3d22ade032c891f4b97588788975fc6" alt="Gravatar de citizenz7" class="gravatar" /><br/><i>Original post of <a href="https://www.citizenz.info/articles/lier-deux-select-avec-jquery-chained" title="Visit the source">citizenz7</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: http://blog.chimrod.com/2020/12/encore-des-cvs-en-rst/
title: Chimrod : Encore des cvs en rst
uri: Chimrod-Encore-des-cvs-en-rst
url: http://blog.chimrod.com/2020/12/encore-des-cvs-en-rst/
content:
<p>J’avais déjà présenté comment <a href="http://blog.chimrod.com/2015/10/se-faire-un-cv-en-rst/">modifier</a> le format rst pour produire un cv avec
la classe moderncv de latex. Cette fois je propose de se créer soi-même son
modèle tout en gardant le format <span>RST</span>.</p>
<p>L’idée est de conserver le standard du format rst et de modifier les fichiers
latex pour les adapter en fonction du besoin. Cela signifie que le même fichier
source peut être utilisé avec les différents exemples sans changements (ou presque).</p>
<div>
<h2>Le résultat</h2>
<p>Commençons directement par le final, voilà le résultat<span> </span>:</p>
<img alt="" src="media/317d067f.model5.png" data-original-source="http://blog.chimrod.com/images/cv/model5.png"><p>le code est disponible sur mon <a href="http://git.chimrod.com/latex_template.git/">dépôt git</a> si vous souhaitez le cloner et
récupérer les sources.</p>
</div>
<div>
<h2>Les directives <span>RST</span></h2>
<div>
<h3>La sidebar</h3>
<div><pre><span></span><span>..</span> <span>sidebar</span><span>::</span> Titre

 Texte à renseigner dans le bandeau
</pre></div>
<p>Permet de créer du texte dans la barre latérale. Le texte peut être une liste,
une image ou tout autre élément standard. Il faut juste faire attention à la
largeur qui oblige à rester concis…</p>
<div>
<p>Sans titre<span> </span>?</p>
<p>rst oblige à déclarer un titre dans la directive, ce qui n’est pas forcément
ce que l’on souhaite. Par contre le titre peut être vide<span> </span>! Il suffit
d’échapper une espace<span> </span>:</p>
<div><div><pre><span></span><span>..</span> <span>sidebar</span><span>::</span> \\

<span>  ..</span> <span>image</span><span>::</span> mon profil.jpg
    <span>:width:</span> 100%
</pre></div>
</div></div>
</div>
<div>
<h3>Les listes</h3>
<p>Avec la directive <tt>class</tt>, il est possible d’appliquer un style qui sera
présent jusqu’à la fin du paragraphe. Ce style est associé à une commande Latex
qui permet l’appliquer le style en question. Ainsi, avec la classe <tt>checklist</tt>,
toutes les puces des listes sont remplacées par une coche<span> </span>:</p>
<div><pre><span></span><span>..</span> <span>class</span><span>::</span> checklist

<span>*</span> 1er élément
<span>*</span> Second élément
</pre></div>
<p>La commande latex suivante est utilisée<span> </span>:</p>
<div><pre><span></span><span>\\newenvironment</span><span>{</span>DUCLASSchecklist<span>}{</span><span>\\renewcommand</span><span>{</span><span>\\labelitemi</span><span>}{</span><span>\\faCheck</span><span>}}{}</span>
</pre></div>
<p>Il est facile de modifier la commande pour charger d’autres types de marques,
voir le fichier <a href="http://git.chimrod.com/latex_template.git/tree/common/10_lists.tex">10_lists.tex</a> pour la liste complète.</p>
<p>Il est possible de modifier le style de liste en cours de route, mais il faut
faire attention à appeler la commande <strong>avant</strong> la ligne que l’on souhaite
modifier. C’est pourquoi l’on retrouve l’exemple suivant dans lequel on annonce
les icônes avant la ligne suivante<span> </span>:</p>
<div><pre><span></span><span>..</span> <span>sidebar</span><span>::</span> Informations

  <span>*</span> 75001 Paris |phoneicon|
  <span>*</span> 01 23 45 67 89 |mailicon|
  <span>*</span> email@example |noicon|
</pre></div>
<p><tt>|phoneicon|</tt> est en fait une substitution de texte qui insère une commande
latex à la place (et donc ne substitue rien du tout<span> </span>:))</p>
</div>
</div>
<div>
<h2>Les barres de niveau</h2>
<p>Autre point assez amusant, il est possible de faire des graphiques à partir de
données dans le fichier. Les niveaux représentés sous forme d’étoiles ou de
barres sont construits dans latex à partir des lignes suivantes<span> </span>:</p>
<div><pre><span></span><span>..</span> <span>role</span><span>::</span> level
<span>..</span> <span>role</span><span>::</span> levelbox
<span>..</span> <span>role</span><span>::</span> star

<span>:star:</span><span>`4.5`</span>
<span>:levelbox:</span><span>`5`</span>
<span>:level:</span><span>`3`</span>
</pre></div>
<p>Il s’agit de rôles personnalisés, qui sont interprétés comme des commandes
latex prenant un paramètre<span> </span>: la valeur du niveau. Celui-ci est ensuite
représenté sous forme d’étoile colorées, ou barre de niveau. On peut imaginer
toutes les fantaisies possibles…</p>
</div>
<div>
<h2>Autres éléments</h2>
<p>Il n’y en a pas d’autres. Tout le reste est ensuite standard et suit les
directives rst. (La directive <a href="https://docutils.sourceforge.io/docs/ref/rst/directives.html#admonitions">admonition</a> permet également des
personnalisations assez avancées, mais je ne l’ai pas appliqué ici).</p>
</div>
<div>
<h2>L’organisation</h2>
<p>Chaque répertoire contient un modèle différent, et tous les modèles suivent le
même schéma<span> </span>:</p>
<pre>
|
|\\ Makefile
|\\ fichier.rst (le fichier source à traiter)
\\ resources (le répertoire contenant les modèles latex)
  |
  |\\ 00_colors.tex (la définition des couleurs)
  |\\ 00_length.tex (les longueurs pour les marges ou autres paramètres)
  |\\ 00_preamble.tex (le fichier contenant les paramètres principaux)
  |\\ 10_fonts.tex (les polices utilisées dans le document)
  |\\ 10_title_style.tex (la personnalisation des titres)
   \\ autres directives latex
</pre>
<p>Tous les fichiers qui sont présents dans le répertoire <tt>resources</tt> sont
automatiquement chargés, et les modules présents dans le fichier <tt>modules</tt> sont
également chargés.</p>
<p>Pour la simplification du dépôt, des fichiers communs à tous mes styles sont
présents dans le répertoire <tt>common</tt></p>
</div>
<div>
<h2>Et voilà</h2>
<p>J’espère que ces petits exemples vous donneront des idées, et qu’ils vous
permettront de construire vos propres modèles. L’idée est vraiment de laisser
toute la mécanique latex en arrière-plan, et se simplifier au maximum
l’écriture<span> </span>!</p>
</div>
<p><img src="media/51a0b109.d6b159cb14220daa49ff4a3f9a25f9f3" data-original-source="http://cdn.libravatar.org/avatar/d6b159cb14220daa49ff4a3f9a25f9f3" alt="Gravatar de Chimrod" class="gravatar" /><br/><i>Original post of <a href="http://blog.chimrod.com/2020/12/encore-des-cvs-en-rst/" title="Visit the source">Chimrod</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Cyrille BORNE : <a href="">LaTeX en sciences humaines</a> (04/09/2012)</li><li>Chimrod : <a href="">Se faire un CV en rst</a> (03/10/2015)</li><li>Matao : <a href="">divx2dvd : comment convertir des divx en un DVD</a> (16/04/2008)</li><li>Slobberbone : <a href="">gSharkDown - un client GTK du site de musique en ligne GrooveShark</a> (29/10/2012)</li><li>Framablog : <a href="">La marque (du langage) Python est en p&eacute;ril en Europe et a besoin de votre aide !</a> (15/02/2013)</li></ul></div></p>


feed_id: https://www.blog-libre.org/2020/12/05/les-petites-infos-8/
title: blog-libre : Les petites infos – 8
uri: blog-libre-Les-petites-infos-8
url: https://www.blog-libre.org/2020/12/05/les-petites-infos-8/
content:
<p>Tout seul on va plus vite, ensemble on va plus loin. Yeah man !</p>
<h3>Déchiffrer les disques sans intervention</h3>
<p><a href="https://opensource.com/" rel="noopener noreferrer" target="_blank">Opensource.com</a> est un des gros sites en Anglais à suivre, articles nombreux et de qualité, « supported by Red Hat ». <a href="https://opensource.com/article/20/11/nbde-linux" rel="noopener noreferrer" target="_blank">Unlock encrypted disks on Linux automatically</a> présente une solution que je ne connaissais pas : Network-Bound Disk Encryption (NBDE). Elle répond au problème de déchiffrer les disques sans intervention de l’utilisateur au boot.</p>
<p>Je n’utilise pas mais j’ai trouvé l’info et les outils présentés intéressants.</p>
<h3>Ctrl-s</h3>
<p>Si vous passez du temps dans un terminal, vous avez déjà malencontreusement appuyé sur la combinaison de touches Ctrl et s. Pour parler simplement le terminal freeze, vous tapez sur votre clavier mais rien ne change à l’écran. Pour <a href="https://unix.stackexchange.com/questions/12107/how-to-unfreeze-after-accidentally-pressing-ctrl-s-in-a-terminal" rel="noopener noreferrer" target="_blank">reprendre la main</a>, il suffit de faire Ctrl et q.</p>
<p>J’ai voulu <a href="https://unix.stackexchange.com/questions/332791/how-to-permanently-disable-ctrl-s-in-terminal" rel="noopener noreferrer" target="_blank">désactiver cette fonctionnalité</a>, j’ai opté pour ajouter <code>stty -ixon</code> dans mon .bashrc. Cependant une fois désactivée, l’appui sur Ctrl-s lance forward-search-history (<code>bind -p | grep C-s</code>) ce qui a tendance à m’emmerder encore plus. Au final j’ai rollback, Ctrl-s peut parfois servir quand on a des tonnes d’infos balancées sur le terminal (pour debug).</p>
<h3>scp -3</h3>
<p><a href="https://lwn.net/Articles/835962/" rel="noopener noreferrer" target="_blank">Deprecating scp</a> est paru début novembre sur <a href="https://lwn.net/" rel="noopener noreferrer" target="_blank">LWN.net</a> et fait le constat que scp est dépassé, peu sécurisé, de la daube. En attendant on continue à l’utiliser et j’ai découvert récemment <code>scp -3</code> : Copies between two remote hosts are transferred through the local host.</p>
<p>En général dans le monde pro on ne peut pas scp d’un serveur à un autre pour des mesures de sécurité, il faut ouvrir le firewall, valider la connexion SSH… pénible. <code>scp -3 server1:/home/toto/file.txt server2:/home/titi/</code> va faire le job (si vous pouvez vous connecter aux 2 serveurs évidemment).</p>
<h3>man en Français</h3>
<p>Saviez-vous que les manpages sont disponibles en d’autres langues que l’Anglais ? Personnellement je <code>sudo apt install manpages-fr manpages-fr-dev</code> (dispo sur <a href="https://packages.debian.org/search?keywords=manpages-fr" rel="noopener noreferrer" target="_blank">Debian Testing mais pas Buster</a>, dispo sur <a href="https://packages.ubuntu.com/search?keywords=manpages-fr" rel="noopener noreferrer" target="_blank">Ubuntu</a>). L’Anglais technique peut parfois être un frein à la compréhension surtout « au démarrage », j’apprécie commencer en lisant dans ma langue natale pour aller ensuite vers l’Anglais plus précis, exact et à jour.</p>
<p>Le gros point négatif des manpages autres qu’Anglais est qu’ils ne sont pas à jour parfois mal traduits. Je maintiens que c’est utile pour certains.</p>
<p>Il faut cependant un moyen rapide et simple de passer du man en Français à l’Anglais. Mon système étant en fr_FR.UTF-8 (<code>locale</code>), <code>man ls</code> affichera le man en Français, <code>men ls</code> en Anglais. J’ai créé l’alias <code>alias men='man -Len'</code> dans mon .bashrc.</p>
<h3>dpkg -S</h3>
<p>Souvent on veut savoir de quel paquet provient un fichier et régulièrement je vois utilisé apt-file, un des rares outils que je trouve mauvais voire inutile.</p>
<p><code>sudo apt install apt-file # Un paquet à installer<br>
sudo apt-file update # Il faut mettre à jour la base<br>
apt-file search -x '/usr/bin/free$' # 5 secondes d'attente, notez la syntaxe simple</code></p>
<p>dpkg est dispo de base avec l’option -S : Search for a filename from installed packages. Il n’est capable que de faire la relation entre fichiers et paquets installés mais c’est suffisant 9 fois sur 10.</p>
<p><code>dpkg -S /usr/share/themes/Mint-X-Aqua/gtk-2.0/styles/panel.rc<br>
mint-themes: /usr/share/themes/Mint-X-Aqua/gtk-2.0/styles/panel.rc</code></p>
<p><code>dpkg -S /usr/bin/free<br>
procps: /usr/bin/free</code></p>
<p>Professionnellement je cherche souvent d’où provient un programme, il est pénible de fournir le chemin complet alors je procède ainsi.</p>
<p><code>dpkg -S $(which free)<br>
procps: /usr/bin/free</code></p>
<p>Cependant on peut rencontrer.</p>
<p><code>dpkg -S $(which ls)<br>
dpkg-query: aucun chemin ne correspond à /usr/bin/ls</code></p>
<p>Lié à <a href="https://wiki.debian.org/UsrMerge" rel="noopener noreferrer" target="_blank">UsrMerge</a>, petit rappel pour Debian.</p>
<p><code>ls -l /bin /sbin /lib*<br>
lrwxrwxrwx 1 root root  7 28 janv.  2020 /bin -> usr/bin<br>
lrwxrwxrwx 1 root root  7 28 janv.  2020 /lib -> usr/lib<br>
lrwxrwxrwx 1 root root  9 28 janv.  2020 /lib32 -> usr/lib32<br>
lrwxrwxrwx 1 root root  9 28 janv.  2020 /lib64 -> usr/lib64<br>
lrwxrwxrwx 1 root root 10 28 janv.  2020 /libx32 -> usr/libx32<br>
lrwxrwxrwx 1 root root  8 28 janv.  2020 /sbin -> usr/sbin</code></p>
<p>La solution élégante.</p>
<p><code>dpkg -S $(which -a ls) # Flemme maximale<br>
dpkg-query: aucun chemin ne correspond à /usr/bin/ls<br>
coreutils: /bin/ls</code></p>
<p><code>dpkg -S $(which -a ls) 2>/dev/null # Propre mais qu'on ne tapera jamais par flemme<br>
coreutils: /bin/ls</code></p>
<p>Bref retenez <code>dpkg -S $(which -a ls)</code> surtout.</p>
<p><img src="media/25c7216e.1ea6f31074367d57d77721240d30fda9" data-original-source="http://cdn.libravatar.org/avatar/1ea6f31074367d57d77721240d30fda9" alt="Gravatar de blog-libre" class="gravatar" /><br/><i>Original post of <a href="https://www.blog-libre.org/2020/12/05/les-petites-infos-8/" title="Visit the source">blog-libre</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>blog-libre : <a href="">Les petites infos &ndash; 2</a> (07/12/2019)</li><li>blog-libre : <a href="">Les petites infos &ndash; Sp&eacute;cial NVMe</a> (15/02/2020)</li><li>blog-libre : <a href="">Les petites infos &ndash; 4</a> (11/04/2020)</li><li>blog-libre : <a href="">Les petites infos &ndash; 5</a> (13/06/2020)</li><li>blog-libre : <a href="">Les petites infos &ndash; 7</a> (23/08/2020)</li></ul></div></p>


feed_id: https://blog.genma.fr/?Ubuntu-Comment-avoir-la-derniere-version-du-client-Nextcloud
title: genma : Ubuntu - Comment avoir la dernière version du client Nextcloud ?
uri: genma-Ubuntu-Comment-avoir-la-dernière-version-du-client-Nextclou
url: https://blog.genma.fr/?Ubuntu-Comment-avoir-la-derniere-version-du-client-Nextcloud
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2926.jpg?1606481000" width="150" height="79"><div><p>Comme indiqué sur la page du wiki d'Ubuntu-fr, <a href="https://doc.ubuntu-fr.org/nextcloud-client" title="Wiki Ubuntu-fr - Page Nexctloud client">https://doc.ubuntu-fr.org/nextcloud-client</a></p>
<p><i>Il existe 4 méthodes pour installer le client Nextcloud sur Ubuntu : les dépôts officiels (à partir de focal), AppImage, Flatpak ou ajout de PPA.</i></p>
<p>Si l'on va sur le site de Nextcloud, section client pour PC, <a href="https://nextcloud.com/install/#install-clients" title="Site de Nextcloud - Page client Nextcloud">https://nextcloud.com/install/#install-clients</a> il est mis en avant et proposer de téléchager le client, au format "AppImage".</p>
<p>Mais il est également possible - et c'est ce que j'ai choisi de faire, de passer par "un PPA" (<a href="https://doc.ubuntu-fr.org/ppa" title="Présentation des PPA sur le wiki Ubuntu-fr">dépôts personnels de paquets logiciels ou Personal Package Archives (abrégés PPA)</a>).</p>
<p>Pour avoir le détail sur ce PPA, <a href="https://launchpad.net/~nextcloud-devs/+archive/ubuntu/client" title="Page du site Launchpad.net sur le client Nextcloud pour Ubuntu">https://launchpad.net/ nextcloud-devs/+archive/ubuntu/client</a></p>
<p>Sa mise en place est très simple, en quelques commandes :</p>
<div dir="ltr"><code>sudo add-apt-repository ppa:nextcloud-devs/client<br> sudo apt-get update<br> sudo apt install nextcloud-desktop</code></div>
<p>Avec cette installation, on a la version stable.</p>
<p>Pour les versions plus avancées, de développement, et par définition par forcément stable, on passera pas les PPA
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> alpha PPA <a href="https://launchpad.net/~nextcloud-devs/+archive/ubuntu/client-alpha" rel="nofollow external">https://launchpad.net/~nextcloud-devs/+archive/ubuntu/client-alpha</a>
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> beta PPA : <a href="https://launchpad.net/~nextcloud-devs/+archive/ubuntu/client-beta" rel="nofollow external">https://launchpad.net/~nextcloud-devs/+archive/ubuntu/client-beta</a></p>
<p>Une ligne du dessus change et devient</p>
<div dir="ltr"><code>sudo add-apt-repository ppa:nextcloud-devs/client-alpha</code></div>
<p>ou</p>
<div dir="ltr"><code>sudo add-apt-repository ppa:nextcloud-devs/client-beta</code></div>
<p>Enfin, pour avoir une intégration du client avec le gestionnaire de fichiers, selon la version d'Ubuntu ou dérivée que l'on utilise :</p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Stock Ubuntu with Nautilus : sudo apt install nautilus-nextcloud
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> KDE Ubuntu with Dolphin : sudo apt install dolphin-nextcloud
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Ubuntu MATE with Caja : sudo apt install caja-nextcloud
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Ubuntu Mint with Nemo : sudo apt installl nemo-nextcloud</p>
<p>Et donc dans le cas d'Ubuntu <i>classique</i> :</p>
<div dir="ltr"><code>sudo apt install nautilus-nextcloud</code></div>
<p>Pour finir, <a href="https://docs.nextcloud.com/desktop/3.0/" title="Nextcloud Desktop Client Manual">pour avoir le manuel complet, en anglais, du client Nextcloud, c'est par ici</a></p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Ubuntu-Comment-avoir-la-derniere-version-du-client-Nextcloud" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Clapico : <a href="">Geary, le client mail l&eacute;ger enfin en version multicompte dans votre Ubuntu</a> (01/04/2013)</li></ul></div></p>


feed_id: http://blog.chimrod.com/2020/12/prise-de-note-avec-graphviz/
title: Chimrod : Prise de note avec graphviz
uri: Chimrod-Prise-de-note-avec-graphviz
url: http://blog.chimrod.com/2020/12/prise-de-note-avec-graphviz/
content:
<p>J’utilise Graphviz depuis un moment — même pour des notes — car la
représentation en graphe permet de synthétiser facilement des notions complexes<span> </span>:</p>
<ul><li>relation de dépendances</li>
<li>séquence de processus</li>
<li>…</li>
</ul><p>Mais il me manquait une manière de pouvoir les créer de manière rapide,
c’est-à-dire avec une syntaxe adaptée à la prise de note, et pouvoir éditer le
résultat en temps réel. Or créer une syntaxe est quelque chose que je sais
faire, et voir le résultat en temps réel est possible grâce à <a href="http://viz-js.com/">viz.js</a> qui a
recompilé Graphviz en javascript à l’aide d’<a href="https://fr.wikipedia.org/wiki/Emscripten">Emscripten</a>, et permet donc de le
faire tourner dans le navigateur.</p>
<p>Il ne reste donc plus qu’à assembler tout ça, pour faire tourner un petit
éditeur de graphe. J’ai choisi de ne représenter que des tables, et d’utiliser
l’indentation pour marquer la relation au parent<span> </span>: (si vous souhaitez en
profiter en pleine page, c’est <a href="http://blog.chimrod.com/pages/graph-editor.html">ici que ça se passe</a>)</p>
<div>
<h2>La démo</h2>
<style>
#app {width: 100%; height: 100%; overflow: hidden; position: relative;}
#panes {display: flex; width: 100%; height: 100%; overflow: auto;}
#output svg, #output object { top: 0; left: 0; width: 100%; height: 100%; }
.flex-child {flex: 1;}
.vcenter {display: table-cell; vertical-align: middle}
#overlay {
display: table;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 99;
color: white;
text-align: center;
}
</style><div disabled>
  <button>Export <span>DOT</span></button>
  <button>Export <span>PNG</span></button>
  <div>
    <textarea>
g1
 Nom
 -
 propriété 1  g2:2
 propriété 2

g2
 Autre
 -
 propriété 1
 encore une autre <i>entrée</i>
 autre champ -> g1:3 retour

g3
 Dernier élément
 -
 ligne 2
 ligne 3
</textarea><div>
    <div>
      <div><object data="//blog.chimrod.com/resources/viz.js/example.svg" type="image/svg+xml"></object></div>
        <div></div>
      </div>
    </div>
  </div>
  <div>
  </div>
</div><div>
<p>Exécution du script</p>
<p>Les librairies étant relativement lourdes (+2Mo), elles ne sont pas chargées
automatiquement avec la page. Je vous laisse cliquer sur le bouton pour les
charger et lancer la mise à jour.</p>
<div><div>
<button type="button">Activer</button>
</div>

</div></div>
<p>Vous pouvez édite le texte ci-dessus pour mettre à jour le graphe de la partie
droite directement. Les nœuds sont représentés à l’aide des <a href="https://www.graphviz.org/doc/info/shapes.html#html"><span>HTML</span> Like label</a>
de graphviz, il est donc possible d’utiliser de la couleur, ou des balises de
mises en formes qui seront reprises dans le graphe final. Tout ce qui est saisi
est transformé dans le navigateur, et aucune donnée ne transite sur le réseau.</p>
<p>Avec les boutons d’export, cela me suffit pour produire un petit schéma
rapidement, ou ensuite le retravailler le fichier dot correspondant si j’ai
besoin d’aller plus loin…</p>
</div>
<div>
<h2>Le code</h2>
<p>Il est écrit en OCaml et compilé en javascript (c’est pour ça qu’il s’exécute
dans la page). Vous pouvez télécharger une version hors ligne à exécuter en
local ci-dessous<span> </span>:</p>
<div>
<a href="http://blog.chimrod.com/resources/viz.js/graphviz.zip"><img alt="get the file" src="media/8124c748.package-x-generic.png" data-original-source="http://blog.chimrod.com/images/package-x-generic.png"></a>
<p>Télécharger</p>
</div>
<p>la commande <tt>make html</tt> permet de régénérer les sources.</p>
</div>
<p><img src="media/51a0b109.d6b159cb14220daa49ff4a3f9a25f9f3" data-original-source="http://cdn.libravatar.org/avatar/d6b159cb14220daa49ff4a3f9a25f9f3" alt="Gravatar de Chimrod" class="gravatar" /><br/><i>Original post of <a href="http://blog.chimrod.com/2020/12/prise-de-note-avec-graphviz/" title="Visit the source">Chimrod</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #49
uri: 2020-12-07-Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-49
feed_id:
https://blog.journalduhacker.net/index.php?article300/liens-interessants-journal-du-hacker-semaine-49-2020

url:
https://blog.journalduhacker.net/index.php?article300/liens-interessants-journal-du-hacker-semaine-49-2020

content:
<p>Pour la 49ème semaine de l'année 2020, voici <strong>10 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/2p9ti2/un_avec_sailfishos">Un an avec SailfishOS</a></li>
<li><a href="https://www.journalduhacker.net/s/nxlqau/les_vpns_et_leur_m_susage">Les VPNs et leur mésusage</a></li>
<li><a href="https://www.journalduhacker.net/s/bya9sw/t_l_travail_la_cnil_interdit_les">Télétravail : la Cnil interdit les keyloggers et tous les outils de surveillance déloyale du salarié</a></li>
<li><a href="https://www.journalduhacker.net/s/kealc8/restic_rempla_ant_de_borg_et_duplicati">Restic, remplaçant de borg et duplicati</a></li>
<li><a href="https://www.journalduhacker.net/s/dwpph7/l_homme_qui_hululait_l_oreille_des">L’homme qui hululait à l’oreille des formulaires</a></li>
<li><a href="https://www.journalduhacker.net/s/63hend/cracker_un_mot_de_passe">Cracker un mot de passe</a></li>
<li><a href="https://www.journalduhacker.net/s/axpdbb/param_tres_nomm_s_en_php_8">Paramètres nommés en PHP 8</a></li>
<li><a href="https://www.journalduhacker.net/s/29om39/m_triques_monitoring_push_vs_pull_riemann">Métriques, monitoring, push vs pull, Riemann, Vector</a></li>
<li><a href="https://www.journalduhacker.net/s/0jakam/le_protocole_gemini_revenir_du_simple_et_s">Le protocole Gemini, revenir à du simple et sûr pour distribuer l'information en ligne ?</a></li>
<li><a href="https://www.journalduhacker.net/s/wg4goj/simuler_de_la_perte_de_paquet_et_de_la">Simuler de la perte de paquet et de la latence sous Linux avec tc</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://twitter.com/journalduhacker">Le compte Twitter du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article300/liens-interessants-journal-du-hacker-semaine-49-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #49</a> (12/12/2016)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #49</a> (11/12/2017)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #49</a> (10/12/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #49</a> (09/12/2019)</li></ul></div></p>


feed_id: https://www.deblan.io/post/593/decrets-pasp-fichage-massif-des-militants-politiques
title: Simon Vieille : Décrets PASP : fichage massif des militants politiques
uri: Simon-Vieille-Décrets-PASP-fichage-massif-des-militants-politique
url: https://www.deblan.io/post/593/decrets-pasp-fichage-massif-des-militants-politiques
content:
<blockquote>
  <p>Après la loi sécurité globale et la loi séparatisme, le gouvernement poursuit 
  son offensive généralisée visant à museler toute opposition politique. 
  Mercredi dernier, les trois fichiers de « sécurité publique » (PASP, GIPASP et EASP) 
  ont été largement étendus par trois décrets (ici, ici et là). Ils</p>
</blockquote>

<p>On y est, on peut maintenant être fiché pour nos opinions politiques, 
nos convictions philosophiques, religieuses ou notre appartenance syndicale.</p>

<p>Alors pour reprendre un vieux débat sur la protection des données où on me répondait "je n'ai rien à cacher", 
ma réponse était systématiquement :</p>

<ul><li>Bien sur si, tu as des choses à cacher car ta vie privée est par définition privée</li>
<li>Dans un futur plus ou moins proche, on pourra te reprocher quelque chose encore toléré aujourd'hui.</li>
</ul><p>Ce futur est maintenant le présent.</p>

<p>En dehors de toute activité, nos simples opinions seront inscrites dans un fichier 
d'état. C'est très grave et nous avons avançons encore vers un état totalitaire. 
Je pense que le point de non retour à été atteint.</p>
<p><img src="media/f6ec4698.a99922fd1c4e000d5911b8c88280938e" data-original-source="http://cdn.libravatar.org/avatar/a99922fd1c4e000d5911b8c88280938e" alt="Gravatar de Simon Vieille" class="gravatar" /><br/><i>Original post of <a href="https://www.deblan.io/post/593/decrets-pasp-fichage-massif-des-militants-politiques" title="Visit the source">Simon Vieille</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://blog.genma.fr/?Ubuntu-Modifier-la-barre-de-raccourci-Unity-via-Ansible
title: genma : Ubuntu - Modifier la barre de raccourci Unity via Ansible
uri: genma-Ubuntu-Modifier-la-barre-de-raccourci-Unity-via-Ansible
url: https://blog.genma.fr/?Ubuntu-Modifier-la-barre-de-raccourci-Unity-via-Ansible
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2925.jpg?1606473304" width="150" height="79"><div><p><strong>Introduction</strong></p>
<p>Je reprends mon projet d'Ubuntu mode kiosk (cf ma conférence au Capitole du Libre 2019 <a href="https://blog.genma.fr/" title="Un mode Kiosk avec Ubuntu en 2019, c'est possible ! — Genma">Un mode Kiosk avec Ubuntu en 2019, c'est possible !</a>), j'ai beaucoup de travail (et peu de temps) pour compléter et remettre la documentation à jour pour la rendre publique.</p>
<p>En attendant, un petit tutoriel qui pourra être utile.</p>
<p><strong>La demande du client</strong></p>
<p>Ajouter Libreoffice et ajouter les icônes de raccourci dans la barre de gauche (issue du design de Unity, repris suite au passage à Gnome Shell pour Ubuntu il y a quelques versions de cela).</p>
<p>En image, cela donne :</p>
<p><span>
<img src="https://blog.genma.fr/local/cache-vignettes/L82xH209/raccourcis-39e31.png?1606473311" width="82" height="209" alt=""></span></p>
<p><strong>Comment faire ça ?</strong></p>
<p>Pour le faire, je passe par un playbook Ansible. Si on connaît un peu Ansible, on verra qu'il n'y a rien de bien sorcier.</p>
<div dir="ltr"><code>---<br> - hosts: ParcUbuntu<br> remote_user: genma<br><br> tasks:<br> # Installation de Libreoffice<br> - name: install libreoffice<br> become: yes<br> apt:<br> update_cache=yes<br> state=latest<br> name=libreoffice<br> # Installation de Libreoffice en français<br> - name: install libreoffice-l10n-fr<br> become: yes<br> apt:<br> update_cache=yes<br> state=latest<br> name=libreoffice-l10n-fr<br> # Ajout des favoris<br> - name: ajout des icones favoris<br> shell: gsettings set org.gnome.shell favorite-apps "['firefox.desktop', 'libreoffice-writer.desktop', 'libreoffice-calc.desktop' ]"<br></code></div>
<p><strong>L'astuce</strong>est donc dans la commande <i> gsettings set org.gnome.shell favorite-apps "[ ...]"</i> qui permet de changer l'équivalent de la clef de registre (au sens Windows de ces termes) pour définir les favoris de la barre de côté de la session Gnome de l'utilisateur.</p>
<p>Ici, on définit les favoris /icones de raccourcis.</p>
<p>Si ça peut être utile d'autre...</p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Ubuntu-Modifier-la-barre-de-raccourci-Unity-via-Ansible" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://mart-e.be/post/2020/12/12/acceder-a-un-systeme-luks-manuellement/
title: mart-e : Accéder à un système LUKS manuellement
uri: mart-e-Accéder-à-un-système-LUKS-manuellement
url: https://mart-e.be/post/2020/12/12/acceder-a-un-systeme-luks-manuellement/
content:
<p>Après la mise à jour journalière de mon pc portable (sous <a rel="noreferrer noopener" href="https://www.archlinux.org/" target="_blank">Archlinux</a>) et le redémarrage hebdomadaire, le drame : on entre le mot de passe de déchiffrement (<a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/Linux_Unified_Key_Setup" target="_blank">LUKS</a>) et…</p>



<p>_</p>



<p>Oui, juste « _ »</p>



<p>Pas d’erreur, rien.</p>



<p>_</p>



<p>Première étape : on augmente le <code>loglevel</code> et on retire le <code>quiet</code> dans la ligne de <a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/GNU_GRUB" target="_blank">GRUB</a> (voir <a rel="noreferrer noopener" href="https://www.thegeekdiary.com/centos-rhel-6-how-to-change-the-verbosity-of-debug-logs-during-booting/" target="_blank">CentOS / RHEL 6 : How to change the verbosity of debug logs during booting</a>). De mon coté, le déchiffrement fonctionne (c’est-à-dire, il accède au contenu du disque et commence la procédure de boot) mais s’arrête abruptement sans plus d’info.</p>



<figure><img loading="lazy" width="1024" height="576" src="media/261aa722.vlcsnap-2020-12-12-09h58m09s593-1024x576.png" data-original-source="https://mart-e.be/wp-content/uploads/2020/12/vlcsnap-2020-12-12-09h58m09s593-1024x576.png" alt="" srcset="https://mart-e.be/wp-content/uploads/2020/12/vlcsnap-2020-12-12-09h58m09s593-1024x576.png 1024w, https://mart-e.be/wp-content/uploads/2020/12/vlcsnap-2020-12-12-09h58m09s593-300x169.png 300w, https://mart-e.be/wp-content/uploads/2020/12/vlcsnap-2020-12-12-09h58m09s593-768x432.png 768w, https://mart-e.be/wp-content/uploads/2020/12/vlcsnap-2020-12-12-09h58m09s593-1200x675.png 1200w, https://mart-e.be/wp-content/uploads/2020/12/vlcsnap-2020-12-12-09h58m09s593.png 1280w" sizes="(max-width: 1024px) 100vw, 1024px"><figcaption>Ce que l’on peut voir avec <code>loglevel</code> supérieur</figcaption></figure><p>Pas des plus informatif sur la source du problème mais au moins, il arrive à démarrer (filmez votre écran et rejouez la vidéo en <a rel="noreferrer noopener" href="https://www.techwhoop.com/frame-by-frame-vlc/" target="_blank">image par image</a>).</p>



<figure><a href="https://www.flickr.com/photos/sdasmarchives/8663892916/in/photolist-ecAHw5-7vfcTy-7vfa8w-2jxMsyQ-bbq5AX-qcC4jt-2jztydZ-2jyo4Nf-9GH2qS-7xyXgH-om8RHz-6P3wbH-MZobqL-9GE9Wz-pzmWXd-d74CaC-mv4ZwZ-9wBhhn-8nB9bS-7mafgP-r9qwba-5JKzmp-2hawpY6-5JTHpW-sP8CaN-GWMZ4m-qraiWm-2iLnMvg-cyDYpo-bLnJ2t-cyDYnq-oxdbXZ-rAxcAZ-qRakfP-ovshmk-oxv2BX-aSuYPK-bF9D5L-4jyEJ9-cE81Mf-bxt1HG-5JR1Dz-bU4qZz-2hawpYm-237WYtG-4juXDz-dKkyRv-CD7KTs-9wA5XX-ieaqjV"><img loading="lazy" width="700" height="457" src="media/21919a8b.8663892916_f048be298f_o.jpg" data-original-source="https://mart-e.be/wp-content/uploads/2020/12/8663892916_f048be298f_o.jpg" alt="" srcset="https://mart-e.be/wp-content/uploads/2020/12/8663892916_f048be298f_o.jpg 700w, https://mart-e.be/wp-content/uploads/2020/12/8663892916_f048be298f_o-300x196.jpg 300w" sizes="(max-width: 700px) 100vw, 700px"></a><figcaption>Dans l’attente d’un message d’erreur lors du boot</figcaption></figure><p>Pas beaucoup d’info mais pas de stress, on crée un live USB (j’ai pris une clef USB <a rel="noreferrer noopener" href="https://ubuntu.com/download/desktop/thank-you?version=20.04.1&amp;architecture=amd64" target="_blank">Ubuntu</a>, il n’est pas obligatoire d’utiliser le même OS que celui installé). On démarre et on lance un terminal:</p>



<pre>$ sudo fdisk -l
..
Disk /dev/nvme0n1: 238.49 GiB, 256060514304 bytes, 500118192 sectors
Disk model: PC SN520 NVMe WDC 256GB
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: EECB8607-5D1A-4B49-BF5E-7D2012C5FB97
Device Start End Sectors Size Type
/dev/nvme0n1p1 2048 411647 409600 200M EFI System
/dev/nvme0n1p2 411648 500118158 499706511 238.3G Linux filesystem</pre>



<p>Voici mon disque, une partition boot, en clair, sur <code>nvme0n1p1</code> et une partition chiffrée avec LUKS sur <code>nvme0n1p2</code>. On va donc les monter pour y accéder:</p>



<pre>$ sudo mount /dev/nvme0n1p2 /mnt/
mount: /mnt: unknown filesystem type 'crypto_LUKS'.
$ sudo cryptsetup luksOpen /dev/nvme0n1p2 mydisk
Enter passphrase for /dev/nvme0n1p2: *****
$ sudo vgscan
Found volume group "MyVolGroup" using metadata type lvm2
$ ls /dev/mapper/
control mydisk MyVolGroup-root
$ sudo mount /dev/mapper/MyVolGroup-root /mnt/
$ sudo mount /dev/nvme0n1p1 /mnt/boot/
$ sudo mount -B /dev /mnt/dev
$ sudo mount -B /dev/pts /mnt/dev/pts
$ sudo mount -B /proc /mnt/proc
$ sudo mount -B /sys /mnt/sys
$ sudo mount -B /run /mnt/run
$ sudo cp /etc/resolv.conf /mnt/etc/resolv.conf</pre>



<p>Toutes ces commandes me permettent d’avoir un système fonctionnel dans le dossier <code>/mnt</code>. La dernière commande permet d’avoir accès à internet lors du <a rel="noreferrer noopener" href="https://en.wikipedia.org/wiki/Chroot" target="_blank">chroot</a>.</p>



<pre>$ sudo chroot /mnt
# pacman -Syu
…
-> Running build hook: [encrypt]
-> Running build hook: [lvm2]
-> Running build hook: [filesystems]
-> Running build hook: [keyboard]
-> Running build hook: [fsck]
==> Generating module dependencies
==> Creating gzip-compressed initcpio image: /boot/initramfs-linux-fallback.img
==> Image generation successful
(11/17) Reloading system bus configuration…
Running in chroot, ignoring command 'try-reload-or-restart'
(12/17) Probing GDK-Pixbuf loader modules…
(13/17) Probing 32-bit GDK-Pixbuf loader modules…
(14/17) Updating icon theme caches…
(15/17) Updating the info directory file…
(16/17) Updating the desktop file MIME type cache…
(17/17) Updating the MIME type database…</pre>



<p>Dans mon cas, il s’agissait probablement d’une mise à jour corrompue. Donc, mettre à jour le système (avec une mise à jour du paquet linux en bonus) a réglé le souci. Si vous aviez un autre problème (GRUB mal installé par exemple), le <code>chroot</code> est également une bonne façon de procéder. Une fois les manipulations finies, on sort du <code>chroot</code> et on referme tous les disques.</p>



<pre># exit
ubuntu@ubuntu:~$ sudo umount /mnt/dev/pts
ubuntu@ubuntu:~$ sudo umount /mnt/dev/
ubuntu@ubuntu:~$ sudo umount /mnt/sys
ubuntu@ubuntu:~$ sudo umount /mnt/run
ubuntu@ubuntu:~$ sudo umount /mnt/proc
ubuntu@ubuntu:~$ sudo umount /mnt/boot
ubuntu@ubuntu:~$ sudo umount /mnt
ubuntu@ubuntu:~$ sudo cryptsetup close MyVolGroup-root
ubuntu@ubuntu:~$ sudo cryptsetup close mydisk
ubuntu@ubuntu:~$ sudo reboot</pre>



<p>Et après un redémarrage et un peu de sueur froide, le système redémarre correctement !</p>



<div><figure><a href="https://www.flickr.com/photos/nypl/3110056172/in/photolist-5JPRm9-9hgqiJ-7VEEgT-pqMcEP-owvJnz-rmSNm4-29MGAqN-ecACKL-kEJz7c-otF8wG-9VG1u3-owjpBc-fyyAXy-qm2yUE-4jCnWj-ecACMS-9oAqh3-aoZfvF-oeRNhr-idNTNp-2jzLLob-Ufdwph-4jyX3q-ecv1AB-xgy8gT-MdwAoo-qm2yXL-w9vio5-2e5cq89-otaXeY-owqxaV-ovf4ST-eXssAq-owrcN6-NNnPvY-od7ZDg-ecv1at-4jykoK-28nsScB-pre4qG-oeYCLh-i6Thwo-BLgrE9-tYfq8w-4jCD5j-ownLRR-ow9ddu-6arLK1-bv8Bk6-4jCDbo"><img loading="lazy" width="760" height="557" src="media/1037bf9e.3110056172_b75b13223d_c.jpg" data-original-source="https://mart-e.be/wp-content/uploads/2020/12/3110056172_b75b13223d_c.jpg" alt=" Limberger's Victory (cinema 1915) " srcset="https://mart-e.be/wp-content/uploads/2020/12/3110056172_b75b13223d_c.jpg 760w, https://mart-e.be/wp-content/uploads/2020/12/3110056172_b75b13223d_c-300x220.jpg 300w" sizes="(max-width: 760px) 100vw, 760px"></a></figure></div>
<p><img src="media/94f3e934.0c49d7e5a294cb2ca762eaede426b7a4" data-original-source="http://cdn.libravatar.org/avatar/0c49d7e5a294cb2ca762eaede426b7a4" alt="Gravatar de mart-e" class="gravatar" /><br/><i>Original post of <a href="https://mart-e.be/post/2020/12/12/acceder-a-un-systeme-luks-manuellement/" title="Visit the source">mart-e</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>mart-e : <a href="">Archlinux avec LUKS et LVM sur un SSD</a> (14/01/2013)</li><li>mart-e : <a href="">R&eacute;parer un syst&egrave;me LUKS apr&egrave;s la derni&egrave;re mise &agrave; jour de LVM</a> (24/02/2013)</li><li>mart-e : <a href="">Enlever le DRM Adobe sous Linux</a> (02/05/2020)</li></ul></div></p>


feed_id: http://www.fullcirclemag.fr/?post/2020/12/12/Bonnes-f%C3%AAtes
title: Full Circle Magazine FR : Bonnes fêtes
uri: Full-Circle-Magazine-FR-Bonnes-fêtes
url: http://www.fullcirclemag.fr/?post/2020/12/12/Bonnes-f%C3%AAtes
content:
<p>Bonjour à nos fidèles lecteurs et lectrices !
Notre petite équipe de traduction est fière de vous présenter le numéro 163, celui de novembre, en français. Comme toujours, il est disponible à la lecture et au téléchargement sur notre page <a href="https://www.fullcirclemag.fr/?pages/Num%C3%A9ros" hreflang="fr">NUMÉROS</a> ou peut être récupéré directement en cliquant sur la photo de couverture ci-dessous.</p>


<p><a href="http://www.fullcirclemag.fr/?download/691" hreflang="fr"><img src="media/a8cbdf15.numero163.png" data-original-source="http://www.fullcirclemag.fr/dotclear/public/Numeros/Couvertures_PNG/numero163.png" alt=""></a></p>


<p>Vous y trouverez les tutoriels familiers, Python, Podcasts et Inkscape, avec une présentation de MicroPad (voir photo). Outre les autres bonnes choses habituelles, il y a des critiques : celle de Xubuntu 20.10 (en gros, il n'y a aucun changement depuis la 20.04 LTS ! Pourquoi ? À vous de voir...) et celle du Kit de Raspberry Pi 400, où quasiment rien ne manque à part un écran. Avec une batterie sur USB, il peut même être mobile et pour un tout petit prix !</p>


<p>La troisième critique concerne deux jeux Open Source en 4X basés sur <em>Master of Orion</em> (1993) avec des graphismes époustouflants et une magnifique bande son. <em>Free Orion</em> n'est pas encore à la version 1.0 et <em>Remnants of the Precursors</em> est en version bêta, mais, d'après les développeurs, c'est pleinement jouable. Laissez vous tenter !</p>


<p>Bonne lecture et bonnes fêtes de fin d'année, malgré la pandémie. Surtout, restez en bonne santé !</p>


<p>Bab, scribeur et relecteur, d52fr, traducteur et relecteur, et moi-même, AuntieE, traductrice et relectrice</p>
<p><img src="media/163a60d9.dd0e1a508d7347d53e0da0678bfd7aff" data-original-source="http://cdn.libravatar.org/avatar/dd0e1a508d7347d53e0da0678bfd7aff" alt="Gravatar de Full Circle Magazine FR" class="gravatar" /><br/><i>Original post of <a href="http://www.fullcirclemag.fr/?post/2020/12/12/Bonnes-f%C3%AAtes" title="Visit the source">Full Circle Magazine FR</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Full Circle Magazine FR : <a href="">Voici, enfin, le num&eacute;ro 52 !</a> (04/11/2011)</li><li>Full Circle Magazine FR : <a href="">Et voici.. le num&eacute;ro 53 !</a> (13/12/2011)</li><li>Full Circle Magazine FR : <a href="">Le num&eacute;ro 54... enfin !</a> (18/01/2012)</li><li>Full Circle Magazine FR : <a href="">Sortie du num&eacute;ro 56</a> (09/03/2012)</li><li>Full Circle Magazine FR : <a href="">Voici le 57 !</a> (29/03/2012)</li></ul></div></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #50
uri: 2020-12-14-Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-50
feed_id:
https://blog.journalduhacker.net/index.php?article301/liens-interessants-journal-du-hacker-semaine-50-2020

url:
https://blog.journalduhacker.net/index.php?article301/liens-interessants-journal-du-hacker-semaine-50-2020

content:
<p>Pour la 50ème semaine de l'année 2020, voici <strong>15 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/wf7ido/la_tech_fran_aise_reste_toxique">La tech française reste toxique</a></li>
<li><a href="https://www.journalduhacker.net/s/yjorw6/combien_faut_il_dutilisateurs_de_gnu">Combien faut-il d'utilisateurs de GNU/Linux pour changer une ampoule ?</a></li>
<li><a href="https://www.journalduhacker.net/s/2fc5nz/que_choisir_entre_rust_et_go">Que choisir entre Rust et Go</a></li>
<li><a href="https://www.journalduhacker.net/s/txmfrd/comment_prononcer_correctement_rsync">Comment prononcer correctement rsync ?</a></li>
<li><a href="https://www.journalduhacker.net/s/eicker/centos_se_saborde">CentOS se saborde ?</a></li>
<li><a href="https://www.journalduhacker.net/s/d3iyvs/dotclear_2_18">Dotclear 2.18</a></li>
<li><a href="https://www.journalduhacker.net/s/qjlphh/un_peu_de_s_curit_avec_nginx">Un peu de sécurité avec Nginx</a></li>
<li><a href="https://www.journalduhacker.net/s/66h8ox/migrer_de_centos_8_centos_stream">Migrer de CentOS 8 à CentOS Stream</a></li>
<li><a href="https://www.journalduhacker.net/s/k0tabt/migrer_de_centos_oracle_linux_petit">Migrer de CentOS à Oracle Linux – Petit retour d’expérience</a></li>
<li><a href="https://www.journalduhacker.net/s/sj66xu/firefox_extensions_configuration_et">Firefox : extensions, configuration et quelques astuces</a></li>
<li><a href="https://www.journalduhacker.net/s/toxsae/linux_ne_mint_resse_plus">Linux ne m'intéresse plus</a></li>
<li><a href="https://www.journalduhacker.net/s/xazdsr/la_sant_balbutiante_de_la_fondation">La santé balbutiante de la fondation Mozilla menace Firefox</a></li>
<li><a href="https://www.journalduhacker.net/s/4nfj6y/5_ans_dannonces_demploi_autour_du">5 ans d'annonces d'emploi autour du Logiciel Libre</a></li>
<li><a href="https://www.journalduhacker.net/s/zpfnc7/l_engagement_de_l_anssi_pour_l_open_source">L’engagement de l’ANSSI pour l’open source</a></li>
<li><a href="https://www.journalduhacker.net/s/r9h9ui/aws_tombe_linternet_tremble">AWS tombe, l'internet tremble</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://twitter.com/journalduhacker">Le compte Twitter du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article301/liens-interessants-journal-du-hacker-semaine-50-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #50</a> (19/12/2016)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #50</a> (18/12/2017)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #50</a> (17/12/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #50</a> (16/12/2019)</li></ul></div></p>


feed_id: https://blog.genma.fr/?Nextcloud-Le-Dasboard-00-N
title: genma : Nextcloud - Le Dasboard 00/N
uri: genma-Nextcloud-Le-Dasboard-00-N
url: https://blog.genma.fr/?Nextcloud-Le-Dasboard-00-N
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2930.jpg?1607678787" width="150" height="79"><div><p>Ce billet est le premier d'une potentielle série de billet sur la fonctionnalité Dashboard de Nextcloud, apparue avec la version 20.<br><strong>Ces billet sont co-écrits par Genma &amp; Brume</strong>.</p>
<p><strong>Objectifs de cette série</strong></p>
<p>Présenter la fonctionnalité Dashboard de Nextcloud et la démarche de recherche d'informations, des tutoriels, en vue de pouvoir ajouter des <i>fonctionnalités</i> dans ce Dashoard.</p>
<p><strong>Introduction</strong></p>
<p>Depuis Nextcloud 20, un Dashboard a été intégré à Nextcloud. Il est sur la page d'accueil de l'application et permet en un clin d'oeil d'être au courant des dernières notifications : mails, conversations, derniers fichiers édités... mais également des notifications sur d'autres sites : des intégrations. Il est par exemple possible de voir ses dernières notifications GitHub, Facebook, Mastodon...</p>
<p>Chaque élément sur ce Dashboard est un widget. Notre but ici, est de récolter le plus d'informations possibles à ce sujet, afin d'essayer d'en créer.</p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/nextcloud_dashboard_00.png?1607678964" width="500" height="284" alt=""></span></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Présentation du Dashboard sur le site de Nextcloud : <a href="https://nextcloud.com/dashboard/" title=" https://nextcloud.com/dashboard/"> https://nextcloud.com/dashboard/</a>
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> Documentation de Nextcloud sur le Dashboard, en anglais : <a href="https://docs.nextcloud.com/server/20/developer_manual/digging_deeper/dashboard.html" title="Documentation de Nextcloud sur le Dashboard, en anglais">https://docs.nextcloud.com/server/20/developer_manual/digging_deeper/dashboard.html</a></p>
<p><strong>Une application Dashboard ?</strong></p>
<p>Pour commencer, il est important de savoir qu'avant la version 20, il existait déjà un Dashboard, sous forme d'application Nextcloud. Le code de l'application a donc été intégré à Nextcloud, et l'application est devenue obsolète. Nous pouvons donc nous demander si les tutoriels pour cette application sont toujours valables ou non à l'heure actuelle.</p>
<p>Le dépôt de l'application obsolète (archivé) : <a href="https://github.com/nextcloud/dashboard" title="https://github.com/nextcloud/dashboard"> https://github.com/nextcloud/dashboard</a></p>
<p><strong>Les technologies utilisées</strong></p>
<p>Nextcloud utilise principalement du PHP et le framework VueJS. Cependant, l'environement de développement est assez poussé, et il ne suffit pas de connaïtre ses deux langages, il est aussi nécessaire de connaitre l'environnement de développement de Nextcloud.</p>
<p><strong>Applications et widgets</strong></p>
<p>Il est nécessaire de créer une application pour créer un widget, le widget n'étant qu'un pont entre l'application et le Dashboard.</p>
<p>Il sera donc pertinent, en plus de se focaliser sur la partie "Widget" pure, d'approfondir (et de partager les connaissances) autour de la création d'une application Nextcloud.</p>
<p><strong>Quelques ressources</strong></p>
<p><strong>Posts du forum pertinents</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><a href="https://help.nextcloud.com/t/vue-js-setup-for-app-development/55209" title="Vue.js setup for app development">Vue.js setup for app development</a> : Ce post parle de l'enviromnement Vue.js sur Nextcloud. Il donne un lien intéressant : <a href="https://github.com/skjnldsv/vueexample" rel="nofollow external">https://github.com/skjnldsv/vueexample</a>, un exemple d'application Nextcloud en Vue. Il explique que le templace HTML est juste un `div` vide, que Vue va utiliser pour le remplacer par son code. Il liste également tous les fichiers notables de l'application, ce qui serait intéressant de décortiquer.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><a href="https://help.nextcloud.com/t/app-development-setup/72290" title="App development setup">App development setup</a> Ce post exprime la difficulté d'une personne à mettre en place son setup de développement Nextcloud. Il n'y a pas énormément d'informations qui pourront nous être utiles, mais il reste intéressant. Il y est d'ailleurs mentionné une série de vidéos tutoriel sur Nextcloud, mais elles sont en allemand.</p>
<p><strong>Vidéos pertinentes</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><a href="https://www.youtube.com/watch?v=jjveUeZKfHo&amp;list=PL0ZTCrsTNYF9EnvK39wVng4WFpEdX8X0I" title="Nextcloud App Entwicklung #1 - Entwicklungsumgebung">Nextcloud App Entwicklung #1 - Entwicklungsumgebung</a> Ces vidéos tutoriel en allemand <i>ont l'air bien</i>, mais malheureusement peu accessibles pour les non germanophones. <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><a href="https://www.youtube.com/watch?v=uhoSC2Say8s" title="[Tech Talk] Create your first Nextcloud-App @ DO!Hack 2017">[Tech Talk] Create your first Nextcloud-App @ DO !Hack 2017</a> Conférence en allemand sur la création d'application dans Nextcloud (27 minutes)<br><a href="https://www.youtube.com/watch?v=_PCJHK9mSBg" title="Working with Nextcloud's JavaScript APIs - Christoph Wurst">Working with Nextcloud's JavaScript APIs - Christoph Wurst</a> Cette vidéo de 4 minutes, en anglais, parle de la toute récente API front-end de Nextcloud.</p>
<p><strong>Fin de ce premier billet d'intégration</strong>.</p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Nextcloud-Le-Dasboard-00-N" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


uri: miamondo-Labortablo-une-interface-de-bureau-codée-en-Python-sur-un
feed_id:
https://miamondo.org/2020/12/14/labortablo-une-interface-de-bureau-sur-une-base-archlinux-openbox-1ere-partie/

title:
miamondo : Labortablo, une interface de bureau codée en Python sur une base Archlinux/Openbox (1ère partie)

url:
https://miamondo.org/2020/12/14/labortablo-une-interface-de-bureau-sur-une-base-archlinux-openbox-1ere-partie/

content:
<p>Dans cet article, je vais vous présenter un projet personnel qui certes, m’a pris un peu de temps, mais que j’ai réussi à mener jusqu’à son terme, après plusieurs échecs. Il est construit sur une base <a rel="noreferrer noopener" href="https://archlinux.org/" target="_blank"><strong>Archlinux</strong></a> et <strong><a rel="noreferrer noopener" href="https://wiki.archlinux.org/index.php/Openbox" target="_blank">Openbox</a></strong>. Pour le coder, j’ai utilisé un bien bel outil qui fera sans doute l’objet d’un prochain article. Il s’agit de <strong><a rel="noreferrer noopener" href="https://www.jetbrains.com/fr-fr/pycharm/" target="_blank">pycharm</a></strong>, en version <em>Community</em> gratuite et open source. C’est un vrai plaisir de coder avec cet environnement de développement intégré, dont le thème <em>Material</em> se marie à merveille avec le design de mon projet.</p>



<figure><img data-attachment-id="1058" data-permalink="https://miamondo.org/pycharm_-1/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png" data-orig-size="1919,1077" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="pycharm_-1" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png?w=768 768w, https://miamondo96030527.files.wordpress.com/2020/12/pycharm_-1.png 1919w" sizes="(max-width: 1024px) 100vw, 1024px"></figure><p>Alors de quoi s’agit-il au juste? Il s’agit d’une interface de bureau entièrement codé en Python, à l’exception d’un petit script en bash. Je l’ai baptisé <em><a href="https://gitlab.com/miamondo/labortablo" target="_blank" rel="noreferrer noopener"><strong>Labortablo</strong></a></em> ce qui, en espéranto, signifie tout simplement <em>bureau</em>. Il est composé d’un menu de douze catégories (<em>Accessoires</em>, <em>Internet</em>, <em>Bureautique</em> etc…), lesquelles se décomposent en autant de menus d’applications (par exemple, <em>Chromium</em>, <em>Brave</em>, <em>Falkon</em> pour le menu <em>Internet</em>). Cette interface de bureau est juste un projet expérimental mais j’ai pris soin de le coder aussi proprement que me le permettent mes capacités. Vous trouverez le code <strong><a href="https://gitlab.com/miamondo/labortablo" target="_blank" rel="noreferrer noopener">ici</a></strong>.</p>



<p>Le fond d’écran est celui d’Openbox mais il est habillé d’une image grâce à cette commande, placée dans le fichier <strong>~/.config/openbox/autostart</strong>. </p>


<pre>
hsetroot -center "/chemin/vers/image.png" &amp;
</pre>


<figure><img data-attachment-id="1035" data-permalink="https://miamondo.org/wp/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/wp.png" data-orig-size="1910,1071" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="wp" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/wp.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/wp.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/wp.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/wp.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2020/12/wp.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/wp.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/wp.png?w=768 768w, https://miamondo96030527.files.wordpress.com/2020/12/wp.png 1910w" sizes="(max-width: 1024px) 100vw, 1024px"><figcaption>Fond d’écran Openbox personnalisé avec hsetroot</figcaption></figure><p>L’avantage de ce fond d’écran est qu’il est déjà configuré pour pouvoir déclencher par un clic gauche,  un petit menu de secours qui n’est autre que le menu d’Openbox. Il est en espéranto et je l’ai réduit au strict minimum car je le conçois juste comme un canot de sauvetage en cas de naufrage de l’application. Je n’en parlerai donc pas davantage.</p>



<figure><img loading="lazy" data-attachment-id="1038" data-permalink="https://miamondo.org/pm/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/pm.png" data-orig-size="315,272" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="pm" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/pm.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/pm.png?w=315" src="https://miamondo96030527.files.wordpress.com/2020/12/pm.png?w=315" alt="" width="307" height="265" srcset="https://miamondo96030527.files.wordpress.com/2020/12/pm.png?w=307 307w, https://miamondo96030527.files.wordpress.com/2020/12/pm.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/pm.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/pm.png 315w" sizes="(max-width: 307px) 100vw, 307px"><figcaption>Canot de sauvetage</figcaption></figure><p>Au centre de ce fond d’écran, on trouve une sorte d’image style polaroid avec une légende. Il s’agit en fait d’un boutton Tkinter qui, lorsqu’on clique dessus, laisse la place au menu principal, constitué de douze catégories. Voici tout d’abord le bouton, illustré d’une image représentant le pont de Rakotz, en Allemagne. Il ressemble un peu à la porte des étoiles.</p>



<figure><img data-attachment-id="1040" data-permalink="https://miamondo.org/img_centr/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png" data-orig-size="1915,1079" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="img_centr" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png?w=768 768w, https://miamondo96030527.files.wordpress.com/2020/12/img_centr.png 1915w" sizes="(max-width: 1024px) 100vw, 1024px"><figcaption>Le Rakotzbrücke</figcaption></figure><p>Et voici le menu principal constitué de douze boutons tkinter. Il sera possible à très court terme, de rajouter ou de supprimer une catégorie. C’est en cours de programmation. L’effet ombré est obtenu grâce au compositeur <strong>xcompmgr</strong> qu’il faut installer au préalable. La commande <strong>xcompmgr -c -f &amp;</strong> doit être placée dans le fichier <strong>~/.config/openbox/autostart</strong>.</p>


<pre>
xcompmgr -c -f &amp;
</pre>


<p>Ce menu s’ouvre et se ferme également en cliquant sur le bouton situé tout en bas de l’écran à gauche. L’icône représente un ordinateur de bureau.</p>



<figure><img data-attachment-id="1043" data-permalink="https://miamondo.org/men_princ/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png" data-orig-size="1912,1077" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="men_princ" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png?w=768 768w, https://miamondo96030527.files.wordpress.com/2020/12/men_princ.png 1912w" sizes="(max-width: 1024px) 100vw, 1024px"></figure><div><figure><img data-attachment-id="1048" data-permalink="https://miamondo.org/men_princ2/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/men_princ2.png" data-orig-size="692,398" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="men_princ2" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/men_princ2.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/men_princ2.png?w=692" src="https://miamondo96030527.files.wordpress.com/2020/12/men_princ2.png?w=692" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/men_princ2.png 692w, https://miamondo96030527.files.wordpress.com/2020/12/men_princ2.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/men_princ2.png?w=300 300w" sizes="(max-width: 692px) 100vw, 692px"></figure></div>



<p>Cliquons sur le bouton le plus à gauche de la rangée du milieu. Il correspond à <em>Bureautique</em> en français. Toutes les catégories disparaissent et laissent la place aux applications de la catégorie sélectionnée.</p>



<figure><img data-attachment-id="1050" data-permalink="https://miamondo.org/submen/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/submen.png" data-orig-size="833,380" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="submen" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/submen.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/submen.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/submen.png?w=833" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/submen.png 833w, https://miamondo96030527.files.wordpress.com/2020/12/submen.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/submen.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/submen.png?w=768 768w" sizes="(max-width: 833px) 100vw, 833px"></figure><p>Ouvrons maintenant LibreOffice. Le sous-menu des applications disparait et laisse la place à l’image du Pont de Rakotz. Veuillez noter que grâce au module <strong><a rel="noreferrer noopener" href="https://docs.python.org/3/library/multiprocessing.html" target="_blank">multiprocessing</a></strong>, cette interface de bureau est multi-écrans. Comme, vous pouvez le voir sur la capture d’écran ci-dessous, Labortablo fonctionne au moins avec deux moniteurs.</p>



<figure><img data-attachment-id="1062" data-permalink="https://miamondo.org/double/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/double.png" data-orig-size="3840,1080" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="double" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=2048 2048w, https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/double.png?w=768 768w" sizes="(max-width: 1024px) 100vw, 1024px"></figure><p>C’est tout pour aujourd’hui. Demain ou après-demain, je vous montrerai comment j’ai procédé pour coder la barre des tâches. C’est sans aucun doute, la partie qui m’a donné le plus de fil à retordre. Je vous présenterai également mes idées d’amélioration:</p>



<ul><li>Sélection de l’image qui illustre le fond d’écran,</li><li>Ajouter/supprimer une catégorie/application (En cours de finalisation),</li><li>Changer les couleurs du thème,</li><li>etc.</li></ul><p>Petite vidéo de présentation en mode muet, compte tenu de mon phrasé hésitant et écorché. </p>



<figure><div>
<div><iframe width="760" height="428" src="https://www.youtube.com/embed/LV7RTE6Q2gM?version=3&amp;rel=1&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;fs=1&amp;hl=fr&amp;autohide=2&amp;wmode=transparent" allowfullscreen="true" sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"></iframe></div>
</div><figcaption>Labortablo</figcaption></figure>
<p><img src="media/848c13f4.27be241458674ac3359b0353fdc37c4a" data-original-source="http://cdn.libravatar.org/avatar/27be241458674ac3359b0353fdc37c4a" alt="Gravatar de miamondo" class="gravatar" /><br/><i>Original post of <a href="https://miamondo.org/2020/12/14/labortablo-une-interface-de-bureau-sur-une-base-archlinux-openbox-1ere-partie/" title="Visit the source">miamondo</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>miamondo : <a href="">Un environnement de bureau tout en Python (acte II : le fond d&rsquo;&eacute;cran)</a> (15/01/2019)</li><li>miamondo : <a href="">Cr&eacute;er une interface graphique en python pour le logiciel de capture d&rsquo;&eacute;cran scrot.</a> (28/04/2019)</li><li>Asher256 : <a href="">Script Linux: Trouver Facilement le Nom d&rsquo;un Fichier Ex&eacute;cutable</a> (08/01/2009)</li><li>miamondo : <a href="">Un environnement de bureau tout en Python (Acte I : le menu principal)</a> (08/01/2019)</li><li>miamondo : <a href="">Un environnement de bureau tout en Python(Acte III: la barre des t&acirc;ches)</a> (06/02/2019)</li></ul></div></p>


feed_id: https://blog.genma.fr/?Nextcloud-Le-Dasboard-01-N
title: genma : Nextcloud - Le Dasboard 01/N
uri: genma-Nextcloud-Le-Dasboard-01-N
url: https://blog.genma.fr/?Nextcloud-Le-Dasboard-01-N
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2931.jpg?1607679661" width="150" height="79"><div><p>Ce billet est le second d'une série de billet sur la fonctionnalité Dashboard de Nextcloud, apparue avec la version 20. <strong>Ces billet sont co-écrits par Genma &amp; Brume</strong>.3</p>
<p><strong>Introduction</strong></p>
<p>Dans ce billet, nous listons les "Widgets" disponibles au moment de la publication du présent billet.<br>
Le but est de pouvoir faire un état des lieux des widgets et avoir des points d'entrées sur des codes sources pour comprendre comment sont structurées les widgets afin de rédiger un tutoriel sur la création d'un widget (sujet des futurs billets de cette série).</p>
<p><strong>Analytics</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Bureautique &amp; texte, Flux
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Propose des graphiques de statistiques sur l'utilisation du serveur Nextcloud en temps réél.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/analytics" title="https://apps.nextcloud.com/apps/analytics">https://apps.nextcloud.com/apps/analytics</a></p>
<p><strong>Discourse integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Widget pour Dashboard qui affiche les dernières noticifations et converations de Discourse. <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_discourse" title="https://apps.nextcloud.com/apps/integration_discourse">https://apps.nextcloud.com/apps/integration_discourse</a></p>
<p><strong>GitHub integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Permet d'avoir les dernières notifications de GitHub sur son Dashboard.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_github" title="https://apps.nextcloud.com/apps/integration_github">https://apps.nextcloud.com/apps/integration_github</a></p>
<p><strong>GitLab integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Permet d'avoir les dernières notifications de GitLab sur son Dashboard.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_gitlab" title="https://apps.nextcloud.com/apps/integration_gitlab">https://apps.nextcloud.com/apps/integration_gitlab</a></p>
<p><strong>Jira integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Widget pour Dashboard qui affiche les dernières noticifations et converations de Jira. <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_jira" title="https://apps.nextcloud.com/apps/integration_jira">https://apps.nextcloud.com/apps/integration_jira</a></p>
<p><strong>Mastodon integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Widget pour Dashboard qui affiche les dernières noticifations et converations de Mastodon. <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_mastodon" title="https://apps.nextcloud.com/apps/integration_mastodon">https://apps.nextcloud.com/apps/integration_mastodon</a></p>
<p><strong>Moodle integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Widget pour Dashboard qui affiche les dernières noticifations et converations de Mastodon. <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_moodle" title="https://apps.nextcloud.com/apps/integration_moodle">https://apps.nextcloud.com/apps/integration_moodle</a></p>
<p><strong>OneDrive integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> L'intégration de Microsoft OneDrive vous permet d'importer automatiquement vos fichiers OneDrive dans Nextcloud.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_onedrive" title="https://apps.nextcloud.com/apps/integration_onedrive">https://apps.nextcloud.com/apps/integration_onedrive</a></p>
<p><strong>Reddit integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Widget pour Dashboard qui affiche les dernières noticifations de Reddit. <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_reddit" title="https://apps.nextcloud.com/apps/integration_reddit">https://apps.nextcloud.com/apps/integration_reddit</a></p>
<p><strong>SuiteCRM integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> L'intégration de SuiteCRM fournit un widget affichant vos notifications importantes, un moteur de recherche et des notifications d'activité dans SuiteCRM.
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_suitecrm" title="https://apps.nextcloud.com/apps/integration_suitecrm">https://apps.nextcloud.com/apps/integration_suitecrm</a></p>
<p><strong>Twitter integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Widget pour Dashboard qui affiche les dernières noticifations de Twitter. <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_twitter" title="https://apps.nextcloud.com/apps/integration_twitter">https://apps.nextcloud.com/apps/integration_twitter</a></p>
<p><strong>Zammad integration</strong></p>
<p><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Catégorie :</strong> Tableau de bord, Intégration
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Description :</strong> Widget pour Dashboard qui affiche les dernières noticifations de Zammad <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"><strong>Lien :</strong> <a href="https://apps.nextcloud.com/apps/integration_zammad" title="https://apps.nextcloud.com/apps/integration_zammad">https://apps.nextcloud.com/apps/integration_zammad</a></p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Nextcloud-Le-Dasboard-01-N" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://www.blog-libre.org/2020/12/19/windows-et-lutilisateur/
title: blog-libre : Windows et l’utilisateur
uri: blog-libre-Windows-et-l-utilisateur
url: https://www.blog-libre.org/2020/12/19/windows-et-lutilisateur/
content:
<p>Bientôt 14 ans que je travaille dans l’informatique. J’ai peu parlé de mon expérience de sysadmin Windows pourtant il s’agit de 10 ans de ma vie. Je n’ai jamais détesté Windows ni Microsoft, je ne suis pas un hater. J’aime l’informatique, Windows fait partie de son histoire.</p>
<h3>Aujourd’hui l’informatique</h3>
<p><a href="media/a9be7c36.windows_001.png" data-original-source="https://www.blog-libre.org/wp-content/uploads/2020/12/windows_001.png"><img loading="lazy" width="1024" height="768" src="media/a9be7c36.windows_001.png" data-original-source="https://www.blog-libre.org/wp-content/uploads/2020/12/windows_001.png" alt="" srcset="https://www.blog-libre.org/wp-content/uploads/2020/12/windows_001.png 1024w, https://www.blog-libre.org/wp-content/uploads/2020/12/windows_001-300x225.png 300w, https://www.blog-libre.org/wp-content/uploads/2020/12/windows_001-768x576.png 768w, https://www.blog-libre.org/wp-content/uploads/2020/12/windows_001-640x480.png 640w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px"></a></p>
<p><a href="https://lecrabeinfo.net/installer-windows-10-le-guide-complet.html" target="_blank" rel="noopener noreferrer">Source</a></p>
<p>Comment en installant un système d’exploitation bureautique en est-on arrivé à parler de publicité ?</p>
<p>Windows 10 est un très bon « produit »… et une honte absolue dans l’Histoire de l’informatique. À se demander dans « système d’exploitation » qui est exploité…</p>
<h3>Client ou utilisateur</h3>
<p>La durée du support pour les éditions Famille et Professionnel de Windows 10 est de <a href="https://lecrabeinfo.net/windows-10-dates-fin-de-support.html" rel="noopener noreferrer" target="_blank">18 mois</a>, le client est contraint de suivre le rythme. <a href="https://docs.microsoft.com/en-us/windows/deployment/update/waas-quick-start" rel="noopener noreferrer" target="_blank">Windows as a Service</a>.</p>
<p>Vendre un logiciel propriétaire est dépassé, le client peut l’utiliser X années sans repasser par la caisse (mon dieu !), sans envoyer constamment des données personnelles (sacrilège !), le réinstaller voire même abuser de sa licence en l’installant sur plus d’un poste (criminel !). Un service que le client renouvelle fréquemment et qui s’arrête brusquement dès qu’il cesse de payer ou de respecter les conditions d’utilisation, voilà l’avenir ! Le contrôle total de l’utilisation du « produit », aucune échappatoire, à tout moment les règles et conditions du service peuvent changer. L’accomplissement de la logique propriétaire, RIEN DE MIEUX que <strong>vendre un service</strong>. Qu’une entreprise veuille gagner de l’argent dans un monde capitaliste ok, que sa mécanique de vente aille jusqu’à éteindre tous droits et privilèges de l’utilisateur… Avec un service si tu n’es plus client… tu n’es plus utilisateur.</p>
<p>Microsoft Office n’est pas disponible pour Linux, un choix délibéré de Microsoft nullement une impossibilité technique. L’utilisateur n’est pas au centre de sa stratégie, le client oui. Un logiciel utile pour l’utilisateur mais non rentable n’a aucun avenir, voilà la différence fondamentale entre client et utilisateur.</p>
<p>On s’éloigne d’une logique répondant aux besoins de l’utilisateur pour entrer dans une stratégie où le client est une cible. Le terme utilisateur est devenu un simple outil de communication, bon pour la documentation et la publicité.</p>
<h3>Le choix de l’utilisateur : Windows ou Windows ?</h3>
<p>Je fais une nette distinction entre ce que propose (ou plutôt impose) Windows et ce que souhaiterait un utilisateur dans l’idéal. Dans l’environnement professionnel il est rare de pouvoir choisir son système d’exploitation et 9 fois sur 10 l’employé est sur Windows. Je doute que la publicité sur Windows soit très appréciée. Une majorité d’utilisateurs ne peut refuser l’utilisation de Microsoft Teams quand son entreprise l’utilise.</p>
<p>La contrainte est forte, les intérêts de l’utilisateur et de Windows divergent.</p>
<h3>Lutter contre, construire avec</h3>
<p>Windows 10 tu <a href="https://www.blog-libre.org/2016/02/21/faire/" rel="noopener noreferrer" target="_blank">luttes contre</a>. Sitôt installé il faut supprimer les bloatwares, se débarrasser de la télémétrie et des mouchards, désactiver la publicité.</p>
<p><a href="media/84631aef.windows_002.jpg" data-original-source="https://www.blog-libre.org/wp-content/uploads/2021/12/windows_002.jpg"><img loading="lazy" width="1024" height="817" src="media/84631aef.windows_002.jpg" data-original-source="https://www.blog-libre.org/wp-content/uploads/2021/12/windows_002.jpg" alt="" srcset="https://www.blog-libre.org/wp-content/uploads/2021/12/windows_002.jpg 1024w, https://www.blog-libre.org/wp-content/uploads/2021/12/windows_002-300x239.jpg 300w, https://www.blog-libre.org/wp-content/uploads/2021/12/windows_002-768x613.jpg 768w, https://www.blog-libre.org/wp-content/uploads/2021/12/windows_002-640x511.jpg 640w" sizes="(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px"></a></p>
<p><a href="https://korben.info/privatezilla-trackers-windows.html" target="_blank" rel="noopener noreferrer">Source</a></p>
<p>J’entends l’acceptation et la résignation de certains : « Avec Privatezilla le sujet est réglé en quelques clics », « On est déjà pisté de partout avec Android, un peu plus ou un peu moins, ça change quoi ? ». Se faire pister par Google ET par Microsoft n’est pas la même chose. Les informations collectées sur un smartphone ont peu de choses à voir avec celles collectées sur un pc, les usages sont différents et complémentaires comme vos données personnelles…</p>
<p>Dark patterns, anti-fonctionnalités : Il n’est plus possible de créer un compte local lors de l’installation de Windows 10, Microsoft impose désormais la création et l’utilisation d’un compte Microsoft pour ouvrir une session (<a href="https://lecrabeinfo.net/creer-compte-utilisateur-local-installation-windows-10.html" rel="noopener noreferrer" target="_blank">contournement</a>).</p>
<p>Debian (distribution que j’utilise) tu construis avec… c’est tout en fait. Pas d’installation silencieuse (les « mises à jour » qui remettent ce que tu avais supprimé), de fonctionnalités et outils imposés (Edge, Cortana, OneDrive), de contenus non désirés (il faut vivre une fois la pub sur Windows, magique). On appelle cela le respect de l’utilisateur, indirectement notre confiance grandit envers l’outil. </p>
<h3>Bugs</h3>
<p>Ma mère s’occupait de la compta de mon père du temps où ils n’étaient pas encore retraités. J’ai naturellement installé du Windows. On attend tous d’un système d’exploitation qu’il fonctionne et nous foute la paix.</p>
<p>Ma mère me dit qu’elle ne peut plus enregistrer aucun mot de passe sur Windows. De mon point de vue le pc est inutilisable, pas inutilisable car il bugue dans tous les sens, inutilisable pour un utilisateur. Rendez-vous compte :</p>
<ul><li>Vous lancez Outlook pour consulter vos mails, un invité vous demande de saisir le mot de passe pour chaque boîte mail. Lorsque dans X minutes, Outlook tentera de relever les mails, il vous redemandera les mots de passe</li>
<li>Vous ouvrez votre navigateur et allez sur un site où vous êtes enregistré, les identifiants sont bien présents dans le navigateur. Il vous demande votre mot de passe pour vous connecter au site</li>
<li>Votre Dropbox ou OneDrive vous demande de rentrer votre mot de passe</li>
<li>Etc. et dès que vous fermez une de ces applications puis vous l’ouvrez de nouveau, il vous redemande votre mot de passe</li>
</ul><p>Le pc serait passé par la fenêtre avec moi. Je lance une recherche en Anglais, un <a href="https://www.zdnet.com/article/windows-10-password-problems-microsoft-says-its-fixing-bad-password-amnesia-bug/" rel="noopener noreferrer" target="_blank">article</a> en parle, en creusant on trouve même un <a href="https://support.microsoft.com/en-us/office/outlook-and-other-apps-won-t-remember-password-after-windows-updates-1e5a8a80-7112-440a-a18c-be2e50047a75" rel="noopener noreferrer" target="_blank">article</a> chez Microsoft. Le souci a été remonté en avril, pas de correctif en 6 mois, le client a pudiquement le droit à un workaround (solution de contournement).</p>
<p>Tout système d’exploitation (et plus généralement logiciel) vient avec des bugs. L’important n’est pas vraiment le nombre de bugs, ce qu’on peut réellement juger est la rapidité et la qualité des correctifs. Je bosse depuis 3 ans sur Linux, j’ai utilisé Windows pendant plus de 15 ans dont quasiment 10 ans à travailler dessus. J’ai moins de soucis sur Linux, moins souvent/longtemps/grave.</p>
<p>Évidemment je tire cette constatation de mon expérience personnelle, il est probable que d’autres feront le constat inverse. Je vais toutefois rappeler un détail dans le point suivant.</p>
<h3>Smicard et milliardaire</h3>
<p>Globalement le Libre manque de moyens notamment d’argent. Certains gros projets reçoivent des dons, quelques développeurs rémunérés par leur entreprise bossent sur : Le noyau Linux, Debian, Ubuntu, Gnome… La majorité des autres projets crèvent la dalle, citons OpenBSD (<a href="https://linuxfr.org/news/openbsd-a-des-problemes-financiers" rel="noopener noreferrer" target="_blank">1</a>, <a href="https://www.silicon.fr/openbsd-a-besoin-dargent-34250.html" rel="noopener noreferrer" target="_blank">2</a>, <a href="https://linuxfr.org/users/spack/journaux/projets-open-source-des-vaches-a-lait" rel="noopener noreferrer" target="_blank">3</a>, <a href="https://en.wikipedia.org/wiki/OpenBSD#Funding" rel="noopener noreferrer" target="_blank">4</a>) qui développe <a href="https://www.openssh.com/" rel="noopener noreferrer" target="_blank">OpenSSH</a>.</p>
<p>Microsoft : Plus de <a href="https://www.zdnet.fr/actualites/microsoft-compte-150-000-employes-une-premiere-dans-son-histoire-39898409.htm" rel="noopener noreferrer" target="_blank">150 000 employés dont 40% affectés à l’ingénierie</a>, <a href="https://fr.wikipedia.org/wiki/Liste_des_entreprises_par_capitalisation_boursi%C3%A8re#2020" rel="noopener noreferrer" target="_blank">seconde capitalisation boursière ***mondiale*** de 1 592 milliards USD</a>, <a href="https://www.01net.com/actualites/la-pandemie-reussit-a-microsoft-ses-resultats-financiers-sont-tres-bons-1997488.html" rel="noopener noreferrer" target="_blank">37,2 milliards de dollars de chiffre d’affaires et 13,9 milliards de bénéfices nets au dernier trimestre</a>.</p>
<p>On compare un O.S Linux avec Windows à jeu égal ? Microsoft et Windows devrait atomiser Linux et les distributions Linux, le rapport de force est de 100 contre 1.</p>
<p>Pourtant on compare… ne vous y trompez pas, le simple fait de mettre Linux et Windows côte à côte démontre à quel point Windows se fout de l’utilisateur.</p>
<h3>Rien à vendre. Rien à gagner ?</h3>
<p>Ce qui sauve les distributions Linux est un grain de sable, une valeur ancrée au plus profond de l’Histoire du logiciel libre et de Linux : <strong>L’utilisateur au centre</strong>. Tout est fait autour de l’utilisateur, tout est fait pour lui.</p>
<p>Parfois malheureusement c’est insuffisant, les logiciels libres sont souvent moches, peu ergonomique, ces critiques sont justifiées. Nous manquons de moyens et de bras, des graphistes, designers, communicants.</p>
<p>Linux n’a rien à vendre mais comme utilisateurs nous avons tout à gagner à le soutenir.</p>
<p><img src="media/25c7216e.1ea6f31074367d57d77721240d30fda9" data-original-source="http://cdn.libravatar.org/avatar/1ea6f31074367d57d77721240d30fda9" alt="Gravatar de blog-libre" class="gravatar" /><br/><i>Original post of <a href="https://www.blog-libre.org/2020/12/19/windows-et-lutilisateur/" title="Visit the source">blog-libre</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>blog-libre : <a href="">Cheminement d&#039;un power user : De Windows &amp;agrave; GNU/Linux</a> (18/11/2017)</li><li>Asher256 : <a href="">Ne Gueulez pas Contre Linux quand votre Mat&eacute;riel n&rsquo;est pas Compatible</a> (06/01/2009)</li><li>Asher256 : <a href="">Fltk, cr&eacute;ez ais&eacute;ment vos interfaces graphiques multi-plateformes en C++</a> (29/07/2008)</li><li>Asher256 : <a href="">Le Podcast Factory marche sous GNU/Linux</a> (14/02/2008)</li><li>Asher256 : <a href="">Miro : la t&eacute;l&eacute;vision gratuite par Internet</a> (15/01/2008)</li></ul></div></p>


uri: 2020-12-20-miamondo-Labortablo-une-interface-de-bureau-codée-en-Python-sur-un
feed_id:
https://miamondo.org/2020/12/20/labortablo-une-interface-de-bureau-codee-en-python-sur-une-base-archlinux-openbox-2eme-partie/

title:
miamondo : Labortablo, une interface de bureau codée en Python sur une base Archlinux/Openbox (2ème partie)

url:
https://miamondo.org/2020/12/20/labortablo-une-interface-de-bureau-codee-en-python-sur-une-base-archlinux-openbox-2eme-partie/

content:
<p><strong><span>La barre de tâches</span></strong></p>



<p><strong>Sommaire</strong> </p>



<p>1. <strong>La boucle</strong> </p>



<p>2. <strong>Récupérer et convertir les icônes avec xprop</strong> </p>



<p>3. <strong>Iconifier et déiconifier les fenêtres</strong></p>



<hr><p><strong>Voici le deuxième article sur mon <a href="https://miamondo.org/2020/12/14/labortablo-une-interface-de-bureau-sur-une-base-archlinux-openbox-1ere-partie/">interface de bureau</a> moulé à la louche. Il traite de la barre des tâches. Le processus fonctionne de manière tout à fait satisfaisante mais il m’a vraiment donné du fil à retordre. Cette zone qui se trouve en bas de l’écran, affiche: </strong></p>



<span></span>



<ul><li>Le bouton d’ouverture ou de fermeture du menu principal,</li><li>quatre boutons qui permettent d’éteindre, de redémarrer, de mettre en veille ou de se déconnecter,</li><li>et bien sûr, autant de boutons qu’il y a de fenêtres ouvertes. </li></ul><p>Le rôle de ces derniers est triple: iconifier, déiconifier ou bien fermer la fenêtre qui lui est associée. Les boutons sont des valeurs stockées dans un dictionnaire. Les clés de ce dernier sont les identifiants obtenus avec la commande <strong>wmctrl -l</strong>.</p>



<p>Dans la capture d’écran ci-dessous, on peut constater que trois applications sont ouvertes, mon agenda, chromium et Libre-Office Calc.</p>



<figure><img data-attachment-id="1081" data-permalink="https://miamondo.org/taskbar-1/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png" data-orig-size="849,26" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="taskbar-1" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png?w=849" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png 849w, https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/taskbar-1.png?w=768 768w" sizes="(max-width: 849px) 100vw, 849px"></figure><p></p>



<ol><li><strong>La boucle</strong></li></ol><p>Toute la difficulté de cette barre de tâches est qu’il faut créer une boucle qui récupère les informations sur chaque fenêtre d’application ouverte et surtout qui affiche l’icône qui lui est associée.  </p>



<figure><img data-attachment-id="1083" data-permalink="https://miamondo.org/til/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/til.png" data-orig-size="892,304" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="til" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/til.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/til.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/til.png?w=892" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/til.png 892w, https://miamondo96030527.files.wordpress.com/2020/12/til.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/til.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/til.png?w=768 768w" sizes="(max-width: 892px) 100vw, 892px"></figure><p>Voici donc le déroulé des opérations:</p>



<p>La boucle commence par exécuter <strong>wmctrl -l</strong> (voir capture d’écran ci-dessus) et stocke les informations obtenues dans une variable que nous allons baptiser <strong>old_running_applications</strong>. <span><strong>Cette variable doit être hors de la boucl</strong></span><strong><span>e.</span></strong></p>



<p>La boucle exécute une nouvelle fois <strong>wmctrl -l</strong> et stocke les informations dans une variable baptisée <strong>new_running_applications</strong>. <strong><span>Cette variable se trouve dans la boucle</span></strong>.</p>



<p>Le contenu des deux variables est comparé (en excluant les lignes contenant <strong>N/A</strong>). Le programme détermine quelles sont les fenêtres ouvertes, il splitte chaque ligne, c’est-à dire qu’il les transforme en liste, pour en extraire le numéro d’identification (par exemple <strong>0x008000007</strong>), ainsi que le titre de la fenêtre (par exemple <strong>Agenda</strong>). Le titre de la fenêtre va s’afficher sur le bouton qui lui correspond. </p>



<p>Si une nouvelle fenêtre a été ouverte, la boucle demande au script <strong><a rel="noreferrer noopener" href="https://gitlab.com/miamondo/labortablo/-/blob/master/Scripts/taskbar.py" target="_blank">taskbar.py</a></strong> de créer le bouton correspondant. En revanche, si une fenêtre a été fermée, elle lui demande de détruire le bouton corespondant. Bien sûr, le script <strong>taskbar.py</strong> ne s’amuse pas à détruire et à recréer une nouvelle barre à chaque changement. Il ne rajoute ou ne détruit que les boutons impactés par une modification. Puis, en fin de boucle, après avoir effectué les modifications et actualisé la barre des tâches, le script met à jour le contenu de la variable <strong>old_running_applications</strong>, qui est hors de la boucle.</p>



<p><strong><strong>old_running_applications</strong> = <strong>new_running_applications</strong></strong></p>



<p>2. <strong>Récupérer les icônes avec xprop, puis les convertir au format *.png pour les afficher à la volée</strong></p>



<p>Il s’agit sans aucun doute de la partie la plus délicate. Je dois vous avouer que le titre de l’article n’est pas correct. Je prétends que l’interface de bureau est codée tout en Python, mais il y a tout de même un fichier <strong>*.sh</strong>. J’ai déniché ce script <strong><a rel="noreferrer noopener" href="https://unix.stackexchange.com/questions/48860/how-to-dump-the-icon-of-a-running-x-program" target="_blank">à cette adresse</a></strong>. </p>


<pre>
 #!/bin/bash

path=$1
id=$2
xprop -id "$id" -notype 32c _NET_WM_ICON |
    perl -0777 -pe '@_=/\\d+/g;
    printf "P7\\nWIDTH %d\\nHEIGHT %d\\nDEPTH 4\\nMAXVAL 255\\nTUPLTYPE RGB_ALPHA\\nENDHDR\\n", splice@_,0,2;
    $_=pack "N*", @_;
    s/(.)(...)/$2$1/gs' > "$path"/"$id".pam

convert "$path"/"$id".pam "$path"/"$id".png
</pre>


<p>Il est manifestement l’oeuvre d’un dénommé Stéphane Chazelas. Bien sûr, je l’ai adapté à ma sauce. Il prend deux paramètres en arguments (le répertoire courant et le numéro d’identification). La mission de ce script est d’exécuter <strong>xprop</strong> et de générer des fichiers portant l’extension <strong>.pam</strong>. Ceux-ci sont immédiatement convertis en fichiers <strong>.png</strong> pour être affichés à la volée sur les boutons respectifs. Si l’identifiant de la fenêtre est <strong>0x00800007</strong>, alors l’icône qui lui est associé, s’appelle <strong>0x00800007.png.</strong></p>



<p>Ça marche presque à tous les coups. Seule quelques applications résistent et refusent de convertir le fichier <strong>*.pam</strong>. C’est le cas de <strong>Shotwell</strong> par exemple. Lorsque cela se produit, elles sont capturées dans une exception. </p>



<p>Le processus <strong>xprop</strong> prend un peu de temps, si bien qu’il était possible que le bouton affiche seulement le texte et pas l’icône. Afin de remédier à ce problème et être <em>ceinture-bretelles</em>, j’ai modifié le code pour que le processus  soit de nouveau lancé à chaque début de boucle. Les boutons qui n’ont que le texte, tentent de récupérer leur icône. Si vraiment, l’icône n’a pas éte convertie au format <strong>png</strong>, alors le bouton s’affiche quand-même. Tout ce processus est invisible pour l’utilisateur. Il n’y a aucun retard. C’est instantané.</p>



<p>Les fichiers générés par <strong>xprop</strong> et portant l’extension <strong>*.pam</strong>,<strong> </strong>ainsi que les fichiers au format <strong>*.png</strong> sont conservés provisoirement dans le répertoire courant. Ils sont détruits à l’extinction, au redémarrage ou à la déconnexion, d’une part pour ne pas encombrer le répertoire, et d’autre part pour être certain qu’à la prochaine session, ils ne seront pas réattribués à une mauvaise application. Le cas s’est déjà produit. Le bouton de thunar affichait l’icône de Chromium!</p>



<p>3. <strong>Iconifier et déiconifier les fenêtres en utilisant un simple clic de souris</strong></p>



<figure><img data-attachment-id="1111" data-permalink="https://miamondo.org/louis-xvi/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png" data-orig-size="1916,1078" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="louis-xvi" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png?w=760" src="https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png?w=768 768w, https://miamondo96030527.files.wordpress.com/2020/12/louis-xvi.png 1916w" sizes="(max-width: 1024px) 100vw, 1024px"></figure><p>Cette opération est bien moins évidente qu’il n’y parait. Il ne s’agit pas seulement d’alterner la commande d’un bouton pour qu’il réduise sa fenêtre puis qu’il l’agrandisse. En se contentant de faire ça, une fenêtre ouverte mais totalement cachée va d’abord se réduire puis s’agrandir au-dessus des autres, ce qui va donner l’illusion d’un double-clic un peu énervant.</p>



<p>Il faut donc faire en sorte de créer une condition pour que le bouton qui iconifie une fenêtre puisse aussi être celui qui va la passer au premier plan si cette dernière n’a pas le focus. Pour ce qui est de la déiconification, c’est beaucoup plus simple puisqu’on demande juste au bouton d’agrandir et de passer sa fenêtre au premier plan.</p>



<p>C’est la commande <strong>xdotool getwindowfocus getwindowname</strong> qui se charge de déterminer quelle fenêtre a le focus. Ensuite, selon le cas, c’est <strong>xdotool windowminimize</strong> qui va iconifier la fenêtre ou bien <strong>wmctrl -i -a</strong> qui va la placer au-dessus de toutes les autres, et par conséquent la rendre visible. </p>


<pre>
def iconify_window(self, ID, tb):
    """iconifies the window"""

    self.ID = ID
    self.taskbar_button = tb

    process = subprocess.Popen(['xdotool', 'getwindowfocus', 'getwindowname'], text=True, stdout=subprocess.PIPE)
    for line in process.stdout.readlines():
        if line.strip()==self.taskbar_button['text'].strip():
            subprocess.Popen(['xdotool', 'windowminimize', self.ID], text=True, stdout=subprocess.PIPE)
            self.taskbar_button.bind('<Button-1>', lambda event, ID=self.ID,
                                                  tb=self.taskbar_button: self.deiconify_window(ID, tb))
        else:
            subprocess.Popen(['wmctrl', '-i', '-a', self.ID], text=True, stdout=subprocess.PIPE)
            self.taskbar_button.bind('<Button-1>', lambda event, ID=self.ID,
                                                  tb=self.taskbar_button: self.iconify_window(ID, tb))
</pre>


<p><strong>Conclusion</strong></p>



<p>Voilà pour ce qui concerne la barre des tâches. Elle fonctionne très bien mais il reste tout de même quelques points d’amélioration. </p>



<p>Ajouter de la transparence et opacifier la barre des tâches au survol de la souris. Malgré la méthode <strong>root.attributes(‘-alpha’, 0.5)</strong>, je n’y parviens pas. </p>



<p>Je souhaiterais également que mes deux écrans affichent une barre de tâches qui corresponde aux fenêtres ouvertes sur chacun d’entre eux. Pour l’instant, les deux barres sont des clônes. Mais j’ai peut-être déjà la solution… </p>



<p>Et pour celles et ceux que ça intéresse, le code est ici:</p>



<p><a href="https://gitlab.com/miamondo/labortablo" target="_blank" rel="noreferrer noopener">https://gitlab.com/miamondo/labortablo</a></p>
<p><img src="media/848c13f4.27be241458674ac3359b0353fdc37c4a" data-original-source="http://cdn.libravatar.org/avatar/27be241458674ac3359b0353fdc37c4a" alt="Gravatar de miamondo" class="gravatar" /><br/><i>Original post of <a href="https://miamondo.org/2020/12/20/labortablo-une-interface-de-bureau-codee-en-python-sur-une-base-archlinux-openbox-2eme-partie/" title="Visit the source">miamondo</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>miamondo : <a href="">Labortablo, une interface de bureau cod&eacute;e en Python sur une base Archlinux/Openbox (1&egrave;re partie)</a> (14/12/2020)</li><li>miamondo : <a href="">Un environnement de bureau tout en Python (Acte I : le menu principal)</a> (08/01/2019)</li><li>miamondo : <a href="">Un environnement de bureau tout en Python (acte II : le fond d&rsquo;&eacute;cran)</a> (15/01/2019)</li><li>miamondo : <a href="">Cr&eacute;er une interface graphique en python pour le logiciel de capture d&rsquo;&eacute;cran scrot.</a> (28/04/2019)</li><li>Asher256 : <a href="">Script Linux: Trouver Facilement le Nom d&rsquo;un Fichier Ex&eacute;cutable</a> (08/01/2009)</li></ul></div></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #51
uri: 2020-12-21-Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-51
feed_id:
https://blog.journalduhacker.net/index.php?article302/liens-interessants-journal-du-hacker-semaine-51-2020

url:
https://blog.journalduhacker.net/index.php?article302/liens-interessants-journal-du-hacker-semaine-51-2020

content:
<p>Pour la 51ème semaine de l'année 2020, voici <strong>10 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/nrcc3y/fiche_de_secours_m_mo_golang">Fiche de secours - mémo Golang</a></li>
<li><a href="https://www.journalduhacker.net/s/hswey0/quatre_ann_es_de_wallabag_it">Quatre années de wallabag.it</a></li>
<li><a href="https://www.journalduhacker.net/s/kh4rvp/r_flexion_sur_centos_8_que_vais_je_faire_en">Réflexion sur CentOS 8 : Que vais-je faire en entreprise ?</a></li>
<li><a href="https://www.journalduhacker.net/s/c51clr/pr_sentation_du_cms_pluxml">Présentation du CMS PluXml</a></li>
<li><a href="https://www.journalduhacker.net/s/ski027/est_il_encore_utile_de_poss_der_un_site_web">Est-il encore utile de posséder un site web en 2021 ?</a></li>
<li><a href="https://www.journalduhacker.net/s/mii7lh/french_tech_interview_demile_vauge_cr">French Tech - Interview d'Emile Vauge, créateur de Traefik</a></li>
<li><a href="https://www.journalduhacker.net/s/azcilw/la_distribution_mageia_8_en_b_ta_2">La distribution Mageia 8 en bêta 2</a></li>
<li><a href="https://www.journalduhacker.net/s/fj2bme/diter_de_mani_re_transparente_des">Éditer de manière transparente des fichiers GPG avec Vim</a></li>
<li><a href="https://www.journalduhacker.net/s/tppwj8/petit_manuel_d_auto_d_fense_de_l_emploi">Petit manuel d’auto-défense de l’emploi</a></li>
<li><a href="https://www.journalduhacker.net/s/22fnyy/duckstation_un_mulateur_playstation">DuckStation, un émulateur PlayStation libre époustouflant</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://twitter.com/journalduhacker">Le compte Twitter du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article302/liens-interessants-journal-du-hacker-semaine-51-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Carl Chenet : <a href="">Liens int&eacute;ressants Journal du hacker semaine #51</a> (21/12/2015)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #51</a> (26/12/2016)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #51</a> (25/12/2017)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #51</a> (24/12/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #51</a> (23/12/2019)</li></ul></div></p>


feed_id: https://www.deblan.io/post/594/bilan-tech-de-l-annee-2020
title: Simon Vieille : Bilan tech de l'année 2020
uri: Simon-Vieille-Bilan-tech-de-l-année-2020
url: https://www.deblan.io/post/594/bilan-tech-de-l-annee-2020
content:
<p>Cette année très particulière m'a quand même permis de consacrer plus de 
temps pour le logiciel libre que l'an passé.</p>

<p>Mes efforts se sont naturellement dirigés vers les outils que j'utilise et c'est 
Nextcloud et son écosystème sur lesquels je me suis concentré.</p>

<p>Mon plus gros projet de 2020 est <a href="https://apps.nextcloud.com/apps/side_menu">Custom menu</a>, une application pour Nextcloud qui 
permet de modifier le menu par défaut en proposant d'autres affichages. Je suis 
très content du résultat et beaucoup d'administrateurs ont décidé de l'installer 
sur leur instance. En effet, toutes versions confondues, <a href="https://apps.nextcloud.com/apps/side_menu">Custom menu</a> a été 
téléchargé plus de 102 mille fois et les dernières versions sont installées sur 
environ 9000 instances.</p>

<p>J'ai réalisé du code pour faire évoluer l'application <a href="https://apps.nextcloud.com/apps/forms">Forms</a> on y ajoutant de 
nouveaux types de champ. Cela n'a pas du tout été évident d'échanger avec 
l'équipe de développement mais j'espère voir arriver ces évolutions dans une 
prochaine version.</p>

<p>Ensuite, j'ai traduis <a href="https://apps.nextcloud.com/apps/analytics">Analytics</a> en français même si je ne suis pas satisfait. 
Je vais faire de nouvelles traductions l'année prochaine ! Cette application
permet de mettre en graphique des données stockées sur Nextcloud ou accessibles
depuis une API. C'est encore relativement basique mais c'est tout de même très pratique.</p>

<p>Même si le développement n'est pas très actif, j'utilise l'application <a href="https://apps.nextcloud.com/apps/printer">Printer</a> 
et j'ai proposé du code pour gérer les permissions et réduire les risques 
d'injection de code.</p>

<p>Dans un contexte très différent de Nextcloud, j'ai apporté un correctif au 
projet <a href="https://pdnsmanager.org/">PDNS Manager</a>, une interface web qui permet de gérer les enregistrements 
d'un serveur <a href="https://www.powerdns.com/">Powerdns</a>.</p>

<p>J'ai récemment publié <a href="https://www.deblan.io/post/591/mail-rss-transformer-des-mails-en-flux-rss">Mail RSS</a>, une application pour transformer des 
emails en flux RSS. Enfin, un peu plus tôt cette année, j'ai mis en ligne les sources du 
site web qui permet de <a href="https://www.deblan.io/post/580/monitoring-d-un-terrarium">monitorer le terrarium</a> de la maison.</p>

<p>Je crois avoir fait le tour de mon activité en espérant poursuivre en 2021 !</p>
<p><img src="media/f6ec4698.a99922fd1c4e000d5911b8c88280938e" data-original-source="http://cdn.libravatar.org/avatar/a99922fd1c4e000d5911b8c88280938e" alt="Gravatar de Simon Vieille" class="gravatar" /><br/><i>Original post of <a href="https://www.deblan.io/post/594/bilan-tech-de-l-annee-2020" title="Visit the source">Simon Vieille</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Simon Vieille : <a href="">Bilan de l&rsquo;ann&eacute;e 2019</a> (09/01/2020)</li></ul></div></p>


feed_id: https://blog.genma.fr/?Reflexion-une-instance-Peertube-pour-mes-conferences
title: genma : Réflexion - une instance Peertube pour mes conférences
uri: genma-Réflexion-une-instance-Peertube-pour-mes-conférences
url: https://blog.genma.fr/?Reflexion-une-instance-Peertube-pour-mes-conferences
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2932.jpg?1608569810" width="150" height="86"><div><p><strong>Peertube ?</strong></p>
<p><i>PeerTube est un logiciel libre, sous licence AGPLv3.0, d'hébergement de vidéo décentralisé grâce à la diffusion en pair à pair, créé en 2015 et soutenu par Framasoft.</i></p>
<p><i>L'ambition de PeerTube, c'est d'être une alternative libre et décentralisée aux services de diffusion de vidéos. Le but n'est pas de remplacer, mais de proposer quelque chose d'autre, avec des valeurs différentes, en parallèle de ce qui existe déjà.</i></p>
<p>Pour plus de détail, voir <a href="https://joinpeertube.org/" title="Join Peertube.org">https://joinpeertube.org/</a></p>
<p><strong>Ma réflexion personnelle</strong></p>
<p>Je fais de l'autohébergement depuis quelques années, je suis pour un Internet décentralisé. Maintenant que j'ai la fibre et donc une bien meilleure bande passante en upload (dans le sens de chez moi vers Internet, la connexion est passée de 1 Mb/s théorique (plutôt 0,8 Mb/s en pratique à 700 Mbit/s avec la fibre, soit 700 fois plus rapide).</p>
<p>Cela fait quelques années que je donne des conférences, certaines d'entre elles ont été filmées et ont été mises en lignes. J'ai donc commencé à récupérer les quelques vidéos qui sont accessibles (sur Youtube, Peertube ou en téléchargement depuis les sites des événements), avant tout pour en conserver une trace (elles peuvent être supprimées à tout moment).</p>
<p>Et je me pose donc la question suivante : est-ce que ce serait intéressant de tout regrouper sur une instance Peertube que je gérerai ? Ma question est plus : si je mets des vidéo de moi sur une instance dédiée, cela ne fait-il pas un peu trop "mise en avant de soi" ?</p>
<p>Mon but est plus de garder ça pour mémoire, de mettre à disposition des vidéos <i>qui ne seront pas vues</i></p>
<p>J'ai déjà fait quelques tests et la machine que j'utilise permet de faire l'encodage nécessaire à la mise en place des vidéos sur une instance peertube. Il faut que je remette à jour le Peertube, que je fasse les choses proprement mais surtout que je réfléchisse encore sur la pertinence de cette instance.</p>
<p>Enfin à noter que l'année 2020 aura été particulière : les quelques événements où j'ai mes habitudes et qui rythme l'année ont été annulés les uns après les autres et je n'ai donc pas donné de conférences.</p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Reflexion-une-instance-Peertube-pour-mes-conferences" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Framablog : <a href="">PeerTube 1.0&amp;nbsp;: la plateforme de vid&amp;eacute;os libre et f&amp;eacute;d&amp;eacute;r&amp;eacute;e</a> (15/10/2018)</li><li>Framablog : <a href="">PeerTube 1.0&amp;nbsp;: the free/libre and federated video platform</a> (15/10/2018)</li><li>Framablog : <a href="">Our plans for PeerTube v3&amp;nbsp;: progressive fundraising, live streaming coming next fall</a> (26/05/2020)</li><li>Framablog : <a href="">Nos plans pour PeerTube v3&amp;nbsp;: collecte perl&amp;eacute;e, du live pour cet automne</a> (26/05/2020)</li><li>Framablog : <a href="">Sepia Search&amp;nbsp;: our search engine to promote PeerTube</a> (22/09/2020)</li></ul></div></p>


feed_id: https://libre-ouvert.tuxfamily.org/index.php?article251/mon-bilan-informatique-de-lannee-2020
title: antistress : Mon bilan informatique de l'année 2020
uri: antistress-Mon-bilan-informatique-de-l-année-2020
url: https://libre-ouvert.tuxfamily.org/index.php?article251/mon-bilan-informatique-de-lannee-2020
content:
<p><a href="https://www.flickr.com/photos/franciscoferreira/5459981428/"><img src="media/739beaac.noel-a-brasileira--chico-ferreira--cc-by-2.0_400x300.jpg" data-original-source="https://libre-ouvert.tuxfamily.org/data/images/noel-a-brasileira--chico-ferreira--cc-by-2.0_400x300.jpg" alt="Père Noël à cheval en short devant la mer par beau temps" height="300" width="400"></a></p>

<p>Ha, « informatique », un mot qui fleure bon le siècle dernier. J'ai hésité avec numérique, avant de décider d'assumer pleinement le premier. En tout cas, on ne parlera pas de Covid dans ce billet (mince, trop tard).</p><h3>Mon blogue</h3>

<p>Il y a eu pas mal de nouveautés concernant mon blogue !</p>

<p>Tout d'abord je l'ai déménagé de Toile Libre (qui semble bloqué sur PHP 5.5) vers <a href="https://www.tuxfamily.org/">TuxFamily</a>. Grâce à la simplicité et à la flexibilité du moteur de blogue <a href="https://libre-ouvert.tuxfamily.org/?article9/pluxml-moteur-blogue-poids-plume">PluXml</a>, il m'a suffit de déplacer les fichiers composant mon blogue d'un espace à l'autre (à condition de faire attention à bien employer des <abbr lang="en" title="Uniform Resource Locator">URL</abbr> relatives pour les éventuels liens internes au blogue).</p>

<p>Ensuite j'ai changé le sous-titre du blogue. Pour rappel, le sous-titre du blogue a longtemps été : <strong><q>bloc-notes d'un affranchi</q></strong>, en référence à l'époque où je n'utilisais pas encore de logiciels libres.<br>
Je l'ai changé :<br>
– une première fois, le 4 février 2014, pour <strong><q>Passer à GNU/Linux n'est pas une fin : c'est un commencement</q></strong> en m'inspirant de <a href="https://libre-ouvert.tuxfamily.org/index.php?article183/le-penible-chemin-de-la-liberte#c1391527323-1">la formule d'un lecteur (otyugh)</a>,<br>
– puis, le 1er novembre dernier, en <strong><q>logiciels libres, formats ouverts, libertés numériques &amp; éducation</q></strong> pour être cohérent avec le fait que ce dernier thème fait désormais partie du blogue.</p>

<p>Car, et c'est sans doute le plus gros changement, cette année j'ai élargi la thématique du blogue pour publier également en lien avec mon métier de <abbr lang="fr" title="Conseiller principal d'éducation">CPE</abbr>. Notez que, pour ne rien vous imposer, j'ai tiré <a href="https://libre-ouvert.tuxfamily.org/index.php?static13/rss">des flux RSS distincts</a>.</p>

<p>Enfin, ceci expliquant cela, cela faisait longtemps que je n'avais pas publié autant ici. J'en suis à 18 billets cette année et il faut remonter à 2014 pour retrouver pareil nombre (j'ai bien conscience que ce nombre peut paraître faible : tout est relatif). Mieux, 13 billets ont été publiés au cours des deux derniers mois. C'est, en ce qui me concerne, une fréquence rarement (jamais ?) atteinte. Les nouvelles thématiques semble m'inspirer puisque, sur les 13 derniers billets, seulement 3 évoquent l'informatique.</p>

<p>L'incroyable sprint final :<br><img src="media/1682e806.diagramme2020_605x340.png" data-original-source="https://libre-ouvert.tuxfamily.org/%0Adata/images/diagramme2020_605x340.png" alt="Diagramme du nombre de publications par mois" height="340" width="605"></p>

<h3>Mon informatique</h3>

<p>J'ai quasiment fini la « flatpakisation » et la « waylandisation » de mon système. <a href="https://libre-ouvert.tuxfamily.org/?article205/au-revoir-debian-bonjour-debian-avec-flatpak-mise-jour">L'essentiel de mes applications sont des flatpak</a> (hors celles au cœur de GNOME dont je laisse la gestion à ma distrib', et à l'exception notable de Firefox : <a href="https://libre-ouvert.tuxfamily.org/index.php?article230/ma-configuration-de-firefox-en-cette-fin-2020">à cause de deux blogues</a>) et tournent nativement sous Wayland, ce qui m'a poussé à activer <a href="https://linuxfr.org/news/gnome-3-34#toc-exp%C3%A9rimental-gnome-coupe-le-cordon-avecx11">la fonctionnalité expérimentale de GNOME <em xml:lang="en" lang="en">XWayland On-Demand</em></a>.</p>

<p><a href="https://libre-ouvert.tuxfamily.org/index.php?categorie11/hardware">Question hardware</a>, mon PC fixe me convient tel qu'il est depuis un moment. Son cerveau a été changé il y a huit ans tout comme l'écran. Ne jouant pas, j'avais misé sur la sobriété pour tous les éléments, sauf la mémoire vive que j'avais prévue large par expérience (j'ai toujours assemblé mes PC depuis mon premier : un Pentium MMX 166MHz). Je sais que je devrais changer la pâte thermique de mon <abbr lang="en" title="central processing unit">CPU</abbr> mais la motivation me manque encore…</p>

<p>Côté <em xml:lang="en" lang="en">smartphone</em>, un sujet que je n'ai encore jamais abordé sur le blogue (j'utilise surtout les fonctions SMS, appareil photo et voix – dans cet ordre), j'en suis à mon quatrième. Après un ZTE OpenC sous Firefox OS, les suivants ont tous tourné sous LineageOS : Sony Xperia Z5 Compact, Samsung Galaxy A3 2017 et le petit dernier que je viens de recevoir, un <a href="https://wiki.lineageos.org/devices/klte">Samsung Galaxy S5</a> (oui, oui, un modèle de 2014). Mes critères sont en général la qualité de l'appareil photo, l'autonomie, une taille raisonnable, et bien sûr la prise en charge de LineageOS. C'est une chute de trop (malgré leur étui de protection) qui m'a poussé à remplacer successivement les Xperia Z5 Compact (plus de mise au point de l'appareil photo) et Galaxy A3 2017 (hémorragie de cristaux liquides inondant l'écran). Pour des objets du quotidien, ces appareils sont très peu solides.</p>

<h3>Mes projets</h3>

<p>Je travaille sur un projet ambitieux, libre et gratuit, que j'aimerais bien voir se finaliser en début d'année prochaine. Des obstacles techniques et humains restent à franchir, nous verrons bien. J'en parlerai bien évidemment prioritairement ici si le projet aboutit.</p>

<h3>Hommage à bloguelinux.ca</h3>

<p>Je termine avec une pensée pour mes podcasts informatiques préférés qui s'arrêtent les uns après les autres : après <a href="https://libre-ouvert.tuxfamily.org/index.php?article202/bon-vent-parole-de-tux"><em>Parole de Tux</em> en 2014</a>, c'est au tour de <a href="http://www.bloguelinux.ca/"><em>bloguelinux</em></a> de tirer sa révérence. Deux podcasts qui avaient pour points communs Linux, l'humour et la bienveillance.</p>

<p>À Eric, Patrick et Sandrine :<br><a href="https://www.flickr.com/photos/zigazou76/5970648519/in/photostream/"><img src="media/57ef10a7.merci---frederic-bisson--cc-by-2.0_704x300.jpg" data-original-source="https://libre-ouvert.tuxfamily.org/data/images/merci---frederic-bisson--cc-by-2.0_704x300.jpg" alt="Merci écrit sur le sol" height="300" width="704"></a></p>
<p><img src="media/4839f6a5.470c5e17640a289d1e99b26d2dec9f54" data-original-source="http://cdn.libravatar.org/avatar/470c5e17640a289d1e99b26d2dec9f54" alt="Gravatar de antistress" class="gravatar" /><br/><i>Original post of <a href="https://libre-ouvert.tuxfamily.org/index.php?article251/mon-bilan-informatique-de-lannee-2020" title="Visit the source">antistress</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Olivier Faurax : <a href="">Mon bilan de 2009</a> (07/01/2010)</li></ul></div></p>


feed_id: https://francois.aichelbaum.com/2020/12/23/json-mongodb-rsyslog-are-on-a-boat
title: Francois Aichelbaum : JSON, MongoDB and rsyslog are on a boat
uri: Francois-Aichelbaum-JSON-MongoDB-and-rsyslog-are-on-a-boat
url: https://francois.aichelbaum.com/2020/12/23/json-mongodb-rsyslog-are-on-a-boat
content:
<aside><nav><header><h4><i></i> JSON, MongoDB and rsyslog are on a boat</h4></header><ul><li><a href="https://francois.aichelbaum.com/#json-is-standard">JSON is standard</a></li>
  <li><a href="https://francois.aichelbaum.com/#nginx-knows-about-cee">Nginx knows about @cee</a></li>
  <li><a href="https://francois.aichelbaum.com/#rsyslog-is-great-its-documentation-is-not">Rsyslog is great. Its documentation is not.</a></li>
  <li><a href="https://francois.aichelbaum.com/#thats-not-all-folks">That’s not all folks!</a></li>
  <li><a href="https://francois.aichelbaum.com/#at-the-end">At the end</a></li>
</ul></nav></aside><p>When dealing with log management, obvious solutions emerge earlier, often before you even discussed the purpose of the log management. We can discuss about <a href="https://www.elastic.co/fr/what-is/elk-stack">ELK</a>, <a href="https://www.graylog.org/">Graylog</a>, <a href="https://www.splunk.com/">Splunk</a>, … Those are great tools but they may not fit will all your needs. Lately, I had to work for one of my customer on enforcing log management for billing purposed. Rsyslog was already set to collect and centralize all the logs (and manage their backups). MongoDB seemed as a perfect tips for storing JSON extract of the logs to generate the proper stats.</p>

<p><img alt="Invoice Management - DronaHQ" src="media/88007b0b.invoice-management.jpg" data-original-source="https://francois.aichelbaum.com/images/2020/12/invoice-management.jpg" title="Invoice Management - DronaHQ" srcset="/assets/resized/480/invoice-management.jpg 480w,/assets/resized/800/invoice-management.jpg 800w, /images/2020/12/invoice-management.jpg 1280w"><br><em>Invoice Management - DronaHQ</em></p>

<h2>JSON is standard</h2>

<p>From <a href="https://www.json.org/json-en.html">json.org</a>:</p>

<blockquote>
  <p>JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.</p>
</blockquote>

<p>On top of that format, we can used a more structured syntax, adapted to log management: <a href="https://cee.mitre.org/language/0.6/CEE_Common_Log_Syntax-JSON-v0.6.html">CEE Log Syntax</a>. This defined format is well used by various tools you might use, in the present case: nginx, rsyslog, and mongodb. Up to a certain level…</p>

<p><img alt="Structured JSON" src="media/42d29c82.json.gif" data-original-source="https://francois.aichelbaum.com/images/2020/12/json.gif" title="" srcset="/assets/resized/480/json.gif 480w, /images/2020/12/json.gif 628w"></p>

<h2>Nginx knows about @cee</h2>

<p>Sort of. Nginx has a <a href="https://nginx.org/en/docs/syslog.html">native syslog export</a> for both error_log and access_log. Out of the box, it will simply push all logs from the default log formats to syslog. This won’t be very convenient for proper management afterwards. But nginx is easy to use, and you can define your own custom format. You’ll find plenty of blogposts, tutorials, and others as <a href="https://ahelpme.com/software/rsyslog/send-access-logs-in-json-to-elasticsearch-using-rsyslog/">Any IT here? Help me!</a> describing the <em>proper</em> @cee JSON log format you need:</p>

<figure><pre><code data-lang="nginx"><span>log_format</span> <span>mainJSON</span> <span>escape=json</span> <span>'@cee:</span> <span>{</span><span>'</span>
        <span>'"vhost":"</span><span>$server_name</span><span>",'</span>
        <span>'"remote_addr":"</span><span>$remote_addr</span><span>",'</span>
        <span>'"time_iso8601":"</span><span>$time_iso8601</span><span>",'</span>
        <span>'"request_uri":"</span><span>$request_uri</span><span>",'</span>
        <span>'"request_length":"</span><span>$request_length</span><span>",'</span>
        <span>'"request_method":"</span><span>$request_method</span><span>",'</span>
        <span>'"request_time":"</span><span>$request_time</span><span>",'</span>
        <span>'"server_port":"</span><span>$server_port</span><span>",'</span>
        <span>'"server_protocol":"</span><span>$server_protocol</span><span>",'</span>
        <span>'"ssl_protocol":"</span><span>$ssl_protocol</span><span>",'</span>
        <span>'"status":"</span><span>$status</span><span>",'</span>
        <span>'"bytes_sent":"</span><span>$bytes_sent</span><span>",'</span>
        <span>'"http_referer":"</span><span>$http_referer</span><span>",'</span>
        <span>'"http_user_agent":"</span><span>$http_user_agent</span><span>",'</span>
        <span>'"upstream_response_time":"</span><span>$upstream_response_time</span><span>",'</span>
        <span>'"upstream_addr":"</span><span>$upstream_addr</span><span>",'</span>
        <span>'"upstream_connect_time":"</span><span>$upstream_connect_time</span><span>",'</span>
        <span>'"upstream_cache_status":"</span><span>$upstream_cache_status</span><span>",'</span>
        <span>'"tcpinfo_rtt":"</span><span>$tcpinfo_rtt</span><span>",'</span>
        <span>'"tcpinfo_rttvar":"</span><span>$tcpinfo_rttvar</span><span>"'</span>
        <span>'</span><span>}</span><span>'</span><span>;</span></code></pre></figure><p>They all give you the very same structure. Not sure who started it, but that’s not the point: they’re all wrong about it!</p>

<p><img alt="I am this close - Terminator 2" src="media/07926789.close.gif" data-original-source="https://francois.aichelbaum.com/images/2020/12/close.gif" title="I am this close - Terminator 2" srcset="/assets/resized/480/close.gif 480w, /images/2020/12/close.gif 720w"><br><em>I am this close - Terminator 2</em></p>

<p>They are close, indeed, but some details have to be fixed first. Why are they wrong? Because JSON, and especially the @cee version of it, has datatypes. Numbers (integers and floats) should not be encapsulated between quotes: quotes are for string only.</p>

<figure><pre><code data-lang="nginx"><span>log_format</span> <span>mainJSON</span> <span>escape=json</span> <span>'@cee:</span> <span>{</span><span>'</span>
        <span>'"vhost":"</span><span>$server_name</span><span>",'</span>
        <span>'"remote_addr":"</span><span>$remote_addr</span><span>",'</span>
        <span>'"time_iso8601":"</span><span>$time_iso8601</span><span>",'</span>
        <span>'"request_uri":"</span><span>$request_uri</span><span>",'</span>
        <span>'"request_length":</span><span>$request_length</span><span>,'</span>
        <span>'"request_method":"</span><span>$request_method</span><span>",'</span>
        <span>'"request_time":</span><span>$request_time</span><span>,'</span>
        <span>'"server_port":</span><span>$server_port</span><span>,'</span>
        <span>'"server_protocol":"</span><span>$server_protocol</span><span>",'</span>
        <span>'"ssl_protocol":"</span><span>$ssl_protocol</span><span>",'</span>
        <span>'"status":</span><span>$status</span><span>,'</span>
        <span>'"bytes_sent":</span><span>$bytes_sent</span><span>,'</span>
        <span>'"http_referer":"</span><span>$http_referer</span><span>",'</span>
        <span>'"http_user_agent":"</span><span>$http_user_agent</span><span>",'</span>
        <span>'"upstream_response_time":</span><span>$upstream_response_time</span><span>,'</span>
        <span>'"upstream_addr":"</span><span>$upstream_addr</span><span>",'</span>
        <span>'"upstream_connect_time":</span><span>$upstream_connect_time</span><span>,'</span>
        <span>'"upstream_cache_status":"</span><span>$upstream_cache_status</span><span>",'</span>
        <span>'"tcpinfo_rtt":</span><span>$tcpinfo_rtt</span><span>,'</span>
        <span>'"tcpinfo_rttvar":</span><span>$tcpinfo_rttvar</span><span>'</span>
        <span>'</span><span>}</span><span>'</span><span>;</span></code></pre></figure><p>Now we are good to go. Then, as all documentations state it, we can use this log format to push logs to syslog:</p>

<figure><pre><code data-lang="nginx"><span>access_log</span>      <span>syslog:server=10.10.10.2:514,facility=local7,tag=nginx,severity=info</span> <span>mainJSON</span><span>;</span></code></pre></figure><p>For sure, you can adapt the faciliy, the tag and the severity of it, along with the log format name.</p>

<h2>Rsyslog is great. Its documentation is not.</h2>

<p>That’s a fact, technical documentation, made by technical individuals, for technical persons, are not the best. Rsyslog might be one of the best example about this statement. Rainer Gerhards did a great work with his tool, one of the best syslog manager in my humble opinion. Thought, the documentation is a hell to read. Add to this fact, that it not as accurate as it should be.</p>

<p>In the use case I was working on, the infrastructure is benefiting from <a href="https://www.rsyslog.com/doc/v8-stable/">rsyslog v8-sable</a>. And as stated, we want to use the mongodb exported, aka <a href="https://www.rsyslog.com/doc/v8-stable/configuration/modules/ommongodb.html">ommongodb</a>. Seems easy and straight forward? Almost. But remember this IT mantra:</p>

<blockquote>
  <p>If all goes well, we forget something.</p>
</blockquote>

<p>For reasons out of my mind while writing down this post, I can tell you that it just do not work. Several aspects are to be considering before dealing with those logs.</p>

<ol><li>You need to ensure about the encodingi: BSON (the JSON variant mongodb uses internally) only supports valid UTF-8 character. For that, you need to properly fix the encoding before sending them. There is a <a href="https://www.rsyslog.com/doc/v8-stable/configuration/modules/mmutf8fix.html">module</a> for that.</li>
  <li>The structured @cee sent using the default configuration to mongodb will just push data “as-is”: first issue and main issue you’ll hit is about the date which will be pushed as a regular string.</li>
</ol><p><img alt="But why? - Ryan Reynolds" src="media/6de0b129.why.gif" data-original-source="https://francois.aichelbaum.com/images/2020/12/why.gif" title="But why? - Ryan Reynolds" srcset=" /images/2020/12/why.gif 480w"><br><em>But why? - Ryan Reynolds</em></p>

<p>Why? Simply because rsyslog only understand numbers and strings as <a href="https://www.rsyslog.com/doc/v8-stable/configuration/templates.html">datatypes</a> on one end, and mongodb doesn’t auto detect date and timestamps on the other end. Is it an issue at the end? If you want to benefit from mongodb filtering features on dates, yes it is. For that purpose, you need to use the ISODate() functions that mongodb only knows about.</p>

<p>After a tremendous number of attempts, trying to deal with the documentation to find the proper format, I decided to read the <a href="https://github.com/rsyslog/rsyslog/blob/master/plugins/ommongodb/ommongodb.c#L392-L393">ommongodb module source code</a>. Pretty easy as it’s a well written C code:</p>

<figure><pre><code data-lang="c">		<span>/* Convert text to ISODATE when needed */</span>
		<span>if</span> <span>(</span><span>strncmp</span><span>(</span><span>name</span><span>,</span> <span>"date"</span><span>,</span> <span>5</span><span>)</span> <span>==</span> <span>0</span> <span>||</span> <span>strncmp</span><span>(</span><span>name</span><span>,</span> <span>"time"</span><span>,</span> <span>5</span><span>)</span> <span>==</span> <span>0</span> <span>)</span> <span>{</span></code></pre></figure><p>You’ve just read it well: the code does not expect the fieldname to start with a <code>date</code> or <code>time</code>, but it expect the fieldname to be <code>date</code> or <code>time</code>.</p>

<p>Two solutions there:</p>
<ol><li>either update the log format, in nginx configuration, from <code>time_iso8601:</code> to <code>date:</code></li>
  <li>update your rsyslog configuration</li>
</ol><p>I’m not found of the string exporter used in the default documentation of rsyslog for mongodb: we’re using JSON as an input, we expect JSON at the output, why should we use strings in between?</p>

<p>For that reason, I moved to a JSON manipulation, thanks to the JSON parse module, and list type for the template:</p>

<figure><pre><code data-lang="rsyslog">module(load="mmutf8fix")
module(load="mmjsonparse")
module(load="ommongodb")

template(name="json-syslog" type="list" option.jsonf="on") {
        property(outname="vhost" name="$!vhost" format="jsonf" datatype="string" onEmpty="null")
        property(outname="remote_addr" name="$!remote_addr" format="jsonf" datatype="string" onEmpty="null")
        property(outname="time_iso8601" name="$!time_iso8601" format="jsonf")
        property(outname="date" name="$!time_iso8601")
        property(outname="request_uri" name="$!request_uri" format="jsonf" datatype="string" onEmpty="null")
        property(outname="request_length" name="$!request_length" format="jsonf" datatype="number")
        property(outname="request_method" name="$!request_method" format="jsonf" datatype="string" onEmpty="null")
        property(outname="request_time" name="$!request_time" format="jsonf" datatype="number")
        property(outname="server_port" name="$!server_port" format="jsonf" datatype="number")
        property(outname="server_protocol" name="$!server_protocol" format="jsonf" datatype="string" onEmpty="null")
        property(outname="ssl_protocol" name="$!ssl_protocol" format="jsonf" datatype="string" onEmpty="null")
        property(outname="status" name="$!status" format="jsonf" datatype="number")
        property(outname="bytes_sent" name="$!bytes_sent" format="jsonf" datatype="number")
        property(outname="http_referer" name="$!http_referer" format="jsonf" datatype="string" onEmpty="null")
        property(outname="http_user_agent" name="$!http_user_agent" format="jsonf" datatype="string" onEmpty="null")
        property(outname="upstream_response_time" name="$!upstream_response_time" format="jsonf" datatype="string" onEmpty="null")
        property(outname="upstream_addr" name="$!upstream_addr" format="jsonf" datatype="string" onEmpty="null")
        property(outname="upstream_connect_time" name="$!upstream_connect_time" format="jsonf" datatype="string" onEmpty="null")
        property(outname="upstream_cache_status" name="$!upstream_cache_status" format="jsonf" datatype="string" onEmpty="null")
        property(outname="tcpinfo_rtt" name="$!tcpinfo_rtt" format="jsonf" datatype="number")
        property(outname="tcpinfo_rttvar" name="$!tcpinfo_rttvar" format="jsonf" datatype="number")
}</code></pre></figure><p><img alt="Now we can talk. - Kyle Maclachlan - Twin Peaks" src="media/a8112059.talk.gif" data-original-source="https://francois.aichelbaum.com/images/2020/12/talk.gif" title="Now we can talk. - Kyle Maclachlan - Twin Peaks" srcset="/assets/resized/480/talk.gif 480w, /images/2020/12/talk.gif 498w"><br><em>Now we can talk. - Kyle Maclachlan - Twin Peaks</em></p>

<h2>That’s not all folks!</h2>

<p>Following that changes, nginx logs are pushed to mongodb, allowing easy statistics aggregation for billing purpose. As we just want to push these lines to mongodb, best is to proceed with something like:</p>

<figure><pre><code data-lang="rsyslog">if ($syslogfacility-text == 'local7' and $syslogseverity-text == 'info') then {
        action(type="mmutf8fix")
        action(type="mmjsonparse")
        action(type="ommongodb" uristr="mongodb://--REDACTED--:--REDACTED--@--REDATED--:27017/?authSource=logs&amp;authMechanism=SCRAM-SHA-1" db="logs" collection="nginx" template="json-syslog")
        &amp; stop
}</code></pre></figure><p>The <code>uristr</code> is a bit different from the the documentation because, once again, the document is not really explicit enough about it. For most real-life scenarios, even if you use a mongodb cluster, you want to rely on dedicated database and dedicated user, with the proper set of permissions. To benefit from it, you need to add some details within the <code>uristr</code> as the <code>user:password</code> but also some query parameters:</p>
<ul><li><code>authSource</code>: the db to rely on for authentication, as you user has only permissons on it</li>
  <li><code>authMechanism</code>: you’re pushing a password via the dsn</li>
</ul><h2>At the end</h2>

<p>We went through. We’ve set up nginx to push JSON @cee-compliant logs to syslog, then we prepare the logs to be properly pushed to mongodb, and we publish them.</p>

<p>Now our folks can run their micro-batching to generate live billing and usage statistics for the customers.</p>

<p>How would you have tackled this kind of need? Did you suffer from technical documentations not adequate or not uptodate?</p>
<p><img src="media/fa8a9a5c.d3aee8c1dcab31df72e021766230892b" data-original-source="http://cdn.libravatar.org/avatar/d3aee8c1dcab31df72e021766230892b" alt="Gravatar de Francois Aichelbaum" class="gravatar" /><br/><i>Original post of <a href="https://francois.aichelbaum.com/2020/12/23/json-mongodb-rsyslog-are-on-a-boat" title="Visit the source">Francois Aichelbaum</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


title: miamondo : Lancer plusieurs processus sans utiliser de threads (Labortablo – 3ème partie)
uri: miamondo-Lancer-plusieurs-processus-sans-utiliser-de-threads-(Labort
feed_id:
https://miamondo.org/2020/12/24/python-lancer-plusieurs-processus-sans-utiliser-de-threads-labortablo-3eme-partie/

url:
https://miamondo.org/2020/12/24/python-lancer-plusieurs-processus-sans-utiliser-de-threads-labortablo-3eme-partie/

content:
<p>Mon ordinateur est équipé de deux écrans. Par conséquent, j’ai fait en sorte que mon interface de bureau moulé à la louche, prenne en compte ce cas de figure. Dans un premier temps, j’ai utilisé le module <strong>multiprocessing</strong>. Cela me semblait être la solution idéale pour lancer simultanément un process sur chaque écran.</p>



<p>Seulement, il y a un léger problème. <strong>threading</strong> et <strong>multiprocessing</strong> rentrent en conflit avec des interfaces graphiques telles que tkinter. Le résultat final présente des signes d’instabilité qui ne sont pas du meilleur effet. En théorie, on peut utiliser <strong>multiprocessing</strong> avec <strong>tkinter</strong> mais toutes les interactions avec l’interface graphique doivent se faire par un seul et unique thread. Le module <strong>multiprocessing</strong> peut traiter des données et faire des calculs dans plusieurs threads, mais il ne peut pas « multithreader » <strong>tkinter</strong>! Les deux processus doivent être séparés.</p>



<p>Donc, dans un souci d’amélioration continue, je me suis mis en quête d’une solution alternative, et je pense avoir codé quelque chose qui répond à mes attentes en terme de stabilité, car même dans un projet amateur, il est important d’être <em>ceinture-bretelles</em>. Alors comment ai-je procédé? En fait, je suis parti de l’idée toute simple que pour deux écrans, il faut avoir non pas deux threads d’un même programme mais deux programmes! Et je voulais que tout le processus se déroule de manière automatique. Pas question pour l’usager, d’ouvrir un fichier de configuration pour en modifier le contenu. L’objectif était vraiment de coder quelque chose qui s’installe tout seul et qui vit sa vie sans intervention de maintenance. Mais comment faire pour donner l’illusion de lancer et d’arrêter deux threads?</p>



<ol><li><strong>Situation initiale</strong></li></ol><p>Voici la configuration initiale avec multiprocessing.</p>



<figure><img data-attachment-id="1184" data-permalink="https://miamondo.org/initial/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/initial.png" data-orig-size="747,460" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="initial" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/initial.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/initial.png?w=747" src="https://miamondo96030527.files.wordpress.com/2020/12/initial.png?w=747" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/initial.png 747w, https://miamondo96030527.files.wordpress.com/2020/12/initial.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/initial.png?w=300 300w" sizes="(max-width: 747px) 100vw, 747px"></figure><p>2. <strong>Suppression de multiprocessing, modification du code et explications détaillées</strong></p>



<p>Au démarrage de l’ordinateur, le programme se lance grâce au fichier <strong>start.py</strong> dont le chemin se trouve dans <strong>~/.config/openbox/autostart</strong>. </p>



<p>Ouvrons, si vous le voulez bien, le fichier lanceur <strong><a rel="noreferrer noopener" href="https://gitlab.com/miamondo/labortablo/-/blob/master/start.py" target="_blank">start.py</a></strong>… La première opération exécutée par ce script consiste à détruire tous les fichiers et répertoires antérieurs qui ne correspondent pas à la configuration par défaut (en monomoniteur, si vous me permettez ce néologisme). Il est nécessaire de partir sur une base propre:</p>



<div><figure><img data-attachment-id="1191" data-permalink="https://miamondo.org/def/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/def.png" data-orig-size="271,113" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="def" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/def.png?w=271" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/def.png?w=271" src="https://miamondo96030527.files.wordpress.com/2020/12/def.png?w=271" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/def.png 271w, https://miamondo96030527.files.wordpress.com/2020/12/def.png?w=150 150w" sizes="(max-width: 271px) 100vw, 271px"><figcaption><strong>Version standard monomoniteur</strong></figcaption></figure></div>



<p>Pourquoi détruire la configuration multi-écrans à chaque démarrage? Eh bien parce que l’utilisateur peut très bien décider, un beau matin, de suppprimer un écran ou d’en rajouter un troisième. Je ne suis pas dans sa tête et je ne connais pas ses intentions.</p>



<p>Ensuite, vient le moment de déterminer le nombre de moniteurs. Plutôt que de compter avec ses doigts, confions cette tâche à la commande suivante:</p>


<pre>
xrandr --listactivemonitors
</pre>


<p>Résultat:</p>


<pre>
Monitors: 4
 0: +*HDMI-1 1920/698x1080/392+1920+0  HDMI-1
 1: +VGA-1 1920/477x1080/268+0+0  VGA-1
 2: etc...
 3: etc...

</pre>


<p>Je crois que c’est clair… Maintenant, le programme va créer autant de répertoires qu’il y a de moniteurs supplémentaires, et il va copier le contenu de <strong>labortablo</strong> dans chacun d’entre eux. Si vous avez quatre écrans, il va donc créer en sus de <strong>labortablo</strong> (qui est en quelque sorte le <em>« répertoire zéro</em>« ): </p>



<ul><li>labortablo_1</li><li>labortablo_2</li><li>labortablo_3</li></ul><p>Nous nous retrouvons donc avec cette configuration:</p>



<div><figure><img data-attachment-id="1193" data-permalink="https://miamondo.org/version_4/" data-orig-file="https://miamondo96030527.files.wordpress.com/2020/12/version_4.png" data-orig-size="542,122" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="version_4" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2020/12/version_4.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2020/12/version_4.png?w=542" src="https://miamondo96030527.files.wordpress.com/2020/12/version_4.png?w=542" alt="" srcset="https://miamondo96030527.files.wordpress.com/2020/12/version_4.png 542w, https://miamondo96030527.files.wordpress.com/2020/12/version_4.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2020/12/version_4.png?w=300 300w" sizes="(max-width: 542px) 100vw, 542px"><figcaption><strong>Version quadrimoniteur</strong></figcaption></figure></div>



<p>Voici la ligne de code qui effectue cette opération:</p>


<pre>
if i > 0:
    shutil.copytree(
        f'{self.cwd}/labortablo',
        f'{self.cwd}/labortablo_{i}'
        )
</pre>


<p>De cette manière, si je veux apporter des modifications au code avant de le pousser dans mon dépôt Git, il me suffit de modifier labortablo, le <em>« répertoire zéro »</em>. Je sais qu’au prochain démarrage, les modifications seront prises en compte pour tous les autres programmes.</p>



<p>Ensuite le script <strong>start.py</strong> se charge de traiter les informations relatives aux écrans. Puis, il créé un fichier <strong><a rel="noreferrer noopener" href="https://gitlab.com/miamondo/labortablo/-/blob/master/labortablo/Config_files/coords.txt" target="_blank">coords.txt</a></strong> pour chaque interface de bureau. Ce fichier est construit de telle sorte qu’il puisse se transformer très facilement en dictionnaire. Je trouve que cette syntaxe facilite bien la vie.</p>


<pre>
w:1920   # largeur
h:1080   # hauteur
x:0      # abscisse
y:0      # ordonnée

</pre>


<p>Ainsi, je peux passer rapidement ces paramètres aux classes qui en ont besoin. Tous les éléments graphiques vont récupérer ces informations pour configurer l’interface de bureau de chaque écran.</p>


<pre>
args = dict()
with open('coords.txt', 'r') as rfile:
    for line in rfile.readlines():
        args[line.split(':')[0]] = int(line.strip().split(':')[1])
</pre>


<p>Le moment est venu de créer le fichier <strong>start.sh</strong>. Il va contenir tous les programmes à lancer et il sera détruit au prochain démarrage. Donc, dans le cas de figure ou il y a quatre écrans, voici à quoi ressemble ce script:</p>


<pre>
#!/bin/bash

/home/miamondo/chemin/vers/labortablo/taskbar.py &amp;
/home/miamondo/chemin/vers/labortablo/categories.py &amp;
/home/miamondo/chemin/vers/labortablo_1/taskbar.py &amp;
/home/miamondo/chemin/vers/labortablo_1/categories.py &amp;
/home/miamondo/chemin/vers/labortablo_2/taskbar.py &amp;
/home/miamondo/chemin/vers/labortablo_2/categories.py &amp;
/home/miamondo/chemin/vers/labortablo_3/taskbar.py &amp;
/home/miamondo/chemin/vers/labortablo_3/categories.py &amp;
</pre>


<p>Alors, vous allez me dire qu’il ne s’agit pas d’un script Python. Par conséquent, je ne devrais pas affirmer que Labortablo est une interface de bureau entièrment codée en Python. C’est vrai. Je le reconnais. Mais je n’ai pas d’autres choix si je veux lancer mon métaprogramme. On peut très bien lancer des fichiers <strong>*.py</strong> à partir d’un fichier Python mais j’ai ouï-dire que ce genre d’hérésie conduisait tout droit au bûcher.</p>



<p>Avec Python, on lance des modules, pas des fichiers, et à ce stade des opérations, je ne peux pas car il faudrait que j’utilise threading ou multiprocessing. C’est le python qui se mord la queue!</p>



<p>Enfin, dernière opération, je rend le fichier <strong>start.sh</strong> exécutable. Il faut le faire  à chaque fois car il est détruit à chaque démarrage. Puis <strong>start.sh</strong> est lancé par <strong>start.py</strong>.</p>



<p><strong>Conclusion</strong></p>



<p>J’ai bien conscience du fait que cette manière de procéder est loin d’être académique mais d’une part, je m’en fiche un peu, et d’autre part ça tourne comme une horloge. J’utilise cette interface de bureau tous les jours, non pas dans une machine virtuelle mais sur mon PC principal. Il faut encore que je lui rajoute la gestion des catégories et des applications (ajouts/suppressions). Il faut aussi que je fasse le point sur tout ce qu’il y a à installer pour faire tourner le programme (xrandr, wmctrl, xprop etc…)</p>



<p>Voilà… Je n’oublie pas de vous souhaiter un Joyeux Nowouel et une bonne vaccination à toutes et à tous.</p>
<p><img src="media/848c13f4.27be241458674ac3359b0353fdc37c4a" data-original-source="http://cdn.libravatar.org/avatar/27be241458674ac3359b0353fdc37c4a" alt="Gravatar de miamondo" class="gravatar" /><br/><i>Original post of <a href="https://miamondo.org/2020/12/24/python-lancer-plusieurs-processus-sans-utiliser-de-threads-labortablo-3eme-partie/" title="Visit the source">miamondo</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>miamondo : <a href="">Labortablo, une interface de bureau cod&eacute;e en Python sur une base Archlinux/Openbox (2&egrave;me partie)</a> (20/12/2020)</li><li>miamondo : <a href="">Labortablo, une interface de bureau cod&eacute;e en Python sur une base Archlinux/Openbox (1&egrave;re partie)</a> (14/12/2020)</li><li>Asher256 : <a href="">Script Linux: Trouver Facilement le Nom d&rsquo;un Fichier Ex&eacute;cutable</a> (08/01/2009)</li></ul></div></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #52
uri: 2020-12-28-Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-52
feed_id:
https://blog.journalduhacker.net/index.php?article304/liens-interessants-journal-du-hacker-semaine-52-2020

url:
https://blog.journalduhacker.net/index.php?article304/liens-interessants-journal-du-hacker-semaine-52-2020

content:
<p>Pour la 52ème semaine de l'année 2020, voici <strong>12 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/esuo5q/fermeture_du_compte_twitter_du_journal_du">Fermeture du compte Twitter du Journal du hacker</a></li>
<li><a href="https://www.journalduhacker.net/s/xc4jd0/interdiction_des_drones_victoire_totale">Interdiction des drones : victoire totale contre le gouvernement</a></li>
<li><a href="https://www.journalduhacker.net/s/0pzbag/windows_et_l_utilisateur">Windows et l’utilisateur</a></li>
<li><a href="https://www.journalduhacker.net/s/6f73e8/nginx_g_re_les_images_au_format_webp">Nginx gère les images au format Webp</a></li>
<li><a href="https://www.journalduhacker.net/s/t98fuz/gal_ne_un_serveur_de_vid_oconf_rence_libre">Galène, un serveur de vidéoconférence libre</a></li>
<li><a href="https://www.journalduhacker.net/s/d8nvkw/25_ans_de_gimp_et_version_de_d_veloppement_2">25 ans de GIMP et version de développement 2.99.2 : premiers pas vers GIMP 3 !</a></li>
<li><a href="https://www.journalduhacker.net/s/r97qwu/transparent_opaque_ou_invisible">Transparent, opaque ou invisible ?</a></li>
<li><a href="https://www.journalduhacker.net/s/vnb1yi/15_blogs_de_dev_ops_d_couvrir_ou_red_couvrir">15 Blogs de Dev &amp; Ops à découvrir ou à redécouvrir !</a></li>
<li><a href="https://www.journalduhacker.net/s/1yzf2s/sondage_sur_l_envie_des_informaticiens_d">Sondage sur l’envie des informaticiens d’aller élever des chèvres dans le Larzac (genre)</a></li>
<li><a href="https://www.journalduhacker.net/s/2ggfwe/cr_er_un_bot_discord_avec_python">Créer un bot Discord avec Python</a></li>
<li><a href="https://www.journalduhacker.net/s/tn8nb8/meteor_au_service_de_la_s_curit_de_votre_r">"Meteor" au service de la sécurité de votre réseau</a></li>
<li><a href="https://www.journalduhacker.net/s/aqoysk/organisez_vos_t_ches_efficacement_la_m">Organisez vos tâches efficacement : la méthode ultime.</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://twitter.com/journalduhacker">Le compte Twitter du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article304/liens-interessants-journal-du-hacker-semaine-52-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Carl Chenet : <a href="">Liens int&eacute;ressants Journal du hacker semaine #52</a> (27/12/2015)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #52</a> (02/01/2017)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #52</a> (01/01/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #52</a> (31/12/2018)</li><li>Journal du hacker : <a href="">Liens int&eacute;ressants Journal du hacker semaine #52</a> (30/12/2019)</li></ul></div></p>


title: Eddy33 : Fedora 33 vs Fedora 32 : comparaison des performances pour les versions 64 bits
uri: Eddy33-Fedora-33-vs-Fedora-32-comparaison-des-performances-pour-le
feed_id:
http://eddy33.eddy33.free.fr/weblog/index.php?post/2020/12/28/Fedora-33-vs-Fedora-32-%3A-comparaison-des-performances-pour-les-versions-64-bits

url:
http://eddy33.eddy33.free.fr/weblog/index.php?post/2020/12/28/Fedora-33-vs-Fedora-32-%3A-comparaison-des-performances-pour-les-versions-64-bits

content:
<p>Salut.</p>
<p>Voici les résultats comparatifs de Fedora 33 vs Fedora 32.</p>
<p>Pour rappel, ma machine est équipée d'un Quad Core Intel Q6600 à 2,4 GHz avec 4 Go de RAM.
</p>
<p>Je me suis limité au benchmark UnixBench qui fournit un indice global, ce qui me simplifiera la comparaison.
La version UnixBench utilisée est la version <a href="http://www.tux.org/pub/tux/niemi/unixbench/unixbench-4.1.0.tgz">4.1.0</a>.</p>
Mon protocole de tests est le suivant : <br><ul><li>Installation de Fedora 33 version 64 bits avec le noyau Fedora 5.9.14-200.fc33.x86_64.</li>
<li>La machine est placée en niveau 3 (init 3).</li>
<li>10 séries de tests avec UnixBench compilé sous Fedora 33 et exécuté sous Fedora 33 (5.9.14-200.fc33.x86_64).</li>
<li>10 séries de tests avec UnixBench compilé sous Fedora 32 et exécuté sous Fedora 32 (5.6.6-300.fc32.x86_64).</li>
</ul><div>
Voici les résultats obtenus :</div><div><h2>Fedora 33 version 64 bits :</h2>


<a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_1">Série 1</a> : 695.5<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_2">Série 2</a> : 699.9<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_3">Série 3</a> : 714.6<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_4">Série 4</a> : 711.5<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_5">Série 5</a> : 714.1<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_6">Série 6</a> : 605.6<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_7">Série 7</a> : 683.1<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_8">Série 8</a> : 695.9<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_9">Série 9</a> : 707.2<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F33/unixbench_64_10">Série 10</a> : 697.6<br><br>
Moyenne : 692,5<br><div><br><h2>Fedora 32 version 64 bits :</h2>
</div><div>

Voici pour rappel les résultats obtenus avec Fedora 32 : </div><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_1">Série 1</a> : 672.0<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_2">Série 2</a> : 680.7<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_3">Série 3</a> : 671.5<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_4">Série 4</a> : 687.4<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_5">Série 5</a> : 681.9<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_6">Série 6</a> : 675.2<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_7">Série 7</a> : 670.2<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_8">Série 8</a> : 688.8<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_9">Série 9</a> : 679.6<br><a hreflang="fr" href="http://eddy33.eddy33.free.fr/benchmarks/F32/unixbench_64_10">Série 10</a> : 682.9<br><br>
Moyenne : 679.0<div><br><h2>Résultats :</h2>
</div>

Pour Fedora 33, on obtient un indice moyen de 692,5 pour UnixBench.<br>Pour
Fedora 32,  j'avais obtenu un indice moyen de 679.0 pour UnixBench.<br><br><br>On
a donc une petite hausse de 2,0 % de Fedora 33 64 bits par
rapport à Fedora 32 64 bits :<br><br><img title="perfs_fedora_F33.png" alt="perfs_fedora_F33.png" src="media/30a0eb94.perfs_fedora_F33.png" data-original-source="http://eddy33.eddy33.free.fr/weblog/public/perfs_fedora_F33.png" width="600"><br><br><h2>Conclusion :</h2>
<p>
Au moment de ces tests, le noyau Fedora 33
(basé sur le noyau vanilla 5.9.14) est un peu plus performant de près de 2 % que le
noyau Fedora 32
(basé sur le noyau vanilla  5.6.6). On retrouve la fluctuation habituelle peu significative par rapport aux précédents tests. </p>
<div>
<p>++</p>
</div></div>
<p><img src="media/889f4f2a.d1430102ed05bb1a49902c819454fef2" data-original-source="http://cdn.libravatar.org/avatar/d1430102ed05bb1a49902c819454fef2" alt="Gravatar de Eddy33" class="gravatar" /><br/><i>Original post of <a href="http://eddy33.eddy33.free.fr/weblog/index.php?post/2020/12/28/Fedora-33-vs-Fedora-32-%3A-comparaison-des-performances-pour-les-versions-64-bits" title="Visit the source">Eddy33</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Eddy33 : <a href="">Fedora 21 vs Fedora 20 : comparaison des performances pour les versions 32 bits</a> (11/02/2015)</li><li>Eddy33 : <a href="">Fedora 22 vs Fedora 21 : comparaison des performances pour les versions 32 bits</a> (26/07/2015)</li><li>Eddy33 : <a href="">Fedora 23 vs Fedora 22 : comparaison des performances pour les versions 32 bits</a> (02/05/2016)</li><li>Eddy33 : <a href="">Fedora 24 vs Fedora 23 : comparaison des performances pour les versions 32 bits</a> (20/12/2016)</li><li>Eddy33 : <a href="">Fedora 25 vs Fedora 24 : comparaison des performances pour les versions 32 bits</a> (22/12/2016)</li></ul></div></p>


title: antistress : Deux de mes fiertés : la cigarette et les réseaux sociaux
uri: antistress-Deux-de-mes-fiertés-la-cigarette-et-les-réseaux-socia
feed_id:
https://libre-ouvert.tuxfamily.org/index.php?article252/deux-de-mes-fiertes-la-cigarette-et-les-reseaux-sociaux

url:
https://libre-ouvert.tuxfamily.org/index.php?article252/deux-de-mes-fiertes-la-cigarette-et-les-reseaux-sociaux

content:
<p><img src="media/222e4339.ike-by-the-icon-z-from-the-noun-project_cc-by-sa-2.0_400x266.jpg" data-original-source="https://libre-ouvert.tuxfamily.org/data/images/derived-from-1-cigarette-by-castio-t.-lauren-and-2-dislike-by-the-icon-z-from-the-noun-project_cc-by-sa-2.0_400x266.jpg" alt="Pouce renversé devant une cigarette se consumant" height="266" width="400"><br>
Crédits photo en fin de billet [1]</p>

<p>Étant dans ma quarante-cinquième année, j'ai eu la chance (je crois que ça en est une) de connaître une adolescence sans <em xml:lang="en" lang="en">smartphone</em> et surtout sans réseaux sociaux (au sens étriqué et artificiel où on entend « réseaux sociaux » de nos jours, puisque ces termes ont été préemptés au bénéfice de quelques sociétés et de leur marque [2]). J'ai plus de vingt ans lorsque Facebook se répand autour de moi.</p>

<p>Mais revenons à mon adolescence : je me souviens très clairement qu'à la fin des années 80, début des 90, fumer la cigarette était perçu comme très <em xml:lang="en" lang="en">cool</em>, et vous connaissez le besoin de conformation aux pairs caractéristique de cet âge.</p><p>Je ne sais par quel miracle j'ai réussi à ne pas céder à la tentation de fumer ma première cigarette – celle qui décide des suivantes – laquelle tentation s'est pourtant présentée à moi à d'innombrables reprises.</p>

<p>Pour ce qui est des réseaux sociaux, éviter la tentation a sans doute été plus facile compte tenu que j'avais dépassé l'adolescence lorsqu'ils se sont répandus. Mais cela ne veut pas dire que je n'ai pas été confronté, de multiples fois, à cette tentation, à la pression sociale.</p>

<p>J'ai notamment ce souvenir précis, tandis que j'étais en vacances avec une tribu d'amis dont certains plus jeunes qui insistaient pour que je les rejoigne sur Facebook. Je me souviens m'être retrouvé à hésiter devant l'écran d'accueil particulièrement léché de Facebook.</p>

<p>Ce qui m'a fait tenir était que j'avais alors acquis ma conviction de libriste et que les problèmes de vie privée posés par des services comme Facebook étant déjà clairement identifiés et commentés dans ma sphère informationnelle. J'ai pu arbitrer en faveur de mes valeurs et en défaveur de Facebook. De justesse.</p>

<p>Bien plus tard les réseaux sociaux alternatifs, décentralisés et/ou respectueux de la vie privée, ont commencé à émerger, de sorte qu'il est devenu possible de fréquenter des réseaux sociaux en ligne « sans se compromettre » (ni compromettre le Monde).</p>

<p>Mais, à ce moment là, c'est une autre conviction qui m'a tenu éloigné des réseaux sociaux mêmes respectueux de la vie privée : celle que <a href="https://libre-ouvert.tuxfamily.org/?article196/bons-baisers-de-la-quatrieme-dimension">je devais maîtriser ma sphère informationnelle pour me dégager une disponibilité psychique</a>.</p>

<p>Par un mélange de chance et de conscience je peux dire aujourd'hui que je n'ai ni (eu) besoin d'arrêter ni la cigarette ni les réseaux sociaux, faute d'y avoir préalablement succombé.</p>

<p>Et c'est tant mieux, parce que ceux qui ont eu à prendre la décision d'arrêter savent mieux que moi à quel point c'est difficile.</p>

<p>Surtout, je suis très heureux de l'équilibre que j'y ai trouvé.</p>

<hr><p>[1] L'illustration de ce billet est une composition réalisée par mes soins avec <a href="https://framalibre.org/content/gimp">GIMP</a> à partir de <a href="https://www.flickr.com/photos/teddybuddy/21718044972/">cette photographie</a> et de <a href="https://thenounproject.com/term/dislike/3323800/">cette icône</a> (que j'ai préalablement modifiée : <a href="https://libre-ouvert.tuxfamily.org/data/documents/dislike.xcf">source ici</a>) ; elle est soumise à la licence CC BY-SA 2.0.
<br>
[2] Des sites comme <a href="https://linuxfr.org/">LinuxFR</a> ou des forums comme <a href="https://forum.hardware.fr/">celui de <abbr lang="en" title="hardware.fr">HFR</abbr></a> sont pour moi des réseaux sociaux.</p>
<p><img src="media/4839f6a5.470c5e17640a289d1e99b26d2dec9f54" data-original-source="http://cdn.libravatar.org/avatar/470c5e17640a289d1e99b26d2dec9f54" alt="Gravatar de antistress" class="gravatar" /><br/><i>Original post of <a href="https://libre-ouvert.tuxfamily.org/index.php?article252/deux-de-mes-fiertes-la-cigarette-et-les-reseaux-sociaux" title="Visit the source">antistress</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://www.citizenz.info/articles/symfony-5-bien-debuter
title: citizenz7 : Symfony 5 : bien débuter
uri: citizenz7-Symfony-5-bien-débuter
url: https://www.citizenz.info/articles/symfony-5-bien-debuter
content:
symfony-5-bien-debuter
<p><img src="media/81133586.d3d22ade032c891f4b97588788975fc6" data-original-source="http://cdn.libravatar.org/avatar/d3d22ade032c891f4b97588788975fc6" alt="Gravatar de citizenz7" class="gravatar" /><br/><i>Original post of <a href="https://www.citizenz.info/articles/symfony-5-bien-debuter" title="Visit the source">citizenz7</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: http://blog.chimrod.com/2021/01/de-la-calligraphie-en-javascript/
title: Chimrod : De la calligraphie en javascript
uri: Chimrod-De-la-calligraphie-en-javascript
url: http://blog.chimrod.com/2021/01/de-la-calligraphie-en-javascript/
content:
<p>À la suite de mon article précédent, j’ai essayé d’aller un peu plus loin dans
ce qu’il était possible de faire en javascript. La page pour construire les
graphes montrait déjà qu’il était possible de charger du javascript dans la
page, et modifier directement le contenu du blog à partir du code exécuté.</p>
<p>En suivant toujours la même démarche (code en OCaml, compilé en javascript),
j’ai mis en place une <em>ardoise</em> dans laquelle je souhaitais retrouver sur <span>PC</span> le
rendu que l’on peut avoir avec une plume dans la main<span> </span>: <a href="http://blog.chimrod.com/pages/script.it/#ardoise-calligraphique">l’ardoise calligraphique</a>.</p>
<div>
<h2>Ce que j’ai appris</h2>
<p>Les courbes de beziers<span> </span>! Je ne pensais pas qu’il y aurait autant à faire avec<span> </span>!
Pour ceux que cela intéresse, la page <a href="https://pomax.github.io/bezierinfo/">A Primer on Bézier Curves</a> est une
référence avec tout ce qu’il faut pour mettre en place ses propres librairies.</p>
<p>Afin d’avoir un tracé souple de la courbe, j’ai suivi un document de l’<a href="media/f7320fd2.dd_splines.pdf" data-original-source="https://www.math.ucla.edu/~baker/149.1.02w/handouts/dd_splines.pdf"><span>UCLA</span></a>
qui explique comment construire les courbes de beziers en suivant une série de
points, ce qui m’a fait faire un détour par les produits matriciels pour
résoudre ce genre d’équations<span> </span>:</p>
<div>
\\begin{equation*}
\\begin{bmatrix}4 &amp;&amp; 1 &amp;&amp; 0 &amp;&amp; 0 \\\\ 1 &amp;&amp; 4 &amp;&amp; 1 &amp;&amp; 0 \\\\0 &amp;&amp; 1 &amp;&amp; 4  &amp;&amp; 1 \\\\0 &amp;&amp; 0 &amp;&amp; 1 &amp;&amp; 4  \\end{bmatrix}
\\begin{bmatrix} B_1 \\\\ B_2 \\\\ B_3 \\\\ B_4 \\end{bmatrix}
=
\\begin{bmatrix} (6 S_1 - S_0)  \\\\ 6S_2 \\\\ 6 S_3 \\\\ (6S_4 - S_5) \\end{bmatrix}
\\end{equation*}
</div>
<p>A priori, il n’existe pas de librairie pour faire de la réduction de matrice en
javascript, mais l’avantage d’utiliser OCaml est d’avoir sous la main <a href="https://github.com/kandluis/ocaml-matrix">quelques
librairies</a> permettant de faire le boulot directement.</p>
<p>Ensuite, travailler le <span>DOM</span>. Vu que le site est statique, j’ai choisi de
modifier la page directement à partir du code javascript. En ajoutant un
élément, en retirant ceux dont je n’avais nécessité, cela permet de changer
l’apparence directement pour se contruire son application. Cela m’a permis de
me plonger dans la librairie <a href="https://erratique.ch/software/brr">brr</a> qui permet d’interragir avec la page via
des évènemens fonctionnels.</p>
<p>Enfin, les <a href="https://developer.mozilla.org/fr/docs/Web/API/Web_Workers_API/Utilisation_des_web_workers">webWorkers</a>, qui sont des threads pouvant être lancés dans le code
javascript. Dans l’application, je les utilise pour <em>lisser</em> la courbe une fois
que celle-ci a été contruite une première fois.</p>
</div>
<div>
<h2>Ce qu’il faudrait continuer</h2>
<p>Il me manque tout un cadre mathématique pour aller plus loin, j’aurai par
exemple besoin de déterminer l’<a href="https://pomax.github.io/bezierinfo/#extremities">extrémité</a> exacte de la courbe afin de traiter
ces cas de manière précise, et j’ai besoin de comprendre le code avant de m’y mettre…</p>
<p>Par conséquent, l’export <span>SVG</span> est un peu biaisé, on retrouve bien ce qui est
affiché sur l’écran, mais cela donne quelque chose qui n’est pas vraiment
éditable comme je l’aurai souhaité.</p>
<p>Il faudrait aussi aller plus loin dans les mouvements de plumes, permettre des
rotations locales, juste sur un segment et non pas sur la totalité du tracé,
enfin des petits ajustements pour qu’il y ait vraiment une plus-value.</p>
</div>
<div>
<h2>D’autres pistes</h2>
<p>Cela m’a aussi donné d’autres pistes pour continuer avec javascript et le blog.
En utilisant l’<span>API</span> <a href="https://developer.mozilla.org/fr/docs/Web/API/Web_Storage_API">Web Storage</a>, on peut également stocker des données comme
si l’on travaillait sur un fichier, les données étant stockées dans l’espace du
navigateur. En combinant cela avec le côté statique du site, je pense à une
page de prise de note, qui dont le code serait uniquement exécuté dans le
navigateur, sans avoir besoin de serveur comme support.</p>
<p>Le blog offrant un espace dans lequel je peux mettre en ligne mes applications,
cela me donne envie de continuer et m’en servir comme petit terrain d’exipérimentation…</p>
</div>

<p><img src="media/51a0b109.d6b159cb14220daa49ff4a3f9a25f9f3" data-original-source="http://cdn.libravatar.org/avatar/d6b159cb14220daa49ff4a3f9a25f9f3" alt="Gravatar de Chimrod" class="gravatar" /><br/><i>Original post of <a href="http://blog.chimrod.com/2021/01/de-la-calligraphie-en-javascript/" title="Visit the source">Chimrod</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>theClimber : <a href="">En vrac quelques liens</a> (03/06/2009)</li><li>Guillaume Kulakowski : <a href="">YUICompressor en RPM pour Fedora 10 &amp;amp; RHEL 5</a> (23/12/2008)</li><li>Matao : <a href="">divx2dvd : comment convertir des divx en un DVD</a> (16/04/2008)</li><li>theClimber : <a href="">R&eacute;cup&eacute;rer les tweets d&#039;une instance statusnet en live avec javascript</a> (02/02/2011)</li><li>Cyrille BORNE : <a href="">LaTeX en sciences humaines</a> (04/09/2012)</li></ul></div></p>


title: Journal du hacker : Liens intéressants Journal du hacker semaine #53
uri: Journal-du-hacker-Liens-intéressants-Journal-du-hacker-semaine-53
feed_id:
https://blog.journalduhacker.net/index.php?article305/liens-interessants-journal-du-hacker-semaine-53-2020

url:
https://blog.journalduhacker.net/index.php?article305/liens-interessants-journal-du-hacker-semaine-53-2020

content:
<p>Pour la 53ème semaine de l'année 2020, voici <strong>10 liens</strong> intéressants que vous avez peut-être ratés, relayés par <a href="https://www.journalduhacker.net/">le Journal du hacker</a>, votre source d’informations pour le Logiciel Libre francophone !</p>

<a href="https://www.journalduhacker.net/"><img src="media/01f45034.logo-journal-du-hacker.png" data-original-source="https://blog.journalduhacker.net/data/medias/logo-journal-du-hacker.png"></a>

<ul><li><a href="https://www.journalduhacker.net/s/rrfema/explorons_le_code_source_du_vaccin">Explorons le code source du vaccin BioNTech / Pfizer contre le SARS-CoV-2</a></li>
<li><a href="https://www.journalduhacker.net/s/yfiddo/alternative_github_et_gitlab_la_forge">Alternative à Github et Gitlab : la forge Chapril en France</a></li>
<li><a href="https://www.journalduhacker.net/s/di211u/en_2021_les_appareils_lectriques_auront">En 2021, les appareils électriques auront un indice de réparabilité</a></li>
<li><a href="https://www.journalduhacker.net/s/comgzz/le_web_est_il_devenu_trop_compliqu">Le Web est-il devenu trop compliqué ?</a></li>
<li><a href="https://www.journalduhacker.net/s/fwov4y/cat_7_cat_6_grade_3_quel_c_ble_rj45_choisir">Cat 7, Cat 6, Grade 3 : Quel câble RJ45 choisir pour ma maison</a></li>
<li><a href="https://www.journalduhacker.net/s/oi0pos/gemini_une_alternative_au_world_wide_web">Gemini, une alternative au World Wide Web ?</a></li>
<li><a href="https://www.journalduhacker.net/s/wtwgqu/generer_des_qr_code_depuis_votre_terminal">Générer des QR Code depuis votre terminal</a></li>
<li><a href="https://www.journalduhacker.net/s/pfiiux/ssh_port_forwarding_par_l_exemple">SSH Port forwarding par l’exemple</a></li>
<li><a href="https://www.journalduhacker.net/s/fdiux3/cr_er_un_revenu_passif_gr_ce_l_open_source">Créer un revenu passif grâce à l’open source</a></li>
<li><a href="https://www.journalduhacker.net/s/vuhomv/une_introduction_vector">Une introduction à Vector</a></li>
</ul><p>Pour ne plus rater aucun article de la communauté francophone, voici :</p>

<ul><li><a href="https://www.journalduhacker.net/rss">Le flux RSS du Journal du hacker</a></li>
<li><a href="https://framasphere.org/u/journalduhacker">Le compte Diaspora* du Journal du hacker</a></li>
<li><a href="https://framapiaf.org/@journalduhacker">Le compte Mastodon du Journal du hacker</a></li>
</ul><p>De plus le site web du Journal du hacker est « adaptatif (responsive) ». N’hésitez pas à le consulter depuis votre smartphone ou votre tablette !</p>

<p>Le Journal du hacker fonctionne de manière collaborative, grâce à la participation de ses membres. <a href="https://www.journalduhacker.net/invitations/request">Rejoignez-nous</a> pour proposer vos contenus à partager avec la communauté du Logiciel Libre francophone et faire connaître vos projets !</p>

<p><strong>Et vous ? Qu’avez-vous pensé de ces articles ?</strong> N’hésitez pas à réagir directement dans les commentaires de l’article sur le Journal du hacker :)</p>
<p><img src="media/ffe97a17.7916ee3cafa0bc3e9583bedad876dcd5" data-original-source="http://cdn.libravatar.org/avatar/7916ee3cafa0bc3e9583bedad876dcd5" alt="Gravatar de Journal du hacker" class="gravatar" /><br/><i>Original post of <a href="https://blog.journalduhacker.net/index.php?article305/liens-interessants-journal-du-hacker-semaine-53-2020" title="Visit the source">Journal du hacker</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://miamondo.org/2021/01/01/dwservice-une-application-de-telemaintenance-originaire-destonie/
title: miamondo : DWService, une application de télémaintenance originaire d’Estonie
uri: miamondo-DWService-une-application-de-télémaintenance-originaire
url: https://miamondo.org/2021/01/01/dwservice-une-application-de-telemaintenance-originaire-destonie/
content:
<p><strong>DWService est une application de télémaintenance qui nous vient d’Estonie. C’est une alternative libre à TeamViewer. Elle permet entre autre de prendre le contrôle d’un ordinateur à distance.</strong></p>



<hr><span></span>



<p>Il y a quelques mois, j’ai découvert qu’il existait une alternative libre et open source à <strong><a href="https://www.teamviewer.com/fr/">TeamViewer</a></strong>. Ce n’est pas que je me sers de ce genre d’outils tous les jours mais il m’arrive parfois de devoir dépanner à distance, l’ordinateur d’un membre de ma famille ou d’un ami.</p>



<p><a href="https://www.dwservice.net/">DWService</a> est une application qui nous vient d’Estonie, un petit pays assez singulier puisqu’il s’est converti au tout numérique quelques années après son indépendance obtenue en 1991. Aujourd’hui, <strong><a rel="noreferrer noopener" href="https://www.challenges.fr/monde/europe/l-estonie-modele-d-un-etat-tout-numerique_657786" target="_blank">l</a><a href="https://www.challenges.fr/monde/europe/l-estonie-modele-d-un-etat-tout-numerique_657786">‘Estonie est ultra-connectée</a></strong>, à tel point qu’il serait plus judicieux de parler d’elle en utilisant le vocable <em>e-stonie</em>. Pourtant, tout n’est pas parfait dans ce choix d’une société digitalisée à l’extrême. Il y a toujours un risque que les informations numériques des citoyens estoniens soient interceptées par des pirates informatiques, ou exploitées par un régime autoritaire qui réussirait à prendre le pouvoir. Cela reste toutefois une expérience digne d’intérêt et qui a inspiré d’autres pays. Sachez également que l’Estonie rémunère des hackeurs pour tester la résistance de sa forteresse numérique et corriger les failles de sécurité éventuelles. Il faut juste qu’un <strong><a href="https://fr.wikipedia.org/wiki/Orage_magn%C3%A9tique">orage magnétique</a></strong> ne frappe pas cette petite nation, sans quoi c’est retour direct à l’âge de pierre. Et par les temps qui courent, on sait que science-fiction et réalité peuvent se confondre…</p>



<div><figure><img data-attachment-id="1234" data-permalink="https://miamondo.org/en-map/" data-orig-file="https://miamondo96030527.files.wordpress.com/2021/01/en-map.jpg" data-orig-size="328,351" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="en-map" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2021/01/en-map.jpg?w=280" data-large-file="https://miamondo96030527.files.wordpress.com/2021/01/en-map.jpg?w=328" src="https://miamondo96030527.files.wordpress.com/2021/01/en-map.jpg?w=328" alt="" srcset="https://miamondo96030527.files.wordpress.com/2021/01/en-map.jpg 328w, https://miamondo96030527.files.wordpress.com/2021/01/en-map.jpg?w=140 140w, https://miamondo96030527.files.wordpress.com/2021/01/en-map.jpg?w=280 280w" sizes="(max-width: 328px) 100vw, 328px"><figcaption>L’e-stonie</figcaption></figure></div>



<p>Bref, c’est tout de même avec une certaine confiance que j’ai testé <strong><a rel="noreferrer noopener" href="https://www.dwservice.net/" target="_blank">DWService</a></strong>. Comme je l’ai déjà dit en introduction, il s’agit d’une application qui permet de prendre le contrôle d’un autre ordinateur à distance et ceci, quel que soit son système d’exploitation (<em>Linux</em>, <em>Windows 10</em> ou <em>Apple</em>). Mais ce qui fait la particularité de DWService par rapport à TeamViewer, c’est que tout se déroule dans le navigateur.</p>



<p>Alors, comment ça fonctionne? Eh bien, ce n’est pas très compliqué. Sur l’ordinateur qui va être « capturé », il faut d’abord se rendre sur la page d’accueil de <strong><a rel="noreferrer noopener" href="https://www.dwservice.net/fr/" target="_blank">DWService</a></strong> avant de télécharger et d’installer <em>dwagent</em>. Si votre système d’exploitation est <strong>Windows 10</strong>, une fois téléchargé, vous allez exécuter un fichier de type <em>*.exe</em>, tandis que si vous tournez sous <strong>Linux</strong>, vous allez lancer ce fichier : <em>./dwagent.sh</em> (évidemment après lui avoir conféré les droits d’exécution: <em>chmod +x ./dwagent.sh</em>). En théorie, si je ne raconte pas de bêtises, l’ordinateur qui prend le contrôle à distance n’est même pas obligé de télécharger le fichier <em>dwagent.sh</em>.</p>



<p>C’est ainsi que j’ai procédé pour tester cette application.</p>



<ul><li>Je n’ai rien installé sur mon ordinateur portable équipé d’<em>Ubuntu 20.10 <s>Coughing Covid</s> Girly Gorilla</em>. C’est lui qui va prendre le contrôle.</li><li>Par contre, j’ai téléchargé et installé l’application sur mon ordinateur de bureau équipé d’Archlinux. C’est lui qui va tenir le rôle du « capturé ». J’ai d’abord créé le répertoire <em>~/.config/dwagent</em> avant d’y télécharger le fichier <em>dwagent.sh</em>. Puis, dans une console, j’ai rendu le fichier exécutable et je l’ai lancé.</li></ul><pre>
mkdir ~/.config/dwagent 
cd ~/.config/dwagent
chmod +x ./dwagent.sh
./dwagent.sh
</pre>


<p>Ensuite, le programme m’a demandé de choisir entre trois possibilités:</p>



<ol><li>Installer</li><li>Exécuter</li><li>Je refuse</li></ol><p>J’ai choisi <strong>exécuter</strong>.</p>



<figure><img data-attachment-id="1235" data-permalink="https://miamondo.org/dws/" data-orig-file="https://miamondo96030527.files.wordpress.com/2021/01/dws.png" data-orig-size="762,500" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="dws" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2021/01/dws.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2021/01/dws.png?w=760" src="https://miamondo96030527.files.wordpress.com/2021/01/dws.png?w=762" alt="" srcset="https://miamondo96030527.files.wordpress.com/2021/01/dws.png 762w, https://miamondo96030527.files.wordpress.com/2021/01/dws.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2021/01/dws.png?w=300 300w" sizes="(max-width: 762px) 100vw, 762px"></figure><p>À la suite de quoi le programme m’a fourni un n° d’identifiant (<em>xxx-xxx-xxx-xxx</em>) et un mot de passe (<em>xxxx</em>). Je suis retourné dans ma cuisine, où j’avais installé mon ordinateur portable. J’ai renseigné ces informations sur le site de DWService, dans la fenêtre intitulée <em>Identifiant</em>.</p>



<figure><img data-attachment-id="1237" data-permalink="https://miamondo.org/dws2/" data-orig-file="https://miamondo96030527.files.wordpress.com/2021/01/dws2.png" data-orig-size="1286,457" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="dws2" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2021/01/dws2.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2021/01/dws2.png?w=760" src="https://miamondo96030527.files.wordpress.com/2021/01/dws2.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2021/01/dws2.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2021/01/dws2.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2021/01/dws2.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2021/01/dws2.png?w=768 768w, https://miamondo96030527.files.wordpress.com/2021/01/dws2.png 1286w" sizes="(max-width: 1024px) 100vw, 1024px"></figure><p>Et après quelques secondes, je me suis retrouvé devant cette fenêtre :</p>



<figure><img loading="lazy" data-attachment-id="1238" data-permalink="https://miamondo.org/dws6/" data-orig-file="https://miamondo96030527.files.wordpress.com/2021/01/dws6-e1609540219153.png" data-orig-size="890,416" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="dws6" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2021/01/dws6-e1609540219153.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2021/01/dws6-e1609540219153.png?w=760" src="media/390ebd8c.dws6-e1609540219153.png" data-original-source="https://miamondo96030527.files.wordpress.com/2021/01/dws6-e1609540219153.png" alt="" width="781" height="535"></figure><p>J’ai cliqué sur <em>écran</em>. Et là, miracle! J’ai vu apparaître le second écran de mon ordinateur de bureau, celui que vous voyez sur l’image ci-dessous:</p>



<figure><img data-attachment-id="1240" data-permalink="https://miamondo.org/dws4/" data-orig-file="https://miamondo96030527.files.wordpress.com/2021/01/dws4.png" data-orig-size="1836,934" data-comments-opened="1" data-image-meta='{"aperture":"0","credit":"","camera":"","caption":"","created_timestamp":"0","copyright":"","focal_length":"0","iso":"0","shutter_speed":"0","title":"","orientation":"0"}' data-image-title="dws4" data-image-description="" data-medium-file="https://miamondo96030527.files.wordpress.com/2021/01/dws4.png?w=300" data-large-file="https://miamondo96030527.files.wordpress.com/2021/01/dws4.png?w=760" src="https://miamondo96030527.files.wordpress.com/2021/01/dws4.png?w=1024" alt="" srcset="https://miamondo96030527.files.wordpress.com/2021/01/dws4.png?w=1024 1024w, https://miamondo96030527.files.wordpress.com/2021/01/dws4.png?w=150 150w, https://miamondo96030527.files.wordpress.com/2021/01/dws4.png?w=300 300w, https://miamondo96030527.files.wordpress.com/2021/01/dws4.png?w=768 768w, https://miamondo96030527.files.wordpress.com/2021/01/dws4.png 1836w" sizes="(max-width: 1024px) 100vw, 1024px"></figure><p>Revenons sur l’image précédente. Vous constatez que vous avez la possibilité d’avoir accès à tous les dossiers et à tous les fichiers. Vous pouvez télécharger ou téléverser ce que vous voulez. Vous avez même une console à votre disposition. Tout ça pour dire qu’il faut avoir pleine confiance en celui qui prend le contrôle de votre ordinateur. S’il est vêtu d’un chandail à capuche rabattue sur une cagoule et qu’il s’exprime avec un accent russe, méfiez-vous quand-même… <strong><a rel="noreferrer noopener" href="https://youtu.be/U8vZNnbkRSc?t=88" target="_blank">C’est un conseil d’ami que je vous donne</a></strong>. Mais bon… Normalement, il s’agit d’un outil pour les administrateurs. Il s’utilise donc principalement dans un cadre professionnel. Ce n’est pas pour faire le mariole.</p>



<p>Pour conclure, il existe d’autres possibilités de se connecter et d’identifier les agents dont vous pouvez prendre le contrôle. Tout est <a rel="noreferrer noopener" href="https://www.dwservice.net/fr/faq.html" target="_blank">expliqué ici</a> mais pas forcément d’une manière limpide, ce qui rend la prise en main de l’application pas toujours intuitive. Attention, DWService ne fonctionne pas avec Wayland. Si vous êtes sur Ubuntu par exemple, au moment d’entrer votre mot de passe, il faut désactiver Wayland ou bien vous débrouiller pour le faire tourner sur Xwayland, qui est une espèce d’entretoise entre X et Wayland.</p>



<p>Voilà… Donc, il est clair pour moi que je vais remplacer TeamViewer par DWService mais simplement pour faire du dépannage à distance. Je n’ai pas forcément envie de transférer des fichiers par ce biais.</p>
<p><img src="media/848c13f4.27be241458674ac3359b0353fdc37c4a" data-original-source="http://cdn.libravatar.org/avatar/27be241458674ac3359b0353fdc37c4a" alt="Gravatar de miamondo" class="gravatar" /><br/><i>Original post of <a href="https://miamondo.org/2021/01/01/dwservice-une-application-de-telemaintenance-originaire-destonie/" title="Visit the source">miamondo</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://carlchenet.com/changez-votre-culture-inefficace-du-teletravail/
title: Carl Chenet : Changez votre culture inefficace du télétravail
uri: Carl-Chenet-Changez-votre-culture-inefficace-du-télétravail
url: https://carlchenet.com/changez-votre-culture-inefficace-du-teletravail/
content:
<p>Ce billet de blog s’adresse aux cadres dirigeants et d’encadrement qui s’étonnent que la culture du télétravail est inefficace dans leur entreprise, mais qui devant leur café chaque matin maugréent que “être sur site, c’est plus efficace” ou “rien ne remplace le contact humain”. Ça fait plus de 10 mois que vos troupes sont à la maison. On se réveille. Car d’autres que vous en profitent déjà.</p>



<h2>Pourquoi cet avertissement ?</h2>



<p>La forme de cet article sera sans doute un peu gênante voire violente pour vous, mais il a des raisons à cela. Vous êtes des grands garçons ou des grandes filles, vous avez une carrière déjà conséquente, on peut vous parler franchement, surtout que vous n’êtes pas visés directement dans un e-mail, ça change du quotidien.</p>



<p>On va commencer par parler du pourquoi vous devez changer votre vision et la culture du télétravail… et vite.</p>



<h2>“C’est une petite grippe, ça va passer en quelques semaines”</h2>



<p>Non. C’est grave, on s’en rend compte de plus en plus chaque jour. À moins de faire courir de graves risques aux collaborateurs et aller contre les préconisations actuelles du gouvernement, ça n’est plus possible.</p>



<p>Donc on oublie la présence au bureau, c’est actuellement plus possible. Et ça pourrait durer tout 2021, jusqu’à 2022, on ne sait pas trop. Oui, faut ouvrir les yeux, si on te dit début 2021, ce sera 2022, faut pas être naïf. Rappelez-vous qu’on vous a dit qu’on serait jamais reconfiné. Bon. Et en plus le virus commence à muter…</p>



<p>Donc à moins de bosser dans un ministère, il va falloir changer tes habitudes de travail, parce que l’excuse du “ça avance pas à cause du télétravail”, ça va finir par vous faire remarquer (au mieux) ou virer (au pire).</p>



<h2>“Moi j’ai toujours bossé comme ça”</h2>



<p>Et ça t’a réussi puisque t’es chef(fe). Bravo.  Mais là, tu peux plus le faire. C’est juste plus possible, parce que même si tu mets ton costume et ton masque chaque jour pour aller enchaîner tes réunions à rallonge au bureau, il n’y a plus personne pour t’écouter. Oui je sais, c’est dur, ça fait un sacré changement. Mais bon, parfois il y a la guerre, parfois une épidémie, qui t’oblige à sortir de la routine de ta vie. Ça se fera avec ou sans toi, à toi de choisir. </p>



<p>Oui c’est violent, je sais, mais ouvre un livre d’histoire et cherche tous les chapitres ce qui commencent par “guerre” tu verras qu’on est pas si mal que ça actuellement, en fait. Et non 2020 n’a pas été la pire année de l’histoire. Très embêtante c’est sûr.</p>



<p>Pour recadrer l’article (on s’enflamme, on s’enflamme), revenons un instant sur ta vision de cadre dirigeant du télétravail.</p>



<p><strong>Soyons clairs, en fait jusqu’ici pour toi le télétravail, c’était pour les mamans le mercredi et pour les feignants le vendredi.</strong></p>



<p>Ta vision du télétravail, c’était un confort accordé gracieusement par l’employeur à l’employé. Tu avais vaguement entendu parler que des boîtes américaines n’avaient plus de bureau depuis des années, mais toi tu es dans une boîte sérieuse, on rigole pas. Dans ta boîte sérieuse, ils ont accordé un jour de télétravail pour l’ajouter également dans les offres d’emploi, parce qu’une offre d’emploi sans télétravail, c’est beaucoup moins sexy depuis cinq ans, surtout si tu veux pécho du développeur. Mais bon, ça reste une connerie pour la génération Y, les femmes et les feignants (dans ta vision).</p>



<figure><img src="media/250ed740.ljfr-teletravail.png" data-original-source="https://carlchenet.com/wp-content/uploads/2021/01/ljfr-teletravail.png" alt="Les offres d'emploi sans culture du télétravail sont moins attractives" srcset="https://carlchenet.com/wp-content/uploads/2021/01/ljfr-teletravail.png 874w, https://carlchenet.com/wp-content/uploads/2021/01/ljfr-teletravail-300x264.png 300w, https://carlchenet.com/wp-content/uploads/2021/01/ljfr-teletravail-768x675.png 768w" sizes="(max-width: 874px) 100vw, 874px"><figcaption><em>Les offres d’emploi sans télétravail sont moins attractives</em></figcaption></figure><h2>“Le contact humain, c’est quand même mieux”</h2>



<p>J’en sais rien, chacun à son avis, on est pas là pour en discuter. Ce qui est sûr, c’est que c’est plus possible puisque, par la situation qui s’impose à nous, il faut justement éviter le contact humain. </p>



<p>Tu peux continuer à t’arc-bouter à ton contact humain, mais en attendant, tes employés s’échangent des conneries toute la journée via la messagerie instantanée. Ils se font des “standups” chaque matin en appel audio pour faire le point sur les projets en cours et s’appellent en direct pour résoudre les problèmes urgents. Ils font grossir la documentation de l’entreprise en éditant des documents partagés… En fait ils mettent en place de fait une culture du télétravail dans ton entreprise.</p>



<h2>“C’est plus difficile de communiquer”</h2>



<p>Chacun sa vision de la communication. Mais encore une fois, si ça se limite à parler à quelqu’un face-à-face, oublie, ça n’est plus possible. Fais ton deuil et passe à autre chose. Tu ne peux pas limiter la culture du télétravail de ton entreprise à ta propre expérience, surtout si jusque là tu ne l’avais pas pratiqué.</p>



<p>Heureusement pour nous, des magnifiques outils sont aujourd’hui disponibles pour télétravailler :</p>



<ul><li>documents partagées</li><li>messagerie instantanée</li><li>visioconférence</li><li>téléphone</li><li>E-mails d’entreprises</li><li>…</li></ul><p>Ces outils n’ont jamais été aussi efficace. Il y a trente ans, on aurait eu que le téléphone… Donc, il est temps d’arrêter de se plaindre et de commencer à s’en servir. Pour information d’autres boîtes s’en servent depuis 10 ans.</p>



<h2>“Personne branle rien parce que je les vois pas bosser”</h2>



<p>Allez, on va pas se mentir, ça, c’est le paramètre qui fait te littéralement FLIPPER.</p>



<p>Sisi, faut le reconnaître (tu peux, on est entre nous), tu ne sais pas comment évaluer le travail de tes collaborateurs en télétravail. Forcément, vu que tu ne sais pas comment ça marche et que surtout jusqu’ici, tu ne voulais pas le savoir. Et donc bien sûr, t’as essayé d’attendre que ça passe, en se disant que de toute façon, tout le monde était comme toi.</p>



<p>Mais là, ça ne se passe pas. Et les projets que tu n’as pas gérés prennent du retard. Tu charges le télétravail, la situation, le covid, tes subordonnés, mais bon, tout le monde est logé à la même enseigne. Ça va donc finir par te retomber dessus, car sauf si tu as beaucoup de chance, tu n’es pas payé à rien faire et tes propres chefs attendent des résultats.</p>



<p>Peut-être qu’aussi la vraie raison, c’est que tu ne peux plus <a href="https://carlchenet.com/le-micromanagement/">micromanager,</a> c’est-à-dire te mettre derrière des salariés intelligents et compétents pour leur dire comment faire leur métier toutes les deux minutes et passer ta journée à faire semblant de travailler comme ça en t’étonnant qu’ils n’avancent pas. Là, c’est sûr, le télétravail va te poser un problème.</p>



<h2>Vous allez faire quoi ?</h2>



<p> Maintenant ce qui est important, c’est de savoir ce que vous, cadres dirigeants et encadrants, vous allez faire ? Vous allez continuer à pleurer avec le motto “c’était mieux avant” et tenter d’attendre que ça passe rapidement (on a vu que c’était mort) ou vous allez commencer à télétravailler, réellement ?</p>



<p>Vous êtes convaincus ? vous avez envie de changer ? Bien, dans ce cas, nous verrons dans le prochain articles quelques points intéressantes pour vous.</p>



<h2>L’auteur</h2>



<p><a href="https://twitter.com/carl_chenet">Carl Chenet</a>, architecte de systèmes informatiques indépendant (en recherche de mission à partir de janvier 2021), 3 ans de télétravail régulier, entrepreneur.</p>



<p>Fondateur de l’agrégateur <a href="https://www.journalduhacker.net/">Le Journal du hacker</a>, du site d’emploi <a href="https://www.linuxjobs.fr/">LinuxJobs.fr</a> et de la newsletter <a href="https://lecourrierduhacker.com/">Le Courrier du hacker</a>. Modérateur sur <a href="https://lechantier.co/">le Chantier</a>, lieu virtuel (Discord, forum) d’échanges d’entrepreneurs francophones.</p>



<h2>Me suivre sur les réseaux sociaux</h2>



<p>N’hésitez pas à me suivre directement sur les différents sociaux pour
  suivre au jour le jour mes différentes projets dans le Logiciel Libre 
et/ou pour me contacter :</p>



<ul><li><strong>Mastodon</strong> : <a href="https://mastodon.social/@carlchenet">@carlchenet</a></li><li><strong>Diaspora</strong> :  <a href="https://framasphere.org/u/carlchenet">@carlchenet</a></li><li><strong>Twitter</strong> : <a href="https://twitter.com/carl_chenet">@carl_chenet</a></li></ul><p>The post <a rel="nofollow" href="https://carlchenet.com/changez-votre-culture-inefficace-du-teletravail/">Changez votre culture inefficace du télétravail</a> appeared first on <a rel="nofollow" href="https://carlchenet.com/">Carl Chenet's Blog</a>.</p>
<p><img src="media/46f73009.e1f1addc890668ce2561431b7be810bc" data-original-source="http://cdn.libravatar.org/avatar/e1f1addc890668ce2561431b7be810bc" alt="Gravatar de Carl Chenet" class="gravatar" /><br/><i>Original post of <a href="https://carlchenet.com/changez-votre-culture-inefficace-du-teletravail/" title="Visit the source">Carl Chenet</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Carl Chenet : <a href="">Migration de Feed2tweet de la 1.0 vers la 1.1</a> (25/04/2017)</li><li>Carl Chenet : <a href="">&Eacute;dito de mai 2017</a> (03/05/2017)</li><li>Carl Chenet : <a href="">De l&rsquo;importance de bien choisir son instance Mastodon</a> (15/05/2017)</li><li>Carl Chenet : <a href="">Booster automatiquement les toots int&eacute;ressants de Mastodon avec le bot Boost</a> (17/05/2017)</li><li>Carl Chenet : <a href="">&Eacute;dito de juillet 2017</a> (13/07/2017)</li></ul></div></p>


feed_id: http://eddy33.eddy33.free.fr/weblog/index.php?post/2021/01/04/AMC-version-1.4.0-Fedora-33
title: Eddy33 : AMC version 1.4.0 Fedora 33
uri: Eddy33-AMC-version-1-4-0-Fedora-33
url: http://eddy33.eddy33.free.fr/weblog/index.php?post/2021/01/04/AMC-version-1.4.0-Fedora-33
content:
<div><p>Les RPM d'<a href="https://www.auto-multiple-choice.net/index.fr">AMC</a> (Auto Multiple Choice) 
version 1.4.0 pour Fedora 33 sont disponibles dans le dépôt eddy33.</p>
</div><br><p>Installation :</p>
<pre>$ sudo dnf install perl-Gtk3 perl-Clone<br>$ sudo dnf install http://kadionik.vvv.enseirb-matmeca.fr/fedora/eddy33-release-33.rpm <br>$ sudo dnf install auto-multiple-choice</pre><div>Attention. AMC utilise openCV. Fedora 33 est basé sur openCV 4.3 qui nécessite le support par le processeur de l'extension AVX2.</div><div><br>++</div>
<p><img src="media/889f4f2a.d1430102ed05bb1a49902c819454fef2" data-original-source="http://cdn.libravatar.org/avatar/d1430102ed05bb1a49902c819454fef2" alt="Gravatar de Eddy33" class="gravatar" /><br/><i>Original post of <a href="http://eddy33.eddy33.free.fr/weblog/index.php?post/2021/01/04/AMC-version-1.4.0-Fedora-33" title="Visit the source">Eddy33</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>
<p><div class="similar-block"><h3>Articles similaires</h3><ul><li>Eddy33 : <a href="">AMC version 1.4.0 Fedora 31</a> (23/12/2019)</li><li>Eddy33 : <a href="">AMC version 1.4.0 Fedora 32</a> (22/06/2020)</li><li>Eddy33 : <a href="">Cr&eacute;ation du d&eacute;p&ocirc;t Fedora eddy33</a> (07/01/2017)</li><li>Eddy33 : <a href="">Fedora 33 vs Fedora 32 : comparaison des performances pour les versions 64 bits</a> (28/12/2020)</li><li>TitaX : <a href="">Fedora 12 version alpha</a> (26/08/2009)</li></ul></div></p>


feed_id: https://www.citizenz.info/articles/git-github-aide-memoire-pour-les-nuls
title: citizenz7 : GIT / GITHUB : aide-mémoire pour "les nuls"
uri: citizenz7-GIT-GITHUB-aide-mémoire-pour-les-nuls
url: https://www.citizenz.info/articles/git-github-aide-memoire-pour-les-nuls
content:
git-github-aide-memoire-pour-les-nuls
<p><img src="media/81133586.d3d22ade032c891f4b97588788975fc6" data-original-source="http://cdn.libravatar.org/avatar/d3d22ade032c891f4b97588788975fc6" alt="Gravatar de citizenz7" class="gravatar" /><br/><i>Original post of <a href="https://www.citizenz.info/articles/git-github-aide-memoire-pour-les-nuls" title="Visit the source">citizenz7</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


feed_id: https://blog.genma.fr/?Lifehacking-Creation-de-tickets-dans-le-Kanban-Gitlab-via-l-API
title: genma : Lifehacking - Création de tickets dans le Kanban Gitlab via l'API
uri: genma-Lifehacking-Création-de-tickets-dans-le-Kanban-Gitlab-via-l
url: https://blog.genma.fr/?Lifehacking-Creation-de-tickets-dans-le-Kanban-Gitlab-via-l-API
content:
<img alt="" src="https://blog.genma.fr/IMG/arton2933.jpg?1609418334" width="150" height="79"><div><p><strong>Introduction</strong></p>
<p>Il y a quelques années, je me suis initié à l'usage du Kanban (<a href="https://blog.genma.fr/?Lifehacking-Kanban" title="Lifehacking - Kanban">Lifehacking - Kanban</a>) et j'ai utilisé pour de nombreux projets et suivi d'actions des Kanbans au sein de Gitlab (<a href="https://blog.genma.fr/?Lifehacking-Gitlab-outil-ideal" title="Lifehacking - Gitlab, outil idéal ?">Lifehacking - Gitlab, outil idéal ?</a>). Je continue d'utiliser le Kanban Gitlab : j'ai mes habitudes, je forme les personnes avec lesquelles je travaille sur les procédures et bonnes pratiques que j'ai mises en place sur les rédactions des tickets et leurs vie (suivi /traçabilité...).</p>
<p>Je me suis demandé comment il serait possible d'automatiser <i>certaines choses</i> dans l'usage du Kanban de Gitlab. Si vous utilisez Gitlab au quotidien, vous serez peut-être intéressés par son API. Elle vous permet, au travers de scripts dans le langage de votre choix, d'exécuter certaines tâches en lignes de commandes.</p>
<p>J'ai demandé à Brume, qui est en stage avec moi, de rédiger le présent billet de tutoriel de création de tickets dans le Kanban Gitlab via l'API de Gitlab. Voici donc le tutoriel.</p>
<p><strong>Les Kanbans dans Gitlab ?</strong></p>
<p>A chaque projet dans Gitlab est associé un Kanban permettant la gestion du projet. L'objectif n'est pas de présenter l'usage de ce Kanban (qui est assez intuitif mais aussi assez riche en fonctionnalités et complet).</p>
<p><strong>Tutoriel de l'API de GitLab</strong></p>
<p>L'API de Gitlab est une API REST. Elle fournit des fichiers JSON accessibles par liens, ainsi que la possibilité de réaliser des actions en donnant des paramètres GET, POST... : après le lien, vous pouvez rajouter ?argument=value.</p>
<p>Dans le navigateur, il n'y en a pas besoin, mais avec Curl, les requêtes doivent être suivies par ?access_token=<token> ou précédées par —header "PRIVATE-TOKEN : <token>".</token></token></p>
<p><strong>Accéder aux fichiers JSON issu d'un Kanban</strong></p>
<p>Les requêtes suivantes sont uniquement des requêtes GET, il est donc possible de soit les ouvrir dans un navigateur soit avec Curl.</p>
<p>Pages d'un projet : <a href="https://gitlab-exemple.com/api/v4/projects/nom_du_projet" rel="nofollow external">https://gitlab-exemple.com/api/v4/projects/nom_du_projet</a></p>
<p>Chaque / entre le nom du mainteneur et le nom du projet doivent être remplacés par %2F. Remarquez également que /projects/ a été rajouté comparé au lien d'origine.</p>
<p>Boards (le Kanban) : <a href="https://gitlab-exemple.com/api/v4/projects/9/boards/2" rel="nofollow external">https://gitlab-exemple.com/api/v4/projects/9/boards/2</a></p>
<p>Le nom du projet est remplacé par son ID, ici 9. 2 correspond à l'ID du board que nous voulons regarder. Les boards sont seulement des filtres de tickets, proposant un rendu plus visuel et qui permet de trouver les informations facilement. Accéder à un board via l'API ne permet que de voir la liste des filtres par label.</p>
<p>Tickets <a href="https://gitlab-exemple.com/api/v4/projects/9/issues" rel="nofollow external">https://gitlab-exemple.com/api/v4/projects/9/issues</a></p>
<p>Il existe beaucoup d'arguments GET pour filter les tickets. Par exemple, pour filtrer les tickets par label, utilisez le l'argument labels=value (vous pouvrez ajouter plusieurs labels en les séparant par des virgules).</p>
<p><strong>Actions via des requêtes sur les tickets</strong></p>
<p>Les requêtes suivantes utilisent d'autre paramètres que GET. Le plus avisé est donc d'utiliser Curl.</p>
<p><strong>Créer un ticket</strong></p>
<div dir="ltr"><code>curl --request POST --header "PRIVATE-TOKEN: <token>" "https://gitlab-exemple.com/api/v4/projects/13/issues?&amp;title=A%20Title&amp;labels=To%20Do&amp;description=test"</token></code></div>
<p>Vous pouvez constater ici qu'il y a trois arguments : title, labels et description. Seul le titre est obligatoire. Il existe de nombreuses possibilités. Remarquez que les espaces doivent être remplacés par %20, sinon vous optiendrez une erreur 400.</p>
<p><strong>Supprimer un ticket</strong></p>
<div dir="ltr"><code>curl --request DELETE --header "PRIVATE-TOKEN: <token>" "https://gitlab-exemple.com/api/v4/projects/13/issues/2"</token></code></div>
<p>2 est l'IID (internal ID) du ticket que nous voulons supprimer. Vous pouvez l'obtenir dans la liste des tickets (ils sont triés par ordre de création).</p>
<p><strong>Éditer un ticket</strong></p>
<div dir="ltr"><code>curl --request PUT --header "PRIVATE-TOKEN: <token>" "https://gitlab-exemple.com/api/v4/projects/13/issues/6?title=Title%20Changed&amp;add_labels=AAA,BBB,changed"</token></code></div>
<p>Il existe beaucoup d'arguments pour éditer des tickets, comme :
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> add_label, remove_labels et labels pour ajouter, supprimer ou réécrire entièrement la liste des labels ;
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> title, description pour ajouter un titre ou une description ;
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> state_event=closed ou reopen pour fermer ou réouvrir un ticket.</p>
<p><strong>Un script d'exemple, en Python</strong></p>
<p>Nous allons proposer et expliquer un script d'exemple, en Python, d'utilisation de cette API. Ce script permettra, pour un projet donné, de publier, éditer ou supprimer des issues.</p>
<p><strong>Prérequis</strong></p>
<p>Pour suivre cet exemple, vous aurez besoin de :
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> avoir Python 3 installé sur votre machine ;
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> avoir un compte sur une instance GitLab ;
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> créer un projet sur votre compte GitLab ;
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> créér un token d'accès (décrit ci-dessous).</p>
<p><strong>Se créer un token d'accès</strong><br>
Sur Gitlab, allez dans les paramètres de votre compte utilisateur. Allez dans l'onglet "Access Token". Entrez un nom, cochez au moins la case "api", et validez. Vous recevrez votre token. Pensez à le stocker, car il ne sera plus accessible par la suite et vous serez obligés de vous en re-créer un.</p>
<p><strong>Bibliothèques utilisées</strong></p>
<p><strong>Requests</strong> est une bibliothèque qui permet de faire des requêtes HTML en Python, à la manière de Curl en Bash.</p>
<p><strong>Utilisation :</strong></p>
<div dir="ltr"><code>import requests<br> headers = {'PRIVATE-TOKEN': "YOUR-TOKEN"}<br> r = requests.get(link, headers=headers)</code></div>
<p><strong>link</strong> est le lien de la page que l'on souhaite récupérer, `YOUR-TOKEN` votre token secret, et `get` le type de la requête. Il est possible d'utiliser d'autre paramètres comme `delete`, `post`, `put`...</p>
<p><strong>r</strong> est un objet, contenant notamment : <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> le code de retour de la requête, `r.status_code` ;
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> le texte (du json dans notre cas) récupéré, `r.text`.</p>
<p><strong>Json</strong> permet tout simplement de parser et de récupérer des informations dans des JSON.</p>
<p><strong>Utilisation :</strong></p>
<div dir="ltr"><code>import json<br> file = json.loads(file)<br> print(json[0]["username"])</code></div>
<p><strong>file</strong> est le fichier ou texte que l'on veut utiliser, dans notre cas `r.text`. Il est possible d'extraire les éléments du json par clés ou index, comme dans l'exemple.</p>
<p><strong>ConfigParser</strong> permet de lire un fichier de configuration dans un fichier `.ini`, et d'ajouter les valeurs à notre code.</p>
<p><strong>Utilisation : </strong></p>
<div dir="ltr"><code>from configparser import ConfigParser<br> cfg = ConfigParser()<br> cfg.read('config.ini')<br> variable = cfg.get("section", "variable")</code></div>
<p>Attention à bien vérifier que le fichier existe et que toutes les valeurs sont présentes à l'intérieur, pour éviter tout dysfonctionnement.</p>
<p>En premier, un objet `ConfigParser` est initialisé. Ensuite, on lui donne le fichier de configuration à lire, ici `config.ini`. Ce fichier utilise la syntaxe suivante :</p>
<div dir="ltr"><code>[section]<br> variable=valeur</code></div>
<p>Il est possible de rajouter autant de variables et de sections que l'on veut (avec des noms différents). <br>
Pour récupérer la valeur d'une variable, on utilise donc `cfg.get`, en précisant la section et la variable.</p>
<p>Dans notre cas, utiliser un fichier de configuration est utile pour que l'utilisateur puisse renseigner une fois mais pas à chaque fois le lien de l'instance Gitlab, l'id de son projet et son token d'accès.</p>
<p><strong>Urllib</strong></p>
<p>`urllib` permet de remplacer tous les caractères spéciaux d'une chaîne de caractères, pour n'utiliser que des caractères autorisés dans les liens. Par exemple, les espaces ne sont pas autorisés, donc ils seront remplacés par `%20`. Certains caractères ont également une signification dans le lien (comme `&amp;`, qui lie deux paramètres. Les remplacer permet d'éviter toute mauvaise interprétation de l'entrée de l'utilisateur.</p>
<p><strong>Utilisation :</strong></p>
<div dir="ltr"><code>import urllib.parse<br> variable = urllib.parse.quote("Titre de mon issue"), safe='')</code></div>
<p>Ici, `Titre de mon issue` deviendra `Titre%20de%20mon%issue`. Par défaut, `urllib.parse.quote` remplace tous les caractères spéciaux sauf le `/`. Nous souhaitons que ce caractère soit aussi remplacé, pour le fonctionnement de notre requête, alors nous rajoutons `safe=''` pour indiquer que même le `/` n'est pas un caractère sécurisé.</p>
<p>En plus de ces 4 bibliothèques, `datetime` et `os.path` on été utilisées, mais ne sont pas fondamentalement nécessaires dans la création d'un script autour de l'API de Gitlab.</p>
<p><strong>Utilisation de l'API de Gitlab</strong></p>
<p>Notre script Python va tout d'abord proposer un choix multiple, où l'utilisateur entrera un chiffre pour accéder aux fonctionnalités suivantes :
<br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> créer une issue, <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> modifier une issue, <br><img src="https://blog.genma.fr/local/cache-vignettes/L8xH11/puce-32883.gif?1548171627" width="8" height="11" alt="-"> supprimer une issue.</p>
<p>À chacune de ces actions est liée une fonction utilisant l'API de Gitlab.</p>
<p>Pour accéder à cette API, il faut rajouter `/api/v4/` à la fin de l'url de votre instance Gitlab. Dans les requêtes suivantes, nous utiliserons `<a href="https://gitlab-exemple.com%60/" rel="nofollow external">https://gitlab-exemple.com`</a> en exemple. Cela donne donc :</p>
<div dir="ltr"><code>https://gitlab-exemple.com/api/v4/</code></div>
<p>Pour envoyer vos requêtes, vous pouvez utiliser la bibliothèque `requests` présentée au-dessus. Pensez bien à utiliser la bibliothèque `urllib` pour sécuriser et formater les entrées des utilisateurs que vous allez rajouter à vos liens.</p>
<p><strong>Créer une issue</strong></p>
<p>Pour créer une nouvelle issue, il faut utiliser la requête suivante :</p>
<div dir="ltr"><code>POST https://gitlab-exemple.com/api/v4/projects/ID/issues/?title=TITRE&amp;labels=LABEL1,LABEL2&amp;description=DESCRIPTION</code></div>
<p>Ici, `ID` est à remplacer par l'ID du projet. Nous utilisons les arguments `title`, `labels` et `description`. Il en existe beaucoup d'autres, et seul `title` est obligatoire. `TITRE`, `LABEL1,LABEL2`, `DESCRIPTION` sont donc à remplacer par vos propres valeurs.</p>
<p>La liste des arguments est disponible [ici](<a href="https://docs.gitlab.com/ee/api/issues.html#new-issue" rel="nofollow external">https://docs.gitlab.com/ee/api/issues.html#new-issue</a>).</p>
<p><strong>Modifier une issue</strong></p>
<p>Pour modifier une issue, il faut utiliser la requête suivante :</p>
<div dir="ltr"><code>PUT https://gitlab-exemple.com/api/v4/projects/ID/issues/IID/?title=TITRE&amp;labels=LABEL1,LABEL2&amp;description=DESCRIPTION</code></div>
<p>Ici, `IID` est à remplacer par l'ID interne de l'issue. Le reste de la requête est semblable à la première.</p>
<p>Encore une fois, il existe de [nombreux arguments](<a href="https://docs.gitlab.com/ee/api/issues.html#edit-issue" rel="nofollow external">https://docs.gitlab.com/ee/api/issues.html#edit-issue</a>), pour modifier plein de détails comme le statut de l'issue, sa date d'échéance...</p>
<p><strong>Supprimer une issue</strong></p>
<p>Pour supprimer une issue, il faut utiliser la requête suivante :</p>
<div dir="ltr"><code>DELETE https://gitlab-exemple.com/api/v4/projects/ID/issues/IID/</code></div>
<p><strong>Récupérer des informations de l'API</strong></p>
<p>L'API ne sert pas qu'à faire des actions, mais aussi à récupérer des informations. Voici quelques exemples :</p>
<p><strongr la liste des projets :></strongr></p>
<div dir="ltr"><code>https://gitlab-exemple.com/api/v4/projects/NOM-DU-PROJET</code></div>
<p><strongr des informations sur un projet pr :></strongr></p>
<div dir="ltr"><code>https://gitlab-exemple.com/api/v4/projects/ID-DU-PROJET</code></div>
<p><strong>Récupérer la liste des issues d'un projet :</strong></p>
<div dir="ltr"><code>https://gitlab-exemple.com/api/v4/projects/ID-DU-PROJET</code></div>
<p>À chaque fois, vous récupérerez un JSON à parser avec la librairie JSON présentée plus haut.</p>
<p><strong>Script en Python utilisant l'API de Gitlab permettant de créer, modifier et supprimer des issues en ligne de commande.</strong></p>
<p>Pour lancer le script, remplissez le fichier `config.ini` avec l'url de votre instance Gitlab, l'id de votre projet et votre token (générable depuis les paramètres utilisateurs), puis lancez :</p>
<div dir="ltr"><code>./gitlab-cli.py</code></div>
<p><strong>Contenu du fichier config.ini</strong></p>
<div dir="ltr"><code>[configuration]<br> baselink=<your gitlab instance url><br> project=<project><br> access_token=<your token></your></project></your></code></div>
<p><strong>Code source du script ./gitlab-cli.py</strong></p>
<div dir="ltr"><code>#!/usr/bin/env python3<br><br> ### BIBLIOTHÈQUES ###<br><br> import requests<br> import json<br> from configparser import ConfigParser <br> from datetime import datetime<br> import os.path<br> import urllib.parse<br><br> ### COULEURS DE TEXTE ###<br><br> NC = "\\033[0m"<br> LB = "\\033[38;5;33m"<br> RED = "\\033[1;38;5;196m"<br> CY="\\033[38;5;81m"<br><br> ### FONCTIONS ###<br><br> # Ajouter des labels<br> def lab_add():<br> labels = urllib.parse.quote(input("Please enter the labels you want to add: "), safe='')<br> if labels:<br> labels = "&amp;add_labels={}".format(labels)<br> return labels<br><br> # Effacer des labels<br> def lab_delete():<br> labels = urllib.parse.quote(input("Please enter the labels you want to delete: "), safe='')<br> if labels:<br> labels = "&amp;remove_labels={}".format(labels)<br> return labels<br><br> # Réécrire la liste des labels<br> def lab_rewrite():<br> labels = urllib.parse.quote(input("Please enter the new labels: "), safe='')<br> if labels:<br> labels = "&amp;labels={}".format(labels)<br> return labels<br><br> def lab_keep():<br> return ""<br><br> # Fonction permettant de réaliser des choix multiples<br> def multiple_choice(choices):<br> value = 0<br> while value  len(choices) :<br> try: <br> value = int(input("Enter a number: "))<br> except ValueError:<br> default()<br> continue<br> result = choices.get(value,default)()<br> return result<br><br> # Imprime les détails d'un ticket<br> def print_issue(link):<br> r = requests.get(link, headers=headers)<br> if r.status_code >= 400:<br> return 0<br> json_r = r.text<br> json_tk = json.loads(json_r)<br> date = datetime.strptime(json_tk["created_at"], "%Y-%m-%dT%H:%M:%S.%fZ")<br> date = datetime.strftime(date, "%Hh%M the %d %B %Y")<br> print("\\n{}Issue #{}{}{:>30} {}, at {}".format(LB, json_tk["iid"], NC, "Created by", json_tk["author"]["username"], date))<br> print("{}Title{}: {}".format(CY, NC, json_tk["title"]))<br> print("{}Description{}: {}".format(CY, NC, json_tk["description"]))<br> print("{}Labels{}: {}\\n".format(CY, NC, json_tk["labels"]))<br> return 1<br><br> # Imprime la liste des tickets<br> def print_list(link):<br> print("\\nList of issues:")<br> r = requests.get(link, headers=headers)<br> if r.status_code >= 400:<br> return 0<br> json_r = r.text<br> json_list = json.loads(json_r)<br> for issue in json_list:<br> print("#{}\\t{}".format(issue["iid"], issue["title"]))<br><br> # confirmer le choix du ticket. Fonction utilisée pour éditer et supprimer.<br> # Paramêtres : le lien du ticket et l'action à faire (dialogues)<br> def confirm_issue(link, action):<br> print_list(link)<br> iid = 0<br> code = 0<br> while iid  boolean = "a"<br> try:<br> iid = int(input("\\nPlease enter the id of the issue you want to {}: ".format(action)))<br> except ValueError:<br> default()<br> continue<br> link_id = "{}{}".format(link, iid)<br> code = print_issue(link_id)<br> if not code :<br> print("{}Error:{} This issue doesn't exists. Please try again.".format(RED, NC))<br> continue<br> while boolean != "y" and boolean != "n":<br> boolean = input("Is it this ticket that you want to {}? (y/n) ".format(action))<br> return link_id<br><br><br><br> # Erreur avec l'API<br> def error_api(verb):<br> print("\\n{}Error:{} The issue has not been {}. Please verify that informations in 'config.ini' are valid.".format(RED, NC, verb))<br> exit(0)<br><br> # créer un ticket<br> def gl_create():<br> title = ""<br> while not title:<br> title = urllib.parse.quote(input("Please enter the title of your new issue (must not be empty) : ").strip(), safe='')<br> if not title:<br> print("{}Error:{} Title must not be empty. Please try again.".format(RED, NC))<br> desc = urllib.parse.quote(input("Please enter the description: "), safe='')<br> labels = urllib.parse.quote(input("Please enter labels, separated by commas: "), safe='')<br> link = "{}/issues?&amp;title={}&amp;labels={}&amp;description={}".format(baselink, title, labels, desc)<br> try:<br> r = requests.post(link, headers=headers)<br> if r.status_code >= 400:<br> error_api("created")<br> print("Issue created!")<br> except: <br> error_api("created")<br><br> # éditer un ticket<br> def gl_edit():<br> link = "{}/issues/".format(baselink)<br> link = confirm_issue(link, "edit")<br> title = urllib.parse.quote(input("Please enter the new title (leave empty to change nothing): "), safe='')<br> desc = urllib.parse.quote(input("Please enter the new description (leave empty to change nothing): "), safe='')<br> if title: <br> title = "&amp;title={}".format(title)<br> if desc:<br> desc = "&amp;description={}".format(desc)<br> # menu des labels<br> print("\\nDo you want to:\\n{}1){} Add some labels\\t\\t{}2){} Delete some labels\\n{}3){} Rewrite all labels\\t\\t{}4){} Keep labels unchanged".format(LB, NC, LB, NC, LB, NC, LB, NC))<br><br> choices = {<br> 1 : lab_add,<br> 2 : lab_delete,<br> 3 : lab_rewrite,<br> 4 : lab_keep,<br> }<br> labels = multiple_choice(choices)<br> link = "{}/?{}{}{}".format(link, title, desc, labels)<br> try:<br> r = requests.put(link, headers=headers)<br> if r.status_code >= 400:<br> error_api("updated")<br> print("The issue had been updated, thank you!")<br> except: <br> error_api("updated")<br><br> # effacer un ticket<br> def gl_delete():<br> link = "{}/issues/".format(baselink)<br> link = confirm_issue(link, "delete")<br> try:<br> r = requests.delete(link, headers=headers)<br> if r.status_code >= 400:<br> error_api("deleted")<br> print("The issue had been deleted, thank you!")<br> except: <br> error_api("deleted")<br><br> def default():<br> print("{}Error:{} Wrong answer. Please try again.".format(RED, NC))<br><br><br> ### MAIN ###<br><br> # effacer l'écran<br> print('\\033[2J')<br><br> if not os.path.isfile('config.ini'):<br> print("{}Error:{} config.ini file not found.".format(RED, NC))<br> exit(0)<br><br> # utilisation de config.ini<br> cfg = ConfigParser() <br> cfg.read('config.ini')<br> try:<br> baselink = "{}/api/v4/projects/{}".format(cfg.get("configuration", "baselink"), cfg.get("configuration", "project"))<br> headers = {'PRIVATE-TOKEN': cfg.get("configuration", "access_token")}<br> except: <br> print("{}Error:{} config.ini is incomplete. Please check that 'baselink', 'project' and 'access_token' fields exists.".format(RED, NC))<br> exit(0)<br><br> # premier menu<br> print("Hello! What do you want to do?\\n\\n{}1){} Create an issue\\t\\t{}2){} Edit an issue\\n{}3){} Delete an issue".format(LB, NC, LB, NC, LB, NC))<br><br> # dictionnaire des choix possibles<br> choices = {<br> 1 : gl_create,<br> 2 : gl_edit,<br> 3 : gl_delete,<br> }<br> # interception du ^C<br> try:<br> multiple_choice(choices)<br> except (KeyboardInterrupt, SystemExit):<br> print("\\nGoodbye!")<br> exit(0)</code></div>
<p><strong>Captures d'écrans de l'exécution du script</strong></p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/script_gitlab_2.png?1609418417" width="500" height="147" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/script_gitlab_3.png?1609418420" width="500" height="281" alt=""></span></p>
<p><span>
<img src="https://blog.genma.fr/IMG/png/script_gitlab_4.png?1609418425" width="500" height="383" alt=""></span></p>
<p><strong>Conclusion</strong></p>
<p>Voilà, avec tous ces éléments, vous devriez pouvoir vous débrouiller pour coder un script similaire. Gardez en tête que je n'ai présenté que quelques-unes des fonctionnalités de l'API de Gitlab, et qu'il en existe bien d'autres !</p>
<p>Enfin, voici un tutoriel <a href="https://git.42l.fr/brume/Script_API_Gitlab/src/branch/master/tutoriel-api-gitlab-bash.md" rel="nofollow external">https://git.42l.fr/brume/Script_API_Gitlab/src/branch/master/tutoriel-api-gitlab-bash.md</a>, en français et en anglais, de l'utilisation de cette API en Bash.</p></div>
<p><img src="media/42493842.dd4318d0d3a7d2ffb13756f63b76d85d" data-original-source="http://cdn.libravatar.org/avatar/dd4318d0d3a7d2ffb13756f63b76d85d" alt="Gravatar de genma" class="gravatar" /><br/><i>Original post of <a href="https://blog.genma.fr/?Lifehacking-Creation-de-tickets-dans-le-Kanban-Gitlab-via-l-API" title="Visit the source">genma</a>.Votez pour ce billet sur <a href="http://www.planet-libre.org" title="Aller sur le planet">Planet Libre</a>.</i></p>


