Monday, 02 July 2018
|
Écrit par
Grégory Soutadé

Logo gPass

Mise à jour en catastrophe de gPass. Le dernier commit ayant introduit un bug dans la génération des wildcards. Oui, je sais, ça fait déjà 6 mois... Les extensions sont normalement mises à jour automatiquement, donc il n'y a rien à faire (aucun changement n'est à signaler côté serveur).

Pour se tenir informé : Mailing list gPass

Monday, 14 May 2018
|
Écrit par
Grégory Soutadé

Fenêtre principale de KissCount

Enfin ! Après avoir retravaillé l'empaquetement, la compilation et la documentation, voici la version 0.7 de KissCount ! Cela fait un an et demi depuis la dernière version (qui ne comportait que peu de correctifs). En réalité, cette mouture était prête depuis 6 mois, mais j'étais occupé à mettre en place Pannous.

Et pour une version, c'est une belle version, avec en figure de proue la migration vers Qt5 (qui a principalement motivé son développement), ainsi qu'un nouvel exécutable pour Windows ! Là aussi, il y avait un gros retard, puisque le dernier binaire en date était la 0.4 de ... 2013. Cette fois-ci, elle est compilée nativement depuis Visual Studio/Windows 10, alors qu'auparavant, j'utilisais mingw en cross compilation depuis Linux.

À ma grande surprise, la migration de Qt4 vers Qt5 s'est faite tout en douceur avec très peu de changements nécessaires. Cela a surtout été l'occasion de se débarrasser de libkdcharts au profit de la bibliothèque de dessin intégrée à Qt (même si je ne suis pas pleinement satisfait du rendu des graphiques circulaires). Le panneau principal a subi une légère modification, puisque le calendrier migre en bas à gauche, ce qui permet de gagner de la place et d'être plus cohérent.

Autre fonctionnalité intéressante : lorsqu'un compte descend en dessous d'une certaine limite (200€ par défaut) ou en dessous de 0, les jours du calendrier sont colorés (en jaune (configurable) et rouge). Également, plutôt que de "cacher" les comptes clôturés, j'ai intégré une date de début et de fin, plus pratique (je sais, c'est une fonctionnalité de base chez la concurrence...). Finalement, tout un tas de petits bugs ont été corrigés.

Bref, une bien belle version pour inaugurer la nouvelle liste de diffusion kisscount-announce@soutade.fr

Monday, 14 May 2018
|
Écrit par
Grégory Soutadé

2cv en jardinière

« Flower power » : le pouvoir des fleurs ! La direction artistique nous re plonge dans les années 70, clin d'oeil non dissimulé aux 50 ans de mai 1968. Peut-être un peu plus sobre que les années précédentes, la décoration de la ville n'en reste pas moins soignée. La météo indécise, voire carrément pluvieuse le dimanche, n'a pourtant pas rebuté la foule à aller admirer la ville-exposition de cette 48e édition. Il faut dire que l'opportunité du jeudi de l'ascension ajouté au festival de Cannes qui se déroulait en parallèle (d'où le mauvais temps) offrait un créneau particulièrement intéressant pour concentrer touristes venus d'ailleurs et locaux en quête de sortie.

Rues fleuries, parfumées. Troupe de théâtre ambulante. Concert, projection. Artisans, commerçants et horticulteurs de tout PACA, mais aussi la compétition sous le chapiteau forment le grand classique de la programmation. Cette année, le chef Yves Terrillon spécialiste de la cuisine des fleurs est venu donner une présentation. Il a régalé le public avec deux associations met/rose (une salée, une sucrée). Il fallait être prompt dans le jardin des plantes si l'on voulait y assister !

Cette année encore, les rosiéristes ont déployé tout leur talent pour nous proposer des compositions splendides avec des roses vraiment originales, mais également un retour des roses anciennes "à parfum".

2cv sur le stand Banc flower power

Jardin zen Stand de roses

Rose dans sa tour de bourgeons

Rose rose et blanche Rose violette

Rose moutarde ketchup Rose rose et blanche

Rose centifolia Rose blanche saumonée

Allée de la villa Fragonard Puit de la villa Fragonard

Escalier de la villa Fragonard

Roses blanche et rose Roses rouges

Roses du concours Rose blanche

Rose jaune et verte Rose orangée

Rose jaune et rouge

Thursday, 03 May 2018
|
Écrit par
Grégory Soutadé

Il y a bien longtemps, au détour d'un forum, quelqu'un avait mentionné l'idée d'un rasage "old school", au coupe chou. Curiosité oblige, je me suis un peu renseigné et ai découvert le rasoir droit (encore appelé sabre ou coupe chou). J'avoue avoir été tout de suite fasciné par cet objet, reflet d'un savoir faire ancestral, fruit de nombreuses heures de travail, pensé pour durer toute une vie !

