Catégories
Developpement Open-source Planet-libre Video

Witsub télécharge automatiquement vos sous-titres

subtitles

Witsub est mon dernier projet personnel visant à développer un utilitaire en ligne de commande permettant de télécharger automatiquement l’ensemble des sous-titres disponibles de votre bibliothèques de vidéos. L’objectif étant de disposer d’un outil simple, rapide, efficace et facilement déclenchable par script shell.

Comment marche Witsub

Witsub est développé en pure Python (sans bibliothèque non standard) et devrait donc fonctionner sur tous les systèmes d’exploitations (je l’ai uniquement testé sous GNU/linux). Dans son utilisation la plus simple, il prend en entrée un fichier ou un répertoire et une langue souhaitée pour les sous-titres. Ensuite il va parcourir la base de donnée OpenSubtitles pour y trouver les fichiers .srt correspondant à vos fichiers vidéos.

Pour installer Witsub, vous pouvez directement télécharger le script sous Github:

wget https://github.com/nicolargo/witsub/blob/master/witsub/witsub.py
chmod a+x witsub.py

ou bien utiliser les sources avec l’installeur au format tar.gz:

wget https://s3.amazonaws.com/witsub/witsub-1.1.tar.gz
tar zxvf witsub-1.1.tar.gz
cd witsub-1.1
sudo python setup.py install

ou plus propre utiliser PiPY pour l’installer sur votre système:

sudo pip install witsub

Un exemple valant mieux qu’un long discours, voici Witsub en action.

On commence par visualiser le répertoire videos avant le lancement de Witsub

	videos
	├── A wonderfull movies.avi
	├── A top serie
	│   ├── A top serie - S1E01.avi
	│   └── A top serie - S1E02.avi
	└── Not a video file.txt

Puis on lance Witsub en fixant la langue Française (code ISO fre, voir la liste complète des codes ici):

	witsub -l fre -f ./videos

On se retrouve avec:

	videos
	├── A wonderfull movies.avi
	├── A wonderfull movies.srt
	├── A top serie
	│   ├── A top serie - S1E01.avi
	│   ├── A top serie - S1E01.srt
	│   ├── A top serie - S1E02.avi
	│   └── A top serie - S1E02.srt
	└── Not a video file.txt

Voir ce qui se passe

J’ai fait en sorte, avec l’option -V, que Witsub affiche chacune des étapes de sa recherche de sous-titres. Par exemple, pour forcer (-w) le téléchargement des sous-titres Anglais de la vidéo breakdance.avi en mode debug:

# witsub -V -w -f ./test/testdata/breakdance.avi

19/05/2013 15:19:29 DEBUG - Running witsub version 1.0
19/05/2013 15:19:29 DEBUG - Debug mode is ON
19/05/2013 15:19:29 DEBUG - Force overwrite if file exist: True
19/05/2013 15:19:29 DEBUG - No language define. Default is eng
19/05/2013 15:19:29 DEBUG - Subtitle language search set to eng
19/05/2013 15:19:29 DEBUG - Connect to XML-RPC server http://api.opensubtitles.org/xml-rpc
19/05/2013 15:19:29 DEBUG - Login to XML-RPC server <ServerProxy for api.opensubtitles.org/xml-rpc>
19/05/2013 15:19:29 DEBUG - Login successfull with status 200 OK
19/05/2013 15:19:29 DEBUG - Compute hash tag for file test/testdata/breakdance.avi
19/05/2013 15:19:29 DEBUG - Hash tag for file test/testdata/breakdance.avi is 0x8e245d9679d31e12L
19/05/2013 15:19:29 DEBUG - Search subtitle in the database
19/05/2013 15:19:29 DEBUG - Search done in 0.008 seconds
19/05/2013 15:19:29 DEBUG - 4 subtitles found
19/05/2013 15:19:29 DEBUG - Subtitle 1/4 (English - Dwnl: 364): The.Sea.Inside.2004.DVDRip.XviD-RiZZ.srt
19/05/2013 15:19:29 DEBUG - Subtitle 2/4 (English - Dwnl: 224): breakdance.srt
19/05/2013 15:19:29 DEBUG - Subtitle 3/4 (English - Dwnl: 421): breakdance2.srt
19/05/2013 15:19:29 DEBUG - Subtitle 4/4 (English - Dwnl: 143): breakdance2.srt
19/05/2013 15:19:29 DEBUG - Select the first one (most downloaded): The.Sea.Inside.2004.DVDRip.XviD-RiZZ.srt
19/05/2013 15:19:29 DEBUG - Download the compressed subtitle file (id 1951887680): http://dl.opensubtitles.org/en/download/filead/1951887680.gz
19/05/2013 15:19:30 DEBUG - Download processed in 0.05 seconds
19/05/2013 15:19:30 DEBUG - Unzip the compressed subtitle file
19/05/2013 15:19:30 DEBUG - Write the subtitle to test/testdata/breakdance.srt
19/05/2013 15:19:30 INFO - Download completed: test/testdata/breakdance.srt
19/05/2013 15:19:30 DEBUG - Logout from XML-RPC server <ServerProxy for api.opensubtitles.org/xml-rpc>
19/05/2013 15:19:30 DEBUG - Logout successfull with status 200 OK

Les sources !

Witsub est hébergé sur GitHub: https://github.com/nicolargo/witsub

Merci d’y poster vos problèmes, questions, demandes d’amélioration !

Faites tourner 🙂

PS: Je ne suis pas très actif sur le blog en ce moment, la faute à pas mal de choses qui me laissent peu d’énergie pour rédiger des billets. Mais ne vous inquiétez pas, certains sont en préparation, notamment un sur la nouvelle caméra pour Raspberry Pi.

