<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">

  <channel>
    <title>12h26</title>
    <link>https://www.12h26.com</link>
    <generator>Kirby</generator>
    <lastBuildDate>Tue, 20 Oct 2020 15:59:38 +0200</lastBuildDate>
    <atom:link href="https://www.12h26.com/feed" rel="self" type="application/rss+xml" />

        <description></description>
    
        <item>
      <title>Recyclage d'un &#233;cran d'Eee PC</title>
      <link>/archives/recyclage-ecran-eeepc</link>
      <guid>/archives/recyclage-ecran-eeepc</guid>
      <pubDate>Sat, 28 Mar 2020 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>L'an dernier je me suis séparé d'un vieux Eee PC Asus. Sortie il y a plus de dix ans, la machine était complètement rincé, mais l'écran ne soufrant d'aucune rayure, j'ai décidé le conserver pour en faire un écran 10 pouces d’appoint pour le Raspberry.</p>
<p>En premier, trouver la référence de l'écran : <strong>HSD100IFW1</strong>, pour ensuite trouver la <a href="https://www.amazon.fr/gp/product/B06XK9MB2L/">carte contrôleur  HDMI</a></p>
<p>Pour mon petit montage j'ai eu besoin de :</p>
<ul>
<li>un écran : <strong>0€</strong></li>
<li>une carte contrôleur HDMI : <strong>29.13€</strong></li>
<li>une tôle en acier 25x50cm :<strong> 5.99€</strong></li>
<li>un support vesa : <strong>9.90€</strong></li>
<li>quelques vis/entretoise : <strong>0€</strong> (j'ai toujours une <a href="https://www.amazon.fr/gp/product/B075GWFBZD/">boite d'avance</a>)</li>
</ul>
<p>coût total :  <strong>45.02€</strong></p>
<figure><img src="/content/1-archives/20-recyclage-ecran-eeepc/01.jpg" alt="pliage de la tôle"></figure>
<figure><img src="/content/1-archives/20-recyclage-ecran-eeepc/02.jpg" alt="perçage"></figure>
<figure><img src="/content/1-archives/20-recyclage-ecran-eeepc/03.jpg" alt="la tôle avec les vis montée"></figure>
<figure><img src="/content/1-archives/20-recyclage-ecran-eeepc/04.jpg" alt="le contrôleur et l&#039;écran"></figure>
<figure><img src="/content/1-archives/20-recyclage-ecran-eeepc/05.jpg" alt="montage final vue de dessus"></figure>
<figure><img src="/content/1-archives/20-recyclage-ecran-eeepc/06.jpg" alt="montage final vue de coté"></figure>
<p>et voila le rendu final une fois au mur au dessus de ma baie domotique</p>
<figure><img src="/content/1-archives/20-recyclage-ecran-eeepc/07.jpg" alt="l&#039;écran accroché au mur"></figure>]]></description>
    </item>
        <item>
      <title>Extraire des pages d'un fichier PDF en CLI</title>
      <link>/archives/extraire-pages-pdf-cli</link>
      <guid>/archives/extraire-pages-pdf-cli</guid>
      <pubDate>Tue, 19 Nov 2019 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Pour extraire des pages d'un fichier PDF, inutile d'installer quoique ce soit.<br />
Ghostscript est installé par défaut sur la plupart des distributions.</p>
<p>Pour enregistrer les pages 3 à 6 du fichier input.pdf dans le fichier output.pdf :</p>
<pre><code class="language-bash">gs -sDEVICE=pdfwrite -dNOPAUSE -dBATCH -dFirstPage=3 -dLastPage=6 -sOutputFile=output.pdf input.pdf</code></pre>]]></description>
    </item>
        <item>
      <title>eslint, stylelint, csscomb : mes fichiers</title>
      <link>/archives/eslint-stylelint-csscomb-mes-fichiers</link>
      <guid>/archives/eslint-stylelint-csscomb-mes-fichiers</guid>
      <pubDate>Thu, 12 Sep 2019 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Bien que ces fichiers soient versionnés dans chacun de mes dépôts, avec souvent quelques variantes.<br />