Pourtant, j'ai mis un certain temps avant de me lancer dans l'aventure. En effet, l'investissement initial n'est pas anodin. Tout d'abord, il faut acquérir la pièce maîtresse : le coupe chou. C'est un objet qui revient à la mode, il est donc possible d'en trouver d'occasions entre 50€ et 100€. Oui, d'occasion, parce que 1) ils sont moins chers et 2) un rasoir neuf n'est pas prêt à raser quand il sort d'usine. Il faudra une bonne dose d'affilage pour le mettre en état. Pour ma part, je suis tombé sur un modèle Grelot (2015) de chez Thiers avec une chasse en bois d'ébène. J'aime son aspect simple, avec un marquage classe mais pas tape à l'oeil.

L'affilage, justement, qui devra être réalisé avant chaque rasage. J'ai choisi une bande de cuir de chez Kachiic Creations. C'est un artisan de la région Lyonnaise qui offre des produits de très bonne facture pour un prix équivalent aux grandes "marques" du milieu. Je ne voulais pas utiliser de raquette (strop) pour éviter les différentes pâtes (vertes, rouges) nécessaires et surtout pour rester le plus naturel possible. Ma petite astuce : je réalise un affilage après le rasage en vue de la session suivante (gain de temps). On pourra alors s'amuser à passer le test du cheveu.

En ce qui concerne le blaireau, je suis allé piocher du côté des Portugais de Semogue pour leur excellent rapport qualité/prix. Un bol artisanal en bois d'olivier et un savon Institut Karité viennent compléter le tout. Ce sont là les éléments essentiels, sans superflu.

Set à raser

Mis bout à bout, il faudra donc un budget minimum d'environ 200€ (frais de port compris), de quoi réfléchir avant de se lancer. Bien sûr, mode oblige, il y a plusieurs fabricants qui proposent des éléments, voir des kits complets, de moindre qualité et à prix réduit. Mais ce n'est pas le but de la démarche, et surtout commencer avec des produits bas de gamme ne peut que donner une mauvaise impression. Je veux faire un investissement sur le moyen/long terme. De plus, il ne sera pas forcément aisé de revendre des éléments de piètre qualité, alors que la perte financière sera moins importante pour des produits nobles. Si ce budget peut paraître important, il n'est pourtant pas extravagant, certains coupe chou peuvent allègrement dépasser les 300€ à eux seuls ! En France, la région historique des lames se trouve autour de Thiers en Auvergne, mais pas seulement. On peut trouver des artisans qualifiés à peu près partout, qui font un travail remarquable et souvent à prix très accessible.

Une fois dans la main, la première impression est étrange. On manipule une lame particulièrement tranchante et pourtant son poids est très léger : 50g/60g chasse comprise ! En réalité, c'est une constante dans la coutellerie. La dureté (donc qualité de la lame) est directement liée à la durée d'utilisation entre chaque affûtage/affilage, mais est indépendante du poids. Au contraire, les alliages utilisés sont généralement légers. Nous avons hélas trop l'habitude des pâles copies de couteaux plus lourds mais ne coupant rien du tout !

Vient alors la pratique. Une fois la peau humidifiée et savonnée, il faut respecter deux règles de base : ne jamais passer le rasoir sur une peau qui n'est pas tendue et y aller petit à petit. En effet, la lame est extrêmement tranchante, donc au moindre bourrelet de peau elle va couper (ce qui se passe en général en fin de mouvement). Le mieux est de regarder quelques sessions sur Youtube. Les premiers temps, il est recommandé de ne faire que des parties simples comme le cou et les joues, puis de finir au rasoir à main (DE pour Double Edge). Personnellement, j'ai la chance de ne pas devoir me raser tous les jours, ce qui permet à la peau de se reposer et de récupérer des coupures éventuelles, tout en alternant avec un rasoir électrique.