Catégories
Developpement Open-source Planet-libre Systeme

Package d’installation pour Glances sous Windows

Grâce au travail de Nicolas Bourges, Glances dispose désormais d’un installeur pour sa version Windows. Vous pouvez donc installer Glances 1.6.1 en version 32 ou 64 bits sans avoir à installer les pré-requis (Python, librairie PsUtil…) puisque tout est « packagé » dans le binaire.

On commence par télécharger le programme d’installation:

download
Télécharger Glances 1.6.1 en version 64 bits
(ou en version 32 bits)

MD5sum

glances-1.6.0-x64.exe                         a347ec5097d6d4d5039c7233872757a8

glances-1.6.0-x86.exe                         13d5be664599f80152f8f1ae47400576

Puis on se laisse guider dans le wizard d’installation qui va mettre, par défaut, le binaire Glances.exe dans le répertoire C:\Program Files\Glances puis créer un raccourci sur votre bureau.

En cliquant sur ce raccourci, Glances va se lancer automatiquement en mode serveur. Pour ajouter d’autres paramètres (comme le mot de passe) il suffit de modifier ce raccourci pour y ajouter les options voulues (par exemple -P <motdepasse>).

Il ne vous reste plus qu’à revenir sur un vrai OS (ndlr: Nicolargo, tu me copieras 100 fois « Je ne trollerai plus. ») puis à lancer la commande:

glances -c <addresse IP machine Windows>

glancesonwin7

Et hop, vous pouvez maintenant surveiller vos machines Windows en une ligne de commande !

Catégories
Blog Developpement Open-source Planet-libre Web Webdesign

Bootstrap pas à pas

7/10/2013 Update: billet mis à jour pour la version 3.0 de Bootstrap

Avec la généralisation des technologies JS, CSS3 et HTML5, il est aujourd’hui possible de faire des sites Web qui n’ont rien à envier aux interfaces des logiciels que l’on peut trouver sur nos machines. Le revers de la médaille est une complexité croissante qui nécessite de faire appel à des professionnels . Quand vous devez faire un site personnel ou pour une association, il est difficile, à moins de s’appeler Cresus, de passer par un Web designer.

Heureusement des frameworks libres permettent avec un minimum d’investissement et de connaissances de bâtir des sites Web dans les règles de l’art. Nous allons dans ce billet parler du plus médiatique d’entre eux: Bootstrap. L’idée n’est pas de traduire la documentation officielle qui est par ailleurs très bien faite, mais de partager avec-vous mes méthodes que je suis en train d’utiliser pour développer le prochain thème du Blog de Nicolargo qui sera, vous l’avez compris largement basé sur Bootstrap.

capture_037

footprint Créer l’arborescence de son projet

Nous allons commencer par créer l’arborescence générale de notre site qui sera stocké, pour illustrer ce billet, dans le répertoire ~/projet de notre disque dur. On y télécharge&&décompresse la dernière version stable de Bootstrap.

mkdir ~/projet
cd ~/projet

wget https://github.com/twbs/bootstrap/releases/download/v3.0.0/bootstrap-3.0.0-dist.zip
unzip bootstrap-3.0.0-dist.zip
rm bootstrap-3.0.0-dist.zip
rm -rf bootstrap 
mv dist bootstrap

Note: Contrairement à la plupart des tutos que l’on peut trouver sur le net, je préfère conserver le répertoire bootstrap intact et utiliser d’autres répertoires pour stocker mes configurations spécifiques. Ainsi, la mise à jour de Bootstrap n’aura aucun impact sur mon site.

En plus de Bootstrap, j’ajoute également la dernière version du projet Font Awesome qui met à notre disposition un nombre important et varié d’icônes jusqu’à une résolution de 280 pixels.

capture_032

cd ~/projet
git clone git://github.com/FortAwesome/Font-Awesome.git

Les données spécifiques à notre site seront stockées dans l’arborescence suivante (à adapter à vos besoins)

cd ~/projet
mkdir css img js
touch index.html css/style.css

 

On peut ensuite commencer à éditer la premier page de son site en utilisant son éditeur de texte de prédilection (par exemple avec Geany):

geany index.html

Voici le template que j’utilise:

<!DOCTYPE html>
<html>
    <head>
        <title>Bootstrap arena</title>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!-- Bootstrap -->
        <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen">
        <!-- Font-Awesome -->
        <link href="Font-Awesome/css/font-awesome.min.css" rel="stylesheet">
        <!-- My style -->
        <link href="css/style.css" rel="stylesheet" media="screen">
    </head>
    <body>
        <h1>Hello Bootstrap !</h1>
    </body>
    <footer>
        <script src="http://code.jquery.com/jquery.js"></script>
        <script src="bootstrap/js/bootstrap.min.js"></script>
    </footer>
</html>

Jusque là rien d’exceptionnel… Vous devriez voir s’afficher « Hello Bootstrap » en chargeant votre page dans un navigateur HTML. C’est à partir de maintenant que l’on va profiter de la puissance de Bootstrap !

footprint Définir vos grilles

Par défaut, Bootstrap utilise un système avec une grille de 12 colonnes (voir le site 960.gs pour une explication de cette dernière phrase). Votre fenêtre de navigateur est ainsi divisée en 12 sections de tailles équivalentes.  Vous pouvez l’adapter à votre besoin en gardant ce chiffre à l’esprit. Par exemple pour créer une page Web avec 2 colonnes, il suffit d’ajouter les lignes suivantes entre les balises <body> … </body> de votre fichier HTML.

<div class="container">
        <div class="row">
            <div class="col-md-8">Article</div>
            <div class="col-md-4">Sidebar</div> 
        </div> 
</div>

Ce qui donne une première colonne de taille 8/12 de la taille de votre fenêtre et une autre de 4/12:

capture_026

On utilise ici une disposition fluide (classe row) qui permet d’adapter dynamique la largeur de vos deux colonnes en fonctions de la taille de votre écran.

Bootstrap génère par défaut des espaces entre deux colonnes (environ 20 pixels pour une dic container). Il est  possible de générer des espaces supplémentaire avant ou entre vos colonnes en utilisant le paramètre de classe offset. Par exemple pour créer un espace de taille 1/12 d’écran entre vos deux colonnes, il suffit de modifier votre code de la manière suivante:

    <div class="container">
       <div class="row">
            <div class="col-md-8">Article</div>
            <div class="col-md-offset-1 col-md-3">Sidebar</div>
       </div>
    </div>

On obtient:

capture_027

Noter bien que la somme des col-md-8 + col-md-offset-1 + col-md-3 est toujours égale à 12. Pour être tout à fait précis, la somme doit être égale à la taille de votre grille dans lequel votre balise row est imbriquée. Comme nous l’avons vu la grille par défaut à une valeur de 12. Mais il est possible d’utiliser une autre valeur en définissant une div chapeau.  Par exemple pour définir une grille de 6 et y créer deux colonnes de 4 et de 2, on doit utiliser le code suivant:

        <div class="row">
            <div class="col-md-6"> 
                <div class="col-md-4">Article</div>
                <div class="col-md-2">Sidebar</div>
            </div>
        </div>

On obtient alors:

capture_028

footprint « Responsive design » en une ligne

Comme vous pouvez le voir il est possible d’imbriquer des grilles dans d’autres et ainsi découper facilement sa page sans se soucier des redimensionnements de fenêtres. En effet, tout le « responsive design » est géré par Bootstrap. Votre site sera donc automatiquement compatible avec les tablettes et les smartphones !

Le tableau suivant donne la liste des tags que l’on peut utiliser pour rendre son site compatible avec les différents supports:

 

capture_132

Comment lire ce tableau ? C’est relativement simple. Prenons un exemple. Nous voulons dans notre premier exemple avec deux colonnes (article et sidebar) cacher automatiquement la sidebar quand notre site est consulté depuis un smartphone. Nous allons pour cela afficher les classes .hidden-sm et .hidden-xs de la manière suivante:

    <div class="container">
        <div class="row">
            <div class="col-md-8">Article</div>
            <div class="col-md-4 hidden-sm hidden-xs">Sidebar</div>
        </div>
    </div>

Affichage sur un PC ou une tablette (ou un écran > à 767 pixels):

capture_030

Affichage sur un smartphone (ou un écran de largeur <= à 767 pixels):

capture_031

Magique non ?

footprint Passons aux contenus de vos pages

Nous avons maintenant une belle grille « responsive » qu’il va falloir remplir.

En plus des éléments de bases (texte, images, icônes, formulaire), Bootstrap propose des composants avancées (barre de navigation, menu, aperçu d’image, pagination, barre de progression) mais également un système de plugins avec des composants dynamiques en JavaScript (carrousel, popup, menu en accordéon, formulaire dynamique…). Je vous invite à consulter les liens données dans ce chapitre. Des idées pour votre prochain site viendront d’elles même.

Sources utilisées pour rédiger ce billet:

 

Catégories
Developpement Open-source Planet-libre

Besoin de bêta testeurs pour Glances 1.6

Glances 1.6 est en plein développement. Une version bêta vient d’être mise à disposition sur le GitHub officiel. J’ai donc besoin de VOUS pour tester, trifouiller, charger cette version avant sa publication. Je prend en charge de mon coté les tests sous Ubuntu et Debian mais je n’ai pas le temps de mener tous les tests sur les autres distributions et OS.

ineedyou

Comment tester ?

Le plus simple pour tester cette version sans casser son installation existante est de suivre la procédure donnée dans cette page du Wiki pour GNU/Linux (sous Windows, il faut au préalable installer quelques logiciels).

Si vous rencontrez un bug, merci de suivre cette procédure pour me le remonter.

Quoi tester ?

Un peu tout… C’est à dire dans un premier temps un lancement de Glances en mode standalone:

~/tmp/glances/glances/glances.py

En mode standalone avec le module sensor actif (si vous avez lm-sensors sur votre OS):

~/tmp/glances/glances/glances.py -e

En chargeant le nouveau fichier de configuration qui permet de changer les limites des alertes (c’est une des grosses nouveauté de cette version):

~/tmp/glances/glances/glances.py -C ~/tmp/glances/glances/conf/glances.conf

Note: vous pouvez bien-sur modifier le fichier de configuration (glances.conf) pour l’adapter à vos besoins.

Puis en mode client/serveur en lançant d’abord le serveur:

~/tmp/glances/glances/glances.py -s

Puis le client (sur la même machine):

~/tmp/glances/glances/glances.py -c localhost

Besoin de qui ?

Une liste non exhaustive de bêta-testeurs dont j’ai besoin et qui utilisent les systèmes suivants:

  • Arch Linux
  • Centos
  • Redhat
  • Gentoo
  • FreeBSD
  • NetBSD
  • OpenBSD
  • Mac OS
  • Windows 7
  • Windows 8
  • n’importe quel OS sous Python 3.x

Merci d’avance à vous !

Catégories
Developpement Open-source Planet-libre Systeme

Glances 1.5.2: Les nouveautés

Il y a quelques jours, j’ai mis en ligne la dernière version stable de Glances, mon outil de supervision système, dont nous allons, dans ce billet, découvrir les nouveautés de cette version 1.5.2.

Screenshots

On commence par l’aperçu général de Glances 1.5.2 dans une console (80×24):

screenshot-console

et dans un terminal (terminator):

screenshot-wide