Ci dessous la base commune à tous mes fichiers de configuration.<br />
Je les posent ici pour archivage et à titre d'information, car ils me valent souvent le qualificatif de &quot;<em>nazi du lintage</em>&quot; sur le plateau quand j'essaye de proposer ces fichiers.<br />
J'aime m'imposer des règles assez strictes (ou rigolote comme la syntaxe Yoda) dans mes projets perso, pour les projets en équipe c'est souvent la fête à la saucisse avec des fichiers beaucoup plus permissif.</p>
<p><strong>.eslintrc</strong></p>
<pre><code class="language-json">{
    "extends": "eslint:recommended",
    "rules": {
        "quotes": "single",
        "no-extra-semi": 1,
        "no-inner-declarations": 2,
        "curly": 2,
        "no-eval": 2,
        "no-extend-native": 2,
        "no-new-wrappers": 2,
        "no-with": 2,
        "eqeqeq": [2, "always"],
        "yoda": [2, "always"],
        "no-undef": 2,
        "no-var": 1,
        "prefer-const": 1,
        "array-bracket-spacing": [2, "never"],
        "no-array-constructor": 2,
        "no-mixed-spaces-and-tabs": 2,
        "no-new-object": 2,
        "object-curly-spacing": [2, "always"],
        "keyword-spacing": 2,
        "key-spacing": 2,
        "semi": 2,
        "no-console": 0,
        "max-depth": 2,
    }
}</code></pre>
<p>nb: ne pas oublier d'ajouter les sections propres au projet comme env et globals par exemple !</p>
<p><strong>.stylelintrc</strong></p>
<pre><code class="language-json">{
    "rules": {
        "at-rule-empty-line-before": ["always", {
            except: [
                "blockless-after-same-name-blockless",
                "first-nested",
            ],
            ignore: ["after-comment"],
        }],
        "at-rule-name-case": "lower",
        "at-rule-name-space-after": "always-single-line",
        "at-rule-semicolon-newline-after": "always",
        "block-closing-brace-empty-line-before": "never",
        "block-closing-brace-newline-after": "always",
        "block-closing-brace-newline-before": "always-multi-line",
        "block-closing-brace-space-before": "always-single-line",
        "block-opening-brace-newline-after": "always-multi-line",
        "block-opening-brace-space-after": "always-single-line",
        "block-opening-brace-space-before": "always",
        "color-hex-case": "lower",
        "color-hex-length": "short",
        "comment-empty-line-before": ["always", {
            except: ["first-nested"],
            ignore: ["stylelint-commands"],
        }],
        "comment-whitespace-inside": "always",
        "custom-property-empty-line-before": ["always", {
            except: [
                "after-custom-property",
                "first-nested",
            ],
            ignore: [
                "after-comment",
                "inside-single-line-block",
            ],
        }],
        "declaration-bang-space-after": "never",
        "declaration-bang-space-before": "always",
        "declaration-block-semicolon-newline-after": "always-multi-line",
        "declaration-block-semicolon-space-after": "always-single-line",
        "declaration-block-semicolon-space-before": "never",
        "declaration-block-single-line-max-declarations": 1,
        "declaration-block-trailing-semicolon": "always",
        "declaration-colon-newline-after": "always-multi-line",
        "declaration-colon-space-after": "always-single-line",
        "declaration-colon-space-before": "never",
        "declaration-empty-line-before": ["always", {
            except: [
                "after-declaration",
                "first-nested",
            ],
            ignore: [
                "after-comment",
                "inside-single-line-block",
            ],
        }],
        "function-comma-newline-after": "always-multi-line",
        "function-comma-space-after": "always-single-line",
        "function-comma-space-before": "never",
        "function-max-empty-lines": 0,
        "function-name-case": "lower",
        "function-parentheses-newline-inside": "always-multi-line",
        "function-parentheses-space-inside": "never-single-line",
        "function-whitespace-after": "always",
        "indentation": "tab",
        "length-zero-no-unit": true,
        "max-empty-lines": 1,
        "media-feature-colon-space-after": "always",
        "media-feature-colon-space-before": "never",
        "media-feature-name-case": "lower",
        "media-feature-parentheses-space-inside": "never",
        "media-feature-range-operator-space-after": "always",
        "media-feature-range-operator-space-before": "always",
        "media-query-list-comma-newline-after": "always-multi-line",
        "media-query-list-comma-space-after": "always-single-line",
        "media-query-list-comma-space-before": "never",
        "no-eol-whitespace": true,
        "no-missing-end-of-source-newline": true,
        "number-leading-zero": "always",
        "number-no-trailing-zeros": true,
        "property-case": "lower",
        "rule-empty-line-before": ["always-multi-line", {
            except: ["first-nested"],
            ignore: ["after-comment"],
        }],
        "selector-attribute-brackets-space-inside": "never",
        "selector-attribute-operator-space-after": "never",
        "selector-attribute-operator-space-before": "never",
        "selector-combinator-space-after": "always",
        "selector-combinator-space-before": "always",
        "selector-descendant-combinator-no-non-space": true,
        "selector-list-comma-newline-after": "always",
        "selector-list-comma-space-before": "never",
        "selector-max-empty-lines": 0,
        "selector-pseudo-class-case": "lower",
        "selector-pseudo-class-parentheses-space-inside": "never",
        "selector-pseudo-element-case": "lower",
        "selector-pseudo-element-colon-notation": "double",
        "selector-type-case": "lower",
        "unit-case": "lower",
        "value-list-comma-newline-after": "always-multi-line",
        "value-list-comma-space-after": "always-single-line",
        "value-list-comma-space-before": "never",
        "value-list-max-empty-lines": 0,
    }
}</code></pre>
<p><strong>.csscomb.json</strong></p>
<pre><code class="language-json">{
    "remove-empty-rulesets": true,
    "always-semicolon": true,
    "color-case": "lower",
    "block-indent": "\t",
    "color-shorthand": false,
    "element-case": "lower",
    "eof-newline": true,
    "leading-zero": false,
    "quotes": "single",
    "space-before-colon": "",
    "space-after-colon": " ",
    "space-before-combinator": " ",
    "space-after-combinator": " ",
    "space-between-declarations": "\n",
    "space-before-opening-brace": " ",
    "space-after-opening-brace": "\n",
    "space-after-selector-delimiter": "\n",
    "space-before-selector-delimiter": "",
    "space-before-closing-brace": "\n",
    "strip-spaces": true,
    "unitless-zero": true
}</code></pre>]]></description>
    </item>
        <item>
      <title>Home Assistant 0.95 refuse de d&#233;marrer</title>
      <link>/archives/home-assistant-0-95-refuse-de-demarrer</link>
      <guid>/archives/home-assistant-0-95-refuse-de-demarrer</guid>
      <pubDate>Mon, 01 Jul 2019 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Si depuis depuis la mise à jour de Home Assistant en version 0.95, celui ci refuse de démarrer, le réponse est toute simple et se trouve dans la <a href="https://www.home-assistant.io/blog/2019/06/26/release-95/#noteworthy-breaking-changes">Release note 0.95</a>.</p>
<p><em>For the last couple of releases, we’ve been printing warnings if your configuration contained invalid slugs or extra keys. Starting with this release, these warnings are now errors. No procrastination anymore, you’ll need to fix it now.</em></p>
<p>en gros corrigez tous les warning depuis une version anterieure avant de monter en version !</p>
<p>au besoin pour downgrader Hass</p>
<pre><code class="language-sh">pip3 install homeassistant==0.94.4</code></pre>]]></description>
    </item>
        <item>
      <title>Configurer une souris R.A.T. 7/9 sur Ubuntu</title>
      <link>/archives/configurer-une-souris-rat-7-9-sur-ubuntu</link>
      <guid>/archives/configurer-une-souris-rat-7-9-sur-ubuntu</guid>
      <pubDate>Mon, 11 Mar 2019 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>A chaque réinstallation d'Ubuntu c'est la même histoire, reconfigurer correctement le système pour qu'il reconnaisse mes souris RAT. Ci-dessous le pense bête.<br />
tout d'abord mettre Ubuntu en session &quot;gnome avec xorg&quot;. En effet je n'ai encore jamais réussi à faire un remap des boutons avec Wayland. donc en attendant, j'utilise le vénérable xorg.</p>
<p>tout d'abord déterminer le modèle exact de la souris avec <strong>xinput</strong></p>
<pre><code class="language-sh">xinput list</code></pre>
<p>garder en mémoire la ligne qui correspond au modèle. dans mon cas :</p>
<pre><code>Mad Catz Mad Catz R.A.T.7 Mouse</code></pre>
<p>Ensuite dans le fichier <strong>/usr/share/X11/xorg.conf.d/40-libinput.conf</strong>, j'ajoute la section suivante, en mettant le modèle dans <strong>MatchProduct</strong></p>
<pre><code>Section "InputClass"
        Identifier       "Mouse Remap"
        MatchDevicePath  "/dev/input/event*"
        MatchProduct     "Mad Catz Mad Catz R.A.T.7 Mouse"
        Option           "AutoReleaseButtons"    "13 14 15"
        Option           "Buttons"     "17"
        Option           "YAxisMapping"      "10 11"
        Option           "ZAxisMapping"     "4 5 6 7"
        Option           "Emulate3Buttons"  "no"
        Option           "Resolution"   "3200"
        Option           "ButtonMapping"   "1 2 3 4 5 0 0 8 9 7 6 12 0 0 0 16 17"
EndSection</code></pre>
<p>Maintenant installer <strong>imwheel</strong></p>
<pre><code class="language-sh">apt install imwheel</code></pre>
<p>puis modifier le fichier <strong>/etc/X11/imwheel/startup.conf</strong> :</p>
<pre><code>IMWHEEL_START=1
IMWHEEL_PARAMS='-b "0 0 0 0 8 9 7 6 12"'</code></pre>
<p>et enfin dans le fichier <strong>/etc/X11/imwheel/imwheelrc</strong> j'ajoute les raccourcis</p>
<pre><code>".*"
None, ExtBt7, Control_L|Alt_L|Up
None, ExtBt8, Control_L|Alt_L|Down
None, ExtBt9, F1</code></pre>
<p>Cette configuration me permet le basculer entre les bureaux virtuel avec la seconde molette et de lancer un terminal 'Tilda' avec la touche sniper.</p>]]></description>
    </item>
        <item>
      <title>GDPR Compliant</title>
      <link>/archives/gdpr-compliant</link>
      <guid>/archives/gdpr-compliant</guid>
      <pubDate>Fri, 25 May 2018 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>oui, cet espace est compatible avec la RGPD.<br />
<strong>12h26.com</strong> n'utilise aucun cookie, ne charge aucune librairie externe, et ne collecte aucune données personnelle.</p>
<p>tout simplement parce j'attache bien plus d'importance à mes temps de chargement et mon score sur <a href="https://developers.google.com/speed/pagespeed/insights/?hl=fr&amp;url=www.12h26.com">PageSpeed Insights</a>, <a href="https://www.dareboost.com/fr/">Dareboost</a> et autres outils du même genre qu'a la collecte de données.</p>
<p>Surfez tranquille.</p>]]></description>
    </item>
        <item>
      <title>Montage auto d'un DD externe avec udev</title>
      <link>/archives/montage-auto-dd-externe-avec-udev</link>
      <guid>/archives/montage-auto-dd-externe-avec-udev</guid>
      <pubDate>Wed, 23 May 2018 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Sur mon poste fixe je jongle avec pas moins de 6 disques dur externe. soit relié directement sur un des port usb soit via un DAS (Direct Attached Storage). afin que chaque disque ai toujours le même point de montage, j'ai mis en place quelques règles udev</p>
<p>tout d’abords, lister les disques</p>
<pre><code class="language-sh">l /dev/disk/by-uuid/</code></pre>
<p>ce qui renvoi un truc du style:</p>
<pre><code class="language-sh">lrwxrwxrwx 1 root root  10 mai    5 13:43 0d29e6f2-2898-4690-a799-9341d6618c06 -&gt; ../../sda1
lrwxrwxrwx 1 root root  10 avril 24 00:50 2a193102-e847-4b45-85ed-93378f867b6f -&gt; ../../sdo1
lrwxrwxrwx 1 root root   9 avril 24 00:50 3a1321c4-b32e-4b44-b831-b669d0122fb2 -&gt; ../../md1
lrwxrwxrwx 1 root root  10 avril 24 00:50 42e66110-ca39-4da9-ae6f-34a8927d5f71 -&gt; ../../sdi1
lrwxrwxrwx 1 root root   9 avril 24 00:50 5988a88f-4jb1-414e-90e9-6ff24b4b1289 -&gt; ../../md0
lrwxrwxrwx 1 root root  10 avril 24 00:50 6a4c385d-f24b-4c1a-8f6a-32ae39f6ed03 -&gt; ../../sdg1
lrwxrwxrwx 1 root root  10 avril 24 07:01 761a9950-9h9d-46c5-91aa-3553c3f77dd2 -&gt; ../../sdn1
lrwxrwxrwx 1 root root   9 avril 24 00:50 7961c967-8361-42d0-9949-7ee56ae2399c -&gt; ../../sdf
lrwxrwxrwx 1 root root  10 avril 24 00:50 888ca435-9f55-49dc-9c23-0db395239ca2 -&gt; ../../sdh1</code></pre>
<p>à partir de là, il faut différencier les disques physique des externes et ajouter dans le fichier fstab les lignes qui vont bien. sans oublier de modifier le point de montage, le système de fichiers  ainsi que les options adéquat</p>
<pre><code class="language-sh">vim /etc/fstab</code></pre>
<pre><code class="language-sh">UUID=761a9950-9h9d-46c5-91aa-3553c3f77dd2       /media/usb-hdd1         ext2    noauto,noatime,errors=remount-ro        0       0
UUID=2a193102-e847-4b45-85ed-93378f867b6f       /media/usb-hdd2         ext4    noauto,noatime,errors=remount-ro        0       0</code></pre>
<p>maintenant au niveau de udev, on ajoute autant de ligne que l'on a de disque dur</p>
<pre><code class="language-sh">vim /etc/udev/rules.d/80-external-usb-disk.rules</code></pre>
<pre><code class="language-sh">ACTION=="add", ENV{DEVTYPE}=="partition", ENV{ID_FS_UUID}=="761a9950-9h9d-46c5-91aa-3553c3f77dd2", RUN+="/bin/mount -U $env{ID_FS_UUID}"
ACTION=="add", ENV{DEVTYPE}=="partition", ENV{ID_FS_UUID}=="2a193102-e847-4b45-85ed-93378f867b6f", RUN+="/bin/mount -U $env{ID_FS_UUID}"</code></pre>
<p>ne reste plus qu'à recharger udev</p>
<pre><code class="language-sh">udevadm control --reload-rules</code></pre>
<p>au passage, si il y a besoin de modifier le label du disque :</p>
<pre><code class="language-sh">e2label /dev/sdn1 usb-hdd1
e2label /dev/sdo1 usb-hdd2</code></pre>
<p>et en bonus comme les disques ont maintenant toujours le même point de montage, j'affiche leurs informations dans conky</p>
<pre><code>${if_mounted /media/usb-hdd1}//usb/hdd1: ${fs_used_perc /media/usb-hdd1}% (${fs_free /media/usb-hdd1}) ${alignr}${fs_bar 8,60 /media/usb-hdd1}
${endif}${if_mounted /media/usb-hdd2}//usb/hdd2: ${fs_used_perc /media/usb-hdd2}% (${fs_free /media/usb-hdd2}) ${alignr}${fs_bar 8,60 /media/usb-hdd2}
${endif}</code></pre>]]></description>
    </item>
        <item>
      <title>Reformater une clef usb bootable sous windows</title>
      <link>/archives/reformater-une-clef-usb-bootable-sous-windows</link>
      <guid>/archives/reformater-une-clef-usb-bootable-sous-windows</guid>
      <pubDate>Tue, 05 Dec 2017 00:00:00 +0100</pubDate>
      <description><![CDATA[<p>Après avoir utilisé une clef USB pour y installer un système bootable Linux, on a parfois besoin de remettre la clef USB dans son état initial, à savoir une seule partition en FAT32.</p>
<p>L'outils &quot;Gestion de l'ordinateur &gt; Gestion des disques&quot; ne permettra pas de supprimer toutes les partitions crées sur la clef USB</p>
<p>Il va falloir passer par l'invite de commande en mode administrateur, puis ensuite utiliser diskpart.<br />
une fois lancé, on affiche la liste des disques, on sélectionne le disque par son numéro, et on clean</p>
<pre><code>C:\WINDOWS\system32\diskpart.exe
DISKPART&gt; list disk
DISKPART&gt; select disk [n]
DISKPART&gt; clean
DISKPART&gt; exit</code></pre>
<p>C'est tout, ensuite on peut retourner dans l'outils Gestion des disques et créer un nouveau volume simple comme si de rien n'était.</p>
<p>ou sinon on peut même créer la partition toujours depuis diskpart</p>
<pre><code>DISKPART&gt; create partition primary
DISKPART&gt; select partition 1
DISKPART&gt; format fs=fat32 quick</code></pre>]]></description>
    </item>
        <item>
      <title>G&#233;n&#233;rer ses stats GoAccess via Logrotate</title>
      <link>/archives/generer-ses-stats-goaccess-via-logrotate</link>
      <guid>/archives/generer-ses-stats-goaccess-via-logrotate</guid>
      <pubDate>Thu, 28 Sep 2017 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>Certains utilisent un cron pour générer leurs fichiers de stats GoAccess alors qu'en parallèle ils utilisent aussi Logrotate.<br />
Logrotate permet d’exécuter des commandes avant ou après la rotation, profitons-en pour lui demander de générer le fichier.<br />
une seule ligne à ajouter, celle juste après le prerotate</p>
<pre><code class="language-sh">/path/to/logs/website.access.log {
    monthly
    missingok
    rotate 24
    compress
    delaycompress
    notifempty
    create 0640 www-data adm
    sharedscripts
    prerotate
        /usr/bin/goaccess -af $1 &gt; /path/to/stats/website-`date --date="10 days ago" +%Y-%m`.html
        if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
            run-parts /etc/logrotate.d/httpd-prerotate; \
        fi \
    endscript
    postrotate
        invoke-rc.d nginx rotate &gt;/dev/null 2&gt;&amp;1
    endscript
}</code></pre>]]></description>
    </item>
        <item>
      <title>&#34;Invalid config for [apiai]&#34; et HASS 0.50</title>
      <link>/archives/invalid-config-for-apiai-hass-0-50</link>
      <guid>/archives/invalid-config-for-apiai-hass-0-50</guid>
      <pubDate>Thu, 03 Aug 2017 00:00:00 +0200</pubDate>
      <description><![CDATA[<p>La <a href="https://home-assistant.io/blog/2017/07/29/release-50/">version 0.50</a> de Home Assistant vient de sortir, et comme souvent un composant qui fonctionnait se met à dérailler.</p>
<p>après le passage à la version 0.50, le composant api.ai sort l'erreur :</p>
<pre><code>Invalid config for [apiai]: not a valid value for dictionary value @ data['apiai']</code></pre>
<p>c'est &quot;normal&quot;, ils ont changé la façon de déclarer les itents</p>
<p>avant le composant s'écrivait :</p>
<pre><code class="language-yaml">apiai:
  intents:
    GetTemperature:</code></pre>
<p>maintenant il faut l'écrire</p>
<pre><code class="language-yaml">apiai:

intent_script:
  GetTemperature:</code></pre>
<p>c'est tout.</p>]]></description>
    </item>
    
  </channel>
</rss>