Si se raser au coupe chou procure un certain plaisir via le maniement de la lame (pogonotomie), il faut reconnaître qu'il prend du temps et nécessite d'être concentré du début à la fin. Compter 20/30 minutes entre la préparation, le rasage et le nettoyage du matériel (la lame n'est pas en inox, il faudra donc qu'elle soit complètement sèche sous peine de voir rapidement apparaître des traces d'oxydation !). Aspect non intuitif, il faudra également éviter de laisser son matériel dans une salle de bain, sauf si celle-ci est très bien aérée, pour éviter l'oxydation due à la vapeur d'eau. C'est un art qui intéressera donc les amateurs de belles lames qui ne sont pas pressés.

L'alternative entre le tout jetable et le coupe chou reste le rasoir de sûreté artisanal. La première version aboutie date de 1880. On la doit aux frères Kampfe, version qui subira par la suite de nombreuses améliorations, notamment sous l'impulsion de l'américain Gillette, précurseur des lames jetables (et qui dit jetable, dit achat récurrent). L'avantage de ce type de rasoir est d'avoir une peau toujours tendue sur la zone à raser grâce aux montants supérieurs et inférieurs, mais aussi d'avoir un angle optimal pour les lames. Il n'en reste que les lames jetables (même si elles sont recyclables) ont une durée de vie assez courte, ce qui est moins bien d'un point de vue écologique que le coupe chou. Dans tous les cas, plusieurs artisans se mettent sur ce créneaux et proposent des manches originaux accueillant des têtes de rasoir standards.

Pour aller plus loin dans ce monde tranchant, je conseille la lecture du forum du Coupe Chou Club qui est une mine d'informations. Ce sera l'occasion d'acquérir son matériel à prix raisonnable auprès d'autres membres passionnés.

Thursday, 26 April 2018
|
Écrit par
Grégory Soutadé

La toute récente sortie de Pannous a été l'occasion de créer un nouveau sous-domaine pour héberger le service. Service qui comporte une partie d'authentification, donc obligation de passer par une communication sécurisée (SSL/TLS). Autrefois, la chose était plus aisée, puisque je pouvais générer mes propres certificats et notamment des certificats "wildcards", donc valides pour tous les sous-domaines.

Sauf que je suis passé à Let's Encrypt. Il a donc fallu attendre la sortie de la version 2 du protocole (qui a eu du retard) afin de bénéficier de cette fonctionnalité. Surtout, qu'au passage, le paquet Debian (backport) de certbot a été cassé, ce qui m'a forcé à revenir à une version encore plus ancienne.

Bref, les choses sont maintenants stables et déployées sur les serveurs respectifs. Petit problème néanmoins, la génération d'un certificat wildcard par Let's Encrypt requiert l'ajout d'une entrée DNS (comme challenge). Fatalité, le DNS de Gandi a lui aussi évolué pour passer en version 5. Avec pour principal avantage une mise à jour immédiate des entrées DNS (là où il fallait plusieurs minutes/heures auparavant). Autre nouveauté : l'API Gandi change de format. On oublie l'ancien XML-RPC (ce qui était pratique avec des bindings Python déjà tout faits), pour passer au REST (un peu moins formel).

Mélangeons tout ça pour obtenir un joli cocktail, dont la recette nous est donnée par Sébastien Blaisot qui, pour nous simplifier la vie, a créé des scripts de génération de certificats wildcards via Let's Encrypt. Le code est disponible sur GitHub et supporte le logiciel bind (en local), l'API OVH et la nouvelle API Gandi. Il ne reste plus qu'à cloner le dépôt et lancer la commande magique :

cd certbot-dns-01-authenticators/gandi-livedns
certbot certonly --manual --server https://acme-v02.api.letsencrypt.org/directory\
 --manual-auth-hook $PWD/auth.py --manual-cleanup-hook $PWD/cleanup.py -d '*.soutade.fr'

Et voilà un joli certificat tout frais !

Du coup, je me suis grandement inspiré de son code pour mettre à jour mon script de DNS fallback (serveur de secours via redirection DNS). Avec, en prime, un passage en Python 3 ! À terme, il faudra que j'ajoute le support IPv6.

#!/usr/bin/env python3
# -*- encoding: utf-8 -*-

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

import requests
import json
import re

# Config
domain="soutade.fr"
API_KEY = "YOUR-KEY"
livedns_api = "https://dns.api.gandi.net/api/v5/"
dyndns_url = 'http://checkip.dyndns.com/'
headers = {
    'X-Api-Key': API_KEY,
}
A_RECORD_NAME="@" # Record of A type

# Get current IP
current_ip = ''
response = requests.get(dyndns_url)
if response.ok:
    pattern = re.compile('[^:]*(\d+\.\d+\.\d+\.\d+)')
    result = pattern.search(response.text, 0)
    if result == None:
        print("No IP found")
        exit(1) 
    else:
        current_ip = result.group(0).strip()
else:
    print("Connexion error")
    response.raise_for_status()
    exit(1)

print('Your Current IP is %s' % (current_ip))

# Retrieve domains address
response = requests.get(livedns_api + "domains", headers=headers)

if (response.ok):
    domains = response.json()
else:
    response.raise_for_status()
    exit(1)

domain_index = next((index for (index, d) in enumerate(domains) if d["fqdn"] == domain), None)

if domain_index == None:
    # domain not found
    print("The requested domain " + certbot_domain + " was not found in this gandi account")
    exit(1)

domain_records_href = domains[domain_index]["domain_records_href"]

# Get recorded IP
response = requests.get(domain_records_href + "/" + A_RECORD_NAME + "/A", headers=headers)

if (response.ok):
    record = response.json()
else:
    print("Failed to look for recorded IP")
    response.raise_for_status()
    exit(1)

print('Old IP : %s' % (record['rrset_values'][0]))

if current_ip != record['rrset_values'][0]:
    record['rrset_values'][0] = current_ip

    # Put updated IP
    response = requests.put(domain_records_href + "/" + A_RECORD_NAME + "/A", headers=headers, json=record)

    if (response.ok):
        print("IP updated")
    else:
        print("something went wrong")
        response.raise_for_status()
        exit(1)

    exit(34) # IP updated return !!

exit(0)

Une version téléchargable est disponible ici.