Les nouveautés

CPU

J’ai repris la zone de statistique CPU pour afficher les attributs suivants: IDLE, IOWait et IRQ. Ces informations sont affichés si l’espace est disponible.

cpu-wide

En cliquant sur la touche ‘1’, Glances va switcher vers l’affichage des statistiques CPU par « core ».

percpu

Mémoire

Grâce au travail d’Alessio Sergi, les statistiques concernant la mémoire sont agrémentés, si la place sur l’écran est disponible, des informations suivantes:

  • active: RAM actuellement utilisée
  • inactive: RAM non utilisée actuellement
  • buffers: zone mémoire pour les informations systèmes (par exemple metadata des systèmes de fichiers)
  • cached: zone mémoire de cache

Processus

Egalement avec la particition d’Alessio, nous avons repris la zone de processus qui affiche maintenant le résumé sur une seule ligne ainsi qu’une optimisation de l’espace.

capture_082

Sensors

Suite à une demande récurrente, j’ai également ajouté un module optionnel pour afficher les températures remontées par les capteurs. Pour cela Glances utilise la librairie Python nommé PySensors qu’il faut installer sur son système et qui va chercher les informations via LM-Sensors (qui doit bien sûr être installé et configuré sur votre système). A ma connaissance, seul les OS Linux sont compatibles.

Pour utiliser ce module, on doit commencer par installer PySensors:

sudo pip install pysensors

Puis on lance Glances avec l’option -e:

glances -e

Et voilà le résultat sur une machine avec 4 capteurs:

capture_083

Amélioration de l’interface RPC

L’interface RPC/JSON est la base du mode client serveur permettant de surveiller à distance une machine. Par exemple pour surveiller depuis la machine B l’état du système de la machine A, il faut:

A> glances -s

Puis

B> glances -c <@IP ou Nom de A>

On peut facilement voir que l’on regarde les statistiques d’une machine distante grâce au message en bas à gauche de l’écran:

capture_084

La liste exhaustive des méthodes RPC disponible est:

getSystem
{"linux_distro": "debian 6.0.6", "platform": "64bit", "os_name": "Linux", "hostname": "frodo", "os_version": "2.6.32-5-amd64"}

getCore
4

getCpu
{"iowait": 0.32641336989226583, "system": 0.26113069591476262, "idle": 97.401749576581707, "user": 1.9845932889502962, "irq": 0.0, "nice": 0.0}

getLoad
{"min1": 0.0, "min5": 0.059999999999999998, "min15": 0.01}

getMem
{"inactive": 1631744000, "cached": 1974865920, "used": 1384603648, "buffers": 585797632, "active": 1932537856, "total": 4080373760, "percent": 33.899999999999999, "free": 2695770112}

getMemSwap
{"total": 1069277184, "percent": 12.800000000000001, "free": 932536320, "used": 136740864}

getSensors
[]

getNetwork
[{"interface_name": "eth0", "rx": 169437, "tx": 2082677}, {"interface_name": "eth1", "rx": 0, "tx": 0}, {"interface_name": "lo", "rx": 385562, "tx": 385562}]

getDiskIO
[{"read_bytes": 0, "write_bytes": 0, "disk_name": "sda1"}, {"read_bytes": 24576, "write_bytes": 458752, "disk_name": "sda2"}, {"read_bytes": 0, "write_bytes": 0, "disk_name": "sda3"}]

getFs
[{"mnt_point": "/", "used": 22333382656, "device_name": "/dev/sda2", "avail": 910442115072, "fs_type": "ext4", "size": 982693486592}, {"mnt_point": "/boot", "used": 24039424, "device_name": "/dev/sda1", "avail": 164789248, "fs_type": "ext4", "size": 199108608}, {"mnt_point": "/dev", "used": 94208, "device_name": "udev", "avail": 2034892800, "fs_type": "tmpfs", "size": 2034987008}, {"mnt_point": "/lib/init/rw", "used": 0, "device_name": "tmpfs", "avail": 2040184832, "fs_type": "tmpfs", "size": 2040184832}]

getProcessCount
{"running": 1, "total": 143, "sleeping": 142}

getNow
"2012-12-30 12:13:45"

Installation et mise à jour

Le mieux est de suivre la procédure adaptée à votre système en consultant le site officiel de Glances ou vous pourrez également consulter la documentation complète.

Contributeurs ? J’ai besoin de vous !

En plus de toutes les remontées de bug / demandes d’améliorations que vous pouvez effectué via cette interface Web sur le GitHub officiel du projet, j’aurai également besoin de contributeurs pour:

  • maintenir le PPA officiel du site et proposer des versions packagées de Glances pour Ubuntu et ses forks (juste pendant une période temporaire vu que Glances est maintenu officiellement dans Debian Sid et devrait donc être intégré de base dans la prochaine version d’Ubuntu)
  • maintenir un packaging « all in one » de Glances pour Windows 32 bits et 64 bits (c’est à dire en suivant la procédure d’installation sur le site officiel et en utilisant le module PyInstaller pour générer un binaire). Je pourrai ensuite héberger ces binaires sur mon espace Amazon S3.
  • participer au développement de la prochaine version de Glances, j’ai nommé la 1.6 dont la roadmap, en cours de conception, est disponible ici.

Il ne me reste plus qu’à vous souhaitez une bonne fin d’année 2012 !

See you soon on the moon.

Catégories
Developpement Open-source Planet-libre

Internationaliser ses programmes Python

Bien que je pense qu’il vaille mieux utiliser un logiciel en Anglais plutôt qu’un logiciel (mal traduit) en Français, la problématique de l’internationalisation des développements viendra tôt ou tard sur le tapis si vous avez des utilisateurs de plusieurs pays.

Nous allons donc dans ce billet aborder le sujet spécifique de la traduction d’un logiciel écrit dans le langage Python. Pour cela nous allons nous baser sur un programme simple et connu de tous: un bon vieux Hello World !

J’ai créé un projet GitHub avec l’ensemble des fichiers don je parle dans ce billet.

On commence par créer, dans un répertoire de travail, la structure suivante:

mkdir -p i18n/fr/LC_MESSAGES
touch hello.py
 Ce qui va donner:
.
├── hello.py
└── i18n
 ├── fr
     └── LC_MESSAGES

On édite une première version du script Python hello.py:

#!/usr/bin/env python

__appname__ = 'hello'
__version__ = "1.0"
__author__ = "Nicolas Hennion <nicolas@nicolargo.com>"
__licence__ = "LGPL"

def main():
    print("Hello world !")

if __name__ == "__main__":
    main()

Sans surprise, l’exécution de ce programme donne:

$ python hello.py
Hello World !

1. Rendre son code compatible

La première étape est de rendre notre code compatible avec l’internationalisation: Pour cela, on édite notre programme en effectuant les modifications suivantes:

#!/usr/bin/env python

__appname__ = 'hello'
__version__ = "1.0"
__author__ = "Nicolas Hennion <nicolas@nicolargo.com>"
__licence__ = "LGPL"

import gettext
gettext.install(__appname__)

def main():
    print(_("Hello world !"))

if __name__ == "__main__":
    main()
On notera donc:
  • l’inclusion de la librairie gettext
  • l’appel à la fonction gettext.install permettant de charger, s’il existe, le fichier de langue correspondant à la langue du système
  • le repérage de la chaîne de caractère à traduire en la faisant précéder par le caractère _: print(_(« Hello world ! »))

2. Génération du modèle de traduction

On passe ensuite à la création du modèle de traduction général (.pot) qui va servir de support de base pour toutes les langues. On utilise l’outil système suivant:

xgettext --language=Python --keyword=_ --output=./i18n/hello.pot ./hello.py

Attention, ce n’est pas dans ce fichier qu’il faut effectuer la traduction. Ce n’est qu’un modèle.

3. Génération du fichier de traduction

On va donc se retrouver avec un fichier ./i18n/hello.pot. C’est à partir de ce modèle que nous allons créer le fichier de traduction pour un langage donnée.

Par exemple, la création du fichier de traduction Francais (fr_FR) se fait:

msginit --input=./i18n/hello.pot --output=./i18n/fr/LC_MESSAGES/hello.po

4. Traduire votre programme

Il reste ensuite le travail le plus manuel à faire: la traduction en elle même…

Pour cela, on édite le fichier i18n/fr/LC_MESSAGES/hello.po:

...
#: hello.py:12
msgid "Hello world !"
msgstr "Bonjour le monde !"
...

5. Compiler le fichier de traduction

Une fois ce fichier renseigné il faut le compiler. C’est le résultat de cette compilation, qui se présente sous la forme d’un fichier .mo qui sera exploité par votre logiciel.

Pour compiler le fichier i18n/fr/LC_MESSAGES/hello.po vers le fichier i18n/fr/LC_MESSAGES/hello.mo:

msgfmt ./i18n/fr/LC_MESSAGES/hello.po --output-file ./i18n/fr/LC_MESSAGES/hello.mo

Il ne reste plus qu’à installer le fichier de traduction compilé (donc le fichier .mo) dans le répertoire standard de votre système d’exploitation:

Installation du fichier de traduction compilé sur le système:

sudo cp i18n/fr/LC_MESSAGES/hello.mo /usr/share/locale/fr/LC_MESSAGES/hello.mo

Note: cette installation devra normalement être faite par votre script d’installation (Makefile ou setup.py).

Il ne reste plus qu’a tester votre programme et oh miracle:

$ python hello.py
Bonjour le monde !

6. Mettre à jour votre fichier de traduction

En cas de mise à jour de votre programme (ajout ou suppression de chaînes de caractères à traduire, il n’est pas la peine de out recommencer. Il faut dans ce cas, utiliser les commandes suivantes:

xgettext --language=Python --keyword=_ --output=./i18n/hello.pot ./hello.py
msgmerge --update --no-fuzzy-matching --backup=off ./i18n/fr/LC_MESSAGES/hello.po ./i18n/hello.pot

Compléter la traduction puis re-compiler pour obtenir la nouvelle version du fichier .mo:

msgfmt ./i18n/fr/LC_MESSAGES/hello.po --output-file ./i18n/fr/LC_MESSAGES/hello.mo

7. Automatisation

Il est bien sûr conseillé d’automatiser les taches que l’on vient de voir, idéalement par un script. Vous pouvez par exemple vous baser sur le script que j’utilise pour l’internationalisation de Glances (voir ici).

Reste maintenant le travail le plus long: trouver des contributeurs/traducteurs pour traduire vos applications 🙂

Catégories
Developpement Open-source Planet-libre

Et si on jouait un peu avec Redis et Python ?

Dans la mouvance NoSQL, Redis se classe dans la catégorie « data structure server »  (que l’on peut traduire en Français par « serveur de dictionnaire distant »). C’est  un système permettant de traiter, de manière très performante, des données sous la forme clés/valeurs. Contrairement à des solutions comme MemCache, Redis est capable de gérer la persistance des données en stockant, sur demande, son contenu sur disque.

La clé, qui peut être comparée au nom d’une variable dans un langage de programmation, permet d’identifier de manière unique la donnée. Lors de la création de votre application, vous allez rapidement vous rendre compte que le choix de cette clé n’est pas négligeable. C’est elle qui définira « la structure » de votre base de donnée.

La clé est dans la définition de la clé.

Quant aux valeurs, elles peuvent appartenir aux types suivants:

  • chaînes de caractères (strings)
  • compteurs numériques (note: les données numériques seront stockées dans la base sous la forme de chaîne de caractères) (atomic counters)
  • listes (lists)
  • tableaux (set) et tableaux ordonnés (sorted set)
  • dictionnaires (hashes)

Comme on peut le voir, on retrouve la plupart des structures du langage Python. En étant un fervent admirateur, je me suis donc penché sur l’API Python Redis.

C’est parti pour un peu de bac à sable…

Installation de Redis

Pour mes tests, j’ai fait une installation standard depuis les paquets Ubuntu du serveur Redis, de l’API Python et de la CLI iPython pou illustrer mes exemples:

sudo apt-get install redis-server python-redis ipython

Les commandes de bases

La librairie Python permet d’envoyer des commandes (voir la liste des commandes ici) au serveur.

On commence par se connecter un serveur (local en écoute sur le port TCP par défaut).

J’utilise iPython pour mes tests de la librairie Python mais il est également possible de passer par la CLI Python classique.

# ipython

In [1]: import redis

In [2]: r = redis.Redis('localhost')

Premier exemple clés / valeur (chaîne de caractères):

In [3]: r.set("cles", "valeur")
Out[3]: True

In [4]: r.get("cles")
Out[4]: 'valeur'

Stocker des valeurs numériques:

In [5]: r.set("clesnum", 666)
Out[5]: True

In [6]: r.get("clesnum")
Out[6]: '666'

In [7]: r.incr("clesnum")
Out[7]: 667

In [8]: r.decr("clesnum")
Out[8]: 666

Attention, la méthode get retourne des chaines, il faut les convertir avant de s’en servir comme des entiers.

In [9]: a = 10

In [10]: a + r.get("clesnum")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/nicolargo/<ipython-input-10-06c75e85d988> in <module>()
----> 1 a + r.get("clesnum")

TypeError: unsupported operand type(s) for +: 'int' and 'str'

In [11]: a + int(r.get("clesnum"))
Out[11]: 676

Des listes comme valeurs:

In [12]: r.rpush("clesliste", "a")
Out[12]: 1L

In [13]: r.rpush("clesliste", "b")
Out[13]: 2L

In [14]: r.rpush("clesliste", "c")
Out[14]: 3L

In [15]: r.lrange("clesliste", 0, -1)
Out[15]: ['a', 'b', 'c']

In [16]: r.lindex("clesliste", 2)
Out[16]: 'c'

In [17]: r.llen("clesliste")
Out[17]: 3

In [22]: r.lpush("clesliste", "z")
Out[22]: 4L

In [23]: r.lrange("clesliste", 0, -1)
Out[23]: ['z', 'a', 'b', 'c']

Pour des listes avec des valeurs uniques (set), il faut utiliser les méthodes sadd (pour ajouter) et smembers (pour récupérer le set).

In [27]: r.sadd("clesset", "a")
Out[27]: True

In [28]: r.sadd("clesset", "b")
Out[28]: True

In [29]: r.sadd("clesset", "c")
Out[29]: True

In [30]: r.sadd("clesset", "a")
Out[30]: False

In [31]: r.smembers("clesset")
Out[31]: set(['a', 'c', 'b'])

Une autre structure de liste intéressante est la liste avec des valeurs uniques et ordonnées. On ajoute un troisième champs à notre couple clés/valeur qui s’appelle score (3em paramètre dans la méthode zadd). C’est ce score qui va déterminer l’ordre de la liste:

In [32]: r.zadd("clessetsort", "a", 4)
Out[32]: True

In [33]: r.zadd("clessetsort", "b", 1)
Out[33]: True

In [34]: r.zadd("clessetsort", "c", 3)
Out[34]: True

In [35]: r.zadd("clessetsort", "a", 5)
Out[35]: False

In [36]: r.zrange("clessetsort", 0, -1, withscores = True)
Out[36]: [('b', 1.0), ('c', 3.0), ('a', 5.0)]

In [37]: r.zrange("clessetsort", 0, -1)
Out[37]: ['b', 'c', 'a']

Pour stocker un dictionnaire, c’est également très simple:

In [38]: r.hset("cleshash", "a", "A")
Out[38]: 1L

In [39]: r.hset("cleshash", "b", "B")
Out[39]: 1L

In [40]: r.hset("cleshash", "c", "C")
Out[40]: 1L

In [41]: r.hgetall("cleshash")
Out[41]: {'a': 'A', 'b': 'B', 'c': 'C'}

In [42]: r.hget("cleshash", "b")
Out[42]: 'B'

Gérer l’expiration de vos données

… importance du garbage…

In [3]: r.set("key", "value")
Out[3]: True

In [4]: r.exists("key")
Out[4]: True

In [5]: r.expire("key", 10)
Out[5]: True

In [6]: r.exists("key")
Out[6]: True

Attendre 10 secondes ou plus...

In [7]: r.exists("key")
Out[7]: False

Egalement de manière statique avec la méthode expireat (http://redis.io/commands/expireat).

Pour être plus fin, il est aussi possible d’utiliser les « scores » avec les méthodes z* (zadd, zrangebyscore) pour supprimer les données qui ont des valeurs de clés les plus faibles (ou forte selon votre structure).  Par exemple pour supprimer les données de plus faible score (< 3) de notre liste « clesetsort » créée dans le chapitre précédant:

In [37]: r.zrange("clessetsort", 0, -1)
Out[37]: ['b', 'c', 'a']

In [60]: r.zremrangebyscore("clessetsort", 0, 3)
Out[60]: 2

In [61]: r.zrange("clessetsort", 0, -1)
Out[61]: ['a']

 

Les pipelines

Si Redis vous intéresse, c’est que vous avez à gérer un volume important de données. Les commandes que nous venons de voir dans le chapitre précédant sont unitaires. C’est à dire que pour une exécuter une commande, une requête (TCP) est faite au serveur Redis. Pour optimiser les performances et donc réduire le nombre de requêtes fait au serveur, nous disposons des Pipelines (lire ce billet comparatif sur le sujet).

Par exemple pour entrer 100.000 clés/valeurs dans votre serveur, il faut environ 11 secondes sur mon PC de test:

import time
import redis

_MAX_ITER = 100000

r = redis.Redis('localhost')

print "Start bench without Pipeline"
start=time.clock()
for i in range(_MAX_ITER):
   r.set("cles%d" % i, i)
stop=time.clock()
print "Result: %s" % str(stop-start)

alors qu’il faut un peu de plus de 4 secondes en utilisant une pipeline (soit un gain de plus de 50%):

import time
import redis

_MAX_ITER = 100000

r = redis.Redis('localhost')

print "Start bench with Pipeline"
start=time.clock()
p = r.pipeline()
for i in range(_MAX_ITER):
   p.set("cles%d" % i, i)
p.execute()
stop=time.clock()
print "Result: %s" % str(stop-start)

Ressources:

 

Catégories
Developpement Open-source Planet-libre Systeme

Préparer l’arrivée de Precise Pangolin avec un script de postinstall

Si vous suivez régulièrement ce blog, vous savez que je suis un informaticien fainéant, j’ai horreur de faire plusieurs fois la même chose. C’est une des raison pour laquelle je développe des scripts d’auto (ou post) installation que vous pouvez trouver sur mon espace GitHub.

Nous allons, dans ce billet, parler de la nouvelle version du script de post installation de la version Ubuntu Precise Pangolin (aka 12.04 LTS).

Heu, c’est quoi un script de post install ?

C’est un script que l’on lance à la fin d’une installation « standard » (« out of the box ») d’un système d’exploitation et qui va s’occuper de le configurer pour répondre au mieux à nos besoins.

On peut par exemple automatiser les tâches suivantes:

  • ajouter les dépôts de logiciels
  • installer les logiciels que vous jugez indispensables
  • supprimer les logiciels inutiles
  • télécharger et installer des thèmes pour votre interface graphique
  • configurer vos applications (BASH, prompt, Vim…)
  • faire toutes les actions en ligne de commande qui vous passe par la tête !

Historique du script UbuntuPostInstall

Les dernières versions de ce script (pour les distributions Ubuntu 11.04 et 11.10) étaient développées en Shell Script (BASH). Afin de simplifier le développement, j’ai donc décidé de re-développer complètement le script en Python en lui apportant une fonction de personnalisation par fichier de configuration.

C’est donc sur cette base que le script pour la version 12.04 d’Ubuntu est développé.

Comment fonctionne le script ?

Le script, disponible sous GitHub ou à partir de sa page officielle, est autonome et fonctionne directement à partir d’une installation standard d’Ubuntu 12.04 LTS. Pour le télécharger, il faut saisir les commandes suivantes:

wget https://raw.github.com/nicolargo/ubuntupostinstall/master/ubuntu-12.04-postinstall.py
chmod a+x ubuntu-12.04-postinstall.py

Pour fonctionner, le script utilise un fichier de configuration qui permet de spécifier les « choses à faire ». Par défaut, si aucun configuration n’est spécifiée dans la ligne de commande, il va télécharger le fichier suivant sur mon GitHub: post-installation pour Unity.

Donc pour lancer une post-installation standard sur une toute fraiche distribution Ubuntu 12.04 LTS, il faut lancer la commande:

sudo ./ubuntu-12.04-postinstall.py

Le script va faire les chose suivantes:

  • Ajouter des dépôts PPA utiles (voir la liste dans la section repos)
  • Ajouter des applications indispensables aux geeks (classées par thème: dev, multimedia, réseau, système…)
  • Ajout de thèmes pour GTK, des icônes…
  • Configuration de BASH (.bashrc, prompt, alias), Vim (.vimrc) et Htop (.htoprc)

Voici un aperçu du script en cous d’exécution:

Le script génère également un fichier de log dans le répertoire /tmp qui va détailler toutes les actions effectuées (et vous permettre d’identifier les éventuels problèmes).

D’autres fichiers de configuration sont disponibles sur mon GitHub et peuvent être spécifiés dans la ligne de commande. Par exemple, si vous préférez utiliser Gnome Shell en lieu et place d’Unity:

sudo ./ubuntu-12.04-postinstall.py -c https://raw.github.com/nicolargo/ubuntupostinstall/master/ubuntu-12.04-gnomeshell-postinstall.cfg

ou si vous êtes plutôt Cinnanon (le fork de Gnome 2):

sudo ./ubuntu-12.04-postinstall.py -c https://raw.github.com/nicolargo/ubuntupostinstall/master/ubuntu-12.04-cinnamon-postinstall.cfg

Comment éditer votre propre fichier de configuration ?

Bien que les fichiers fournis en standard répondent aux besoins de la plupart des geek qui lisent ce blog, il peut être intéressant de l’adapter plus finement à vos besoins.

Le plus simple est donc de « forker » la configuration par défaut qui s’approche le plus de votre environnement (Unity, Gnome Shell ou Cinnanon). Puis d’éditer le fichier de configuration et enfin de l’utiliser avec l’option -c du script (qui peut prendre en paramètre une URL ou un fichier local).

Par exemple, si vous êtes un fan de Gnome Shell, vous pouvez télécharger le fichier suivant puis l’éditer en suivant les consignes disponibles sur le site officiel.

Comme vous allez le voir, le fichier de configuration permet, en plus des actions détaillées au début de ce chapitre, de lancer des lignes de commandes en début (section preactions) ou fin de script (section postactions).

Conclusion

Si vous avez des remarques ou des demandes spécifiques sur ce nouveau scripts ou que vous vouliez partager vos fichiers de configurations personnels, les commentaires ci-dessous sont là pour ça !

Catégories
Developpement Open-source Planet-libre Systeme

En route vers Puppet, Chef, CfEngine…

  

Derrière ce titre un peu pompeux se cache une problématique que tout administrateur système s’est ou se posera un jour ou l’autre: Comment gérer l’installation, la mise à jour et la configuration de toutes les machines de son parc informatique ?

Ce billet a pour objectif de poser le problème de base et d’aborder quelques unes des solutions possibles. Il servira d’introduction à une série d’article sur ce vaste et intéressant sujet.

Introduction

Imaginons donc un responsable informatique disposant de trois administrateurs système: Michel, David et Jean-Pierre. Il leurs demande de travailler sur les solutions de déploiement des logiciels dans le système d’information de  l’entreprise. Quelques jours plus tard, il leur demande de présenter leurs solutions…

Première solution: « à la mimine »

La première solution pour répondre à la question posée est celle Michel, sysadmin de base (fort en technique mais moins en processus et en communication): lire la documentation du système (ou logiciel) à installer (ou mettre à jour), Googlelifier si la documentation est trop longue (ou seulement en Anglais), tester sur un environnement de développement (Jean-Pierre est quand même un garçon prudent) puis appliquer la dite procédure sur l’ensemble des machines.

On trouve également certains Michel (ceux qui ont passé la certification ISO) qui vont documenter leur installation dans un beau document (ou encore mieux un Wiki). Comme Michel travaille souvent seul, le document ne sera jamais partagé ou enrichie, il deviendra donc obsolète à la prochaine version du système (ou logiciel).

Cette première solution apporte quelques avantages: Michel peut maîtriser de manière unitaire toutes les installations et donc facilement identifier les problèmes, il a une connaissance précise et réelles des briques de ses machines.

D’un autre coté, Michel demande un certain temps pour déployer ou mettre à jour vos logiciels sur les 100 machines de votre parc et il deviendrait complètement débordé, voir incompétent,  si ce nombre passait à plusieurs centaines voir milliers de machines…

Deuxième solution: « script, script, script… »

Michel a un collègue, David, qui adopte une méthode similaire dans les premières étapes (lecture de la documentation, recherche sur Internet, test dans un environnement de développement). Mais qui, au lieu de faire lui même les opérations sur les machines, passe par un script Shell qui va automatiser ces taches. Si vous suivez ce blog, vous savez que j’utilise souvent cette méthode pour installer des composants sur mes machines persos (et quelques fois professionnelles).

David bichonne ses beaux scripts dans un repos Git. Ses procédures sont rodées: connexion en SSH, récupération du script et le exécution.

Tout semble parfait mais les développements de ces scripts peuvent vite devenir une vrai galère quand on s’attaque à un parc multi-distribution (ceux qui ont essayé de développer un script d’installation multi-plateforme/distribution doivent me comprendre…).

Troisième solution: « gestionnaire de configuration des machines »

Bienvenu dans le monde de Jean-Pierre. Lui, il utilise un gestionnaire de configuration des machines. Ces systèmes apportent une couche d’abstraction entre ceux que l’on veut faire (les besoins) et comment ces besoins sont concrètement résolus sur les machines cibles.Un pseudo langage de programmation permet de définir les actions à effectuer et le moteur de configuration des machines va s’occuper du déploiement, de l’exécution et de la génération d’un rapport sur chacune des machines cibles.

Plusieurs solutions existent, des propriétaires (comme IBM Tivoli, BSM ou HP Operations Manager i) et des libres (Puppet, Chef, CfEngine). C’est bien sûr sur ces dernières que Jean-Pierre, grand partisan des solutions libres, a donc porté son choix.

Il ne reste plus qu’à commencer à jouer avec le bébé en travaillant sur un environnement de développement/Cloud (teasing pour les prochains billets :)).

Conclusion

Je ne connais pas assez ces solutions pour avoir un avis tranché sur la meilleure solution libre. Après quelques recherches sur le net et la consultation des 3 sites internet officiels, je trouve que le projet Puppet est très bien structuré et documenté. Je pense donc partir sur cette solution pour mes prochains billet sur le sujet.

La discussion est cependant ouverte (et les commentaires sont fait pour cela).

Je suis preneur de retours d’expériences sur ces 3 solutions libres !

Sources ayant inspiré ce billet:

 

Catégories
Developpement Open-source Planet-libre Systeme

Les nouveautés de Glances 1.3.6

Glances, mon logiciel de supervision système en mode console vient de sortir en version 1.3.6.

Voici les nouveautés:

  • Les statistiques du panneau de gauche peuvent être masqués ou affichés à la demande en cliquant sur les touches ‘n‘ (interfaces réseau), ‘d‘ (entrées/sorties disques) et ‘f‘ (espaces disques).
  • Un panneau d’aide s’affiche quand on clique sur la touche ‘h‘.
  • En plus du « man », il est possible d’afficher le manuel en lançant glances avec les options -h ou –help.
  • Glances est maintenant disponible en Anglais (langue par défaut), en Français ou en Espagnol grâce à la contribution de Jean Bob.
  • Optimisation de l’affichage sur des terminaux > 80×24 caractères.
  • … et bien sûr son lot de corrections de bugs et ajout de contrôles lors du lancement de l’application.

Voici un aperçu de l’interface de la version 1.3.6 de Glances:

Vous trouverez plus d’informations ainsi que la procédure d’installation dans le billet suivant.