My Own Memory Hole

Lancer une application maximisée par défaut sous LXDE / Lubuntu

Par exemple, dans mon cas, lxterminal, qui a chaque démarrage me frustrait du fait de la taille de sa fenêtre. Utilisant par ailleurs régulièrement tmux (voir à ce sujet « My Own Tmux Cheat Sheet »), je souhaitais que lxterminal s'ouvre par défaut maximisée.

Pour cela, on édite le fichier ~/.config/openbox/lubuntu-rc.xml (ou son ~/.config/openbox/lxde-rc.xml) et on ajoute juste avant la fin de la section applications ceci :

<application name="lxterminal">
  <maximized>yes</maximized>
</application>

Puis on force Openbox à relire sa configuration :

$ openbox --reconfigure

Twig pagination for Pico 2, round 2

After a first round where the challenge was to realize a pure Twig pagination for Pico 2 using it's new HTTP parameters feature, I've worked on a new version. It's purpose? Dynamically reducing the number of displayed pages...

So, I've added the pagi_max_near_by variable to define how many pages around the active page should be displayed. Then, you have to add some more tests inside the includes/pagination.twig file:

{% set pagi_next_page = pagi_basepage + 1 %}
{% set pagi_prev_page = pagi_basepage - 1 %}
{% if pagi_max_near_by is null %}
  {% set pagi_max_near_by = 2 %}
{% endif %}

{% if pagi_maxpage > 1 %}
  <ul>
    {% if pagi_prev_page is not null %}
      <li class="pi" {% if pagi_prev_page < 1 %}style="visibility: hidden;"{% endif %}><a href="{% if pagi_prev_page == 1 %}{{ pagi_base_url }}{% else %}{{ pagi_base_url ~ '/?' ~ pagi_http_param ~ '=' ~  pagi_prev_page }}{% endif %}" title="Newest posts" id="prev_page_link">Newest posts</a></li>
    {% endif %}

    {% if pagi_basepage - pagi_max_near_by > 1 %}
      <li class="pi">&hellip;</li>
    {% endif %}

    {% for item in range(1, pagi_maxpage|number_format) %}
      <li {% if pagi_basepage - pagi_max_near_by > item or pagi_basepage + pagi_max_near_by < item  %}style="display:none;"{% endif %} class="pi {%if item == pagi_basepage %} pi_a{%endif %}"><a href="{% if item == 1 %}{{ pagi_base_url }}{% else %}{{ pagi_base_url ~ '/?' ~ pagi_http_param ~ '=' ~ item }}{% endif %}" class="page_item {%if item == pagi_basepage %} page_active{%endif %}">{{ item }}</a></li>
    {% endfor %}

    {% if pagi_basepage + pagi_max_near_by < pagi_maxpage %}
      <li class="pi">&hellip;</li>
    {% endif %}

    {% if pagi_next_page is not null %}
      <li class="pi" {% if pagi_next_page > pagi_maxpage %}style="visibility: hidden;"{% endif %}><a href="{{ pagi_base_url ~ '/?' ~ pagi_http_param ~ '=' ~ pagi_next_page }}" title="Older posts" id="next_page_link">Older posts</a></li>
    {% endif %}
  </ul>
{% endif %}

Of course, you can adjust the pagi_max_near_by variable template by template by passing it a an argument to your Twig include; for example, inside your index.twig template (please refer to the first post if you don't know how to use):

{% set pagi_slice_length = 5 %}
{% set pagi_pages_array = pagesbis %}
{% set pagi_base_url = base_url %}
{% set pagi_http_param = 'page' %}
{% set pagi_max_near_by = 3 %}

[... snip ...]

{% include 'includes/pagination.twig' with [pagi_basepage, pagi_maxpage, pagi_base_url, pagi_http_param, pagi_max_near_by] %}

Quels outils pour réduire CSS et JS ?

cleancss

$ sudo apt install cleancss

Ensuite, il suffit de lancer la commande :

$ cleancss -o mon_fichier.min.css mon_fichier.css

Traitement par lot

Mais c'est un peu lassant de répéter cette opération lorsque l'on a de multiples fichiers à traiter. J'ai donc adapté le script proposé par Marco G qui utilise yui-compressor.

On crée donc le script mincss dans un répertoire bin de notre home puis on le rend exécutable avant d'y coller le script ci-dessous :

$ mkdir /home/$USER/bin
$ touch /home/$USER/bin/mincss
$ chmod +x /home/$USER/bin/mincss
$ nano /home/$USER/bin/mincss
#!/bin/sh
echo Compressing CSS Files...
saved=0
for f in `find -name "*.css" -not -name "*.min.css"`;
do
    target=${f%.*}.min.css
    echo "\t- "$f to $target
    FILESIZE=$(stat -c%s "$f")
    cleancss -o $target $f
    FILESIZEC=$(stat -c%s "$target")
    diff=$(($FILESIZE - $FILESIZEC))
    saved=$(($saved + $diff))
    echo "\t  $diff bytes saved"
done
echo "Done&nbsp;! Total saved: $saved bytes"

UglifyJS

Pour les fichiers Javascript, j'utiliser UglifyJS

$ sudo apt install node-uglify

ou en utilisant npm l'utilitaire de gestion des paquets de NodeJS :

$ sudo npm install -g uglify-js

La commande uglifyjs est désormais disponible :

$ uglifyjs mon_fichier.js -o mon_fichier.js.min.js

Ajouter la compression :

$ uglifyjs mon_fichier.js -o mon_fichier.minc.js -c

Ajouter en plus l'« altération » :

$ uglifyjs mon_fichier.js -o mon_fichier.minc.js -m

On peut ainsi lancer la commande pour n'obtenir plus qu'un fichier à partir de tous les fichiers spécifiés :

$ uglifyjs *.js -o output.js -c -m

uglifyjs-folder

Pour traiter l'ensemble des fichiers d'un répertoire (et de ses sous-répertoire), on peut également utiliser uglifyjs-folder.

$ sudo npm install -g uglifyjs-folder

Pour compresser tous les fichiers d'un répertoire, il suffit de lancer :

$ uglifyjs-folder mon_dossier/ -o script.min.js

On peut aussi vouloir conserver des fichiers séparés, ce que permet l'option -e ; dans un tel cas, l'arborescence du dossier traité est conservé dans le répertoire indiqué avec l'option o :

$ uglifyjs-folder ../test/ -o output/ -e

Un petit script pour écouter la radio depuis un terminal

Afin de faciliter l'écoute de certaines radio en streaming, et surtout sans utiliser un navigateur web, de plus en plus gourmand en ressources, j'utilise désormais un petit script bash qui utilise mplayer.

$ mkdir /home/$USER/bin
$ touch /home/$USER/bin/radio
$ chmod +x /home/$USER/bin/radio
$ nano /home/$USER/bin/radio
#!/bin/bash

usage ()
{
    echo '*****************************************************'
    echo '******************** Radio **************************'
    echo '*****************************************************'
    echo '  - beaub    &nbsp;: BeaubFM, radio associative de Limoges'
    echo '  - culture  &nbsp;: France Culture'
    echo '  - info     &nbsp;: France Info'
    echo '  - inter    &nbsp;: France Inter'
    echo '*****************************************************'
}

case $1 in
    beaub )         mplayer http://beaubfm2.ice.infomaniak.ch/beaubfm2-96.mp3
                   &nbsp;;;
    culture )       mplayer http://direct.franceculture.fr/live/franceculture-midfi.mp3
                   &nbsp;;;
    info )          mplayer http://direct.franceinfo.fr/live/franceinfo-midfi.mp3
                   &nbsp;;;
    inter )         mplayer http://direct.franceinter.fr/live/franceinter-midfi.mp3
                   &nbsp;;;
    -h | --help )   usage
                    exit
                   &nbsp;;;
    * )             usage
                    exit 1
esac

Ensuite, il suffit de choisir sa radio et de lancer la commande suivante (par exemple) :

$ radio culture

Auto-complétion des stations

On crée le fichier radio-completion.bash :

$ nano /home/$USER/bin/radio-completion.bash

dans lequel on colle les deux lignes suivantes :

#/usr/bin/env bash
complete -W "beaub culture info inter" radio

lancez la commande suivante :

$ source /home/$USER/bin/radio-completion.bash

Et vous devriez avoir les stations qui vous sont proposées lorsque vous pressez la touche Tab à la suite de la commande radio et au fur et à mesure de votre saisie.

Connexion Bluetooth au retour de veille sous Lubuntu 18.04 sur ASUS F200M

Sous Lubuntu 18.04, il m'était impossible de me re-connecter en Bluetooth à mon ampli Hi-Fi au retour de la veille.
Et aucune des solutions repérées sur le forum de la communauté anglophone d'Ubuntu, ni celle de Ferux, ni celle de lotharmat ne me permettait de re-connecter mon ampli, bien qu'il soit bien enregistré comme de confiance. J'avais toujours le même message d'erreur :

Connection Failed: blueman.bluez.errors.DBusFailedError: Resource temporarily unavailable

Une solution simple et définitive  !

La solution vient de Halka sur askubuntu.com, bien qu'il ne faille pas se contenter d'une version >=5.28.2 de bluez : la version disponible dans les dépôts de Lubuntu 18.04 est la 5.48-0ubuntu3 (au 7 juillet 2018)...

Par contre, l'utilisation de la version que propose la « Ubuntu Bluetooth team » via son PPA, la 5.50-0ubuntu0ppa1 (au 7 juillet 2018) permet de résoudre le problème.
Donc, on fait tout simplement :

$ sudo add-apt-repository ppa:bluetooth/bluez
$ sudo apt-get update && sudo apt-get upgrade

Si ça ne marche pas... comment retrouver mes connections Bluetooth ?

J'utilisais le programme bluetoothctl et devais retirer l'appareil avant de l'appairer à nouveau et de le connecter...

$ bluetoothctl 
Agent registered
[bluetooth]# disconnect FC:58:FA:14:27:BC 
Attempting to disconnect from FC:58:FA:14:27:BC
Successful disconnected
[bluetooth]# connect FC:58:FA:14:27:BC
Attempting to connect to FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC Connected: yes
Connection successful
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: yes
[Tangent Ampster BT]#

Si la seule déconnexion ne suffit pas, il faut alors complètement retirer le périphérique&nbsp:

$ bluetoothctl
Agent registered
[Tangent Ampster BT]# remove FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: no
Device has been removed
[CHG] Device FC:58:FA:14:27:BC Connected: no
[DEL] Device FC:58:FA:14:27:BC Tangent Ampster BT
[bluetooth]# scan on
Discovery started
[CHG] Controller 54:27:1E:C9:81:80 Discovering: yes
[NEW] Device FC:58:FA:14:27:BC Tangent Ampster BT
[bluetooth]# pair FC:58:FA:14:27:BC
Attempting to pair with FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC Connected: yes
[CHG] Device FC:58:FA:14:27:BC UUIDs: 00001101-0000-1000-8000-00805f9b34fb
[CHG] Device FC:58:FA:14:27:BC UUIDs: 0000110b-0000-1000-8000-00805f9b34fb
[CHG] Device FC:58:FA:14:27:BC UUIDs: 0000110c-0000-1000-8000-00805f9b34fb
[CHG] Device FC:58:FA:14:27:BC UUIDs: 0000110e-0000-1000-8000-00805f9b34fb
[CHG] Device FC:58:FA:14:27:BC UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: yes
[CHG] Device FC:58:FA:14:27:BC Paired: yes
Pairing successful
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: no
[CHG] Device FC:58:FA:14:27:BC Connected: no
[bluetooth]# connect FC:58:FA:14:27:BC
Attempting to connect to FC:58:FA:14:27:BC
[CHG] Device FC:58:FA:14:27:BC Connected: yes
Connection successful
[CHG] Device FC:58:FA:14:27:BC ServicesResolved: yes
[Tangent Ampster BT]#

Quelque peu pénible... le plus simple étant de redémarrer le service Bluetooth :

$ sudo service bluetooth restart

puis de reconnecter l'ampli depuis l'applet Blueman.

Twig pagination for Pico 2

Pico 2.0 introduces some major changes including the possibility to access HTTP parameters.
This allows us to let pagination plugins aside and to code a pagination only with Twig.
Here is how!

Inside your index.twig (for example), paste this code and set the variables:

{#  number of pages to display per page #}
{% set pagi_slice_length = 5 %}
{#  the array of pages to use #}
{% set pagi_pages_array = pages %}
{#  the base URL of the page the pagination applied
    it can be a more complex string, concatenated like this:
    base_url ~ "/tag/" ~ current_tag
#}
{% set pagi_base_url = base_url %}
{#  the name to use as the URL parameter (?page=xxx) #}
{% set pagi_http_param = 'page' %}

{% if url_param(pagi_http_param, 'int') is not null %}
{% set pagi_basepage = url_param(pagi_http_param, 'int') %}
{% set pagi_slice_start = pagi_slice_length * (pagi_basepage - 1) %}
{% else %}
{% set pagi_slice_start = 0 %}
{% set pagi_basepage = 1 %}
{% endif %}

{% set pagi_maxpage = (pagi_pages_array|length / pagi_slice_length)|round(0, 'ceil') %}

{% for page in pagi_pages_array|slice(pagi_slice_start, pagi_slice_length, preserve_keys) %}      
    <article>
        <h2 class="h1"><a href="{{ page.url }}">{{ page.title }}</a></h2>
    </article>
{% endfor %}

{% include 'includes/pagination.twig' with [pagi_basepage, pagi_maxpage, pagi_base_url, pagi_http_param] %}

You have to create a includes/pagination.twig file in which you have to paste this code:

{% set pagi_next_page = pagi_basepage + 1 %}
{% set pagi_prev_page = pagi_basepage - 1 %}
{% if pagi_maxpage > 1 %}
  <ul>
    {% if pagi_prev_page is not null %}
      <li class="pi" {% if pagi_prev_page < 1 %}style="visibility: hidden;"{% endif %}><a href="{% if pagi_prev_page == 1 %}{{ pagi_base_url }}{% else %}{{ pagi_base_url ~ '/?' ~ pagi_http_param ~ '=' ~  pagi_prev_page }}{% endif %}" title="Newest posts" id="prev_page_link">Newest posts</a></li>
    {% endif %}

    {% for item in range(1, pagi_maxpage|number_format) %}
      <li class="pi {%if item == pagi_basepage %} pi_a{%endif %}"><a href="{% if item == 1 %}{{ pagi_base_url }}{% else %}{{ pagi_base_url ~ '/?' ~ pagi_http_param ~ '=' ~ item }}{% endif %}" class="page_item {%if item == pagi_basepage %} page_active{%endif %}">{{ item }}</a></li>
    {% endfor %}

    {% if pagi_next_page is not null %}
      <li class="pi" {% if pagi_next_page > pagi_maxpage %}style="visibility: hidden;"{% endif %}><a href="{{ pagi_base_url ~ '/?' ~ pagi_http_param ~ '=' ~ pagi_next_page }}" title="Older posts" id="next_page_link">Older posts</a></li>
    {% endif %}
  </ul>
{% endif %}

It's awful, but it works ! ^^

If you have too many pages or simply want to reduce the number of displayed items, read the post "Twig pagination for Pico 2, round 2".