Sometimes I write things, sometimes I don't.

To content | To menu | To search

Tag - Linux

Entries feed - Comments feed

Friday 3 February 2012

FOSDEM 2012

divers.pngI arrived in Belgium yesterday.

I'm glad to see people that were at DebConf in Bosnia and Herzgovina. I'll try to assistat many conferences about Java, Debian, GNOME and more if I can. I will also participate to the LibreDinner tomorrow.

Well, see you at FOSDEM 2012!

fosdem2012-going-to.png

Sunday 22 January 2012

Une extension à Nautilus pour GNOME Split

astuce.pngBientôt 2 ans après avoir exprimé ma volonté de créer une extension pour Nautilus afin de pouvoir lancer un découpage ou un assemblage avec GNOME Split, cette extension est enfin arrivée.

Le but de l'extension est de proposer deux nouvelles entrées dans le menu contextuel de Nautilus. Lors d'un clic droit sur un fichier quelconque l'item "Découper le fichier..." apparaît, l'utiliser permet de lancer GNOME Split avec les arguments qui vont biens pour découper le fichier sélectionné. Lors d'un clic droit sur un fichier étant considéré comme la première partie d'un fichier qui a été découpé auparavant, l'entrée "Assembler les fichiers..." apparaît permettant de lancer GNOME Split pour assembler les parties.

nautilus-extension-decoupage.png
Concrètement, cette extension de Nautilus est codée en C, publiée sous GPL version 3 et déjà présente dans le PPA pour la version 11.10 d'Ubuntu.

    ~$ sudo add-apt-repository ppa:gnome-split-team/ppa
    ~$ sudo aptitude update
    ~$ sudo aptitude install nautilus-gnome-split


N'étant pas expert en développement d'extensions pour Nautilus toute aide est la bienvenue.
En espérant que cette extension soit utile.

Friday 18 November 2011

Chaînes de caractères dynamiques

mobile.png Tout bon programmeur Android a pour habitude de lister toutes les chaînes de caractères (ou presque) dans le fichier res/values/strings.xml. A priori, seules les chaînes de caractères statiques ne peuvent être mises dans ce fichier. Mais, il existe des méthodes pour rendre ces chaînes un petit peu plus dynamique qu'elles n'y paraissent. Voyons tout ça.

1. Les formes plurielles

Les formes plurielles varient plus ou moins d'un langage à un autre. Par exemple, en français, on peut vouloir écrire :

  • Je ne possède pas de stylo.
  • Je possède un stylo.
  • Je possède des stylos.

L'API Android met à disposition plusieurs distinctions de formes plurielles grâce à 6 mot clés.

  1. zero, pour la quantité 0 ;
  2. one, pour la quantité 1 ;
  3. two, pour la quantité 2 ;
  4. few, pour représenter une petite quantité ;
  5. many, pour représenter une moyenne quantité ;
  6. other, pour représenter une quantité supérieure à une autre suivant la langue.

En français, on aura tendance à n'utiliser que zero, one et other.
Ainsi pour former les chaînes précédemment citées on mettra dans notre fichier res/values/strings.xml le code suivant :

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <plurals name="nombreDeStylos">
    <item quantity="zero">Je ne possède pas de stylo.</item>
    <item quantity="one">Je possède un stylo.</item>
    <item quantity="other">Je possède des stylos.</item>
  </plurals>
</resources>

Dans le code Java, on récupérera la bonne forme de cette manière.

final List<Stylo> stylos = getStylos();
final int count = stylos.size();
final String text = this.getResources().getQuantityString(R.plurals.nombreDeStylos, count, count);

2. Formatage des chaînes

Il peut être également utile d'afficher des nombres dans les chaînes de caractères comme par exemple : "Bonjour X, vous avez Y nouveaux messages !". Cela se fait de manière relativement simple grâce à la méthode String.format(String, Object...) de Java. Cette méthode est également invoquée automatiquement lors de l'utilisation de Context.getString(int, Object...). La chaîne de caractères à formater doit contenir quelques marques de formatage comme %1$s pour dire qu'il faut remplacer cette marque par le premier argument et que celui-ci est une chaîne de caractère ou encore %2$d pour dire qu'il faut mettre ici le second argument qui est un entier.
Ainsi dans le fichier res/values/strings.xml on écrira :

<string name="welcome_message">Bonjour %1$s, vous avez %2$d nouveaux messages !</string>

Et on utilisera le code Java suivant :

final String username = "toto";
final int mailCount = 10;
final String text = String.format(this.getResources().getString(R.string.welcome_message), username, mailCount);

On pourra aussi utiliser celui-ci :

final String username = "toto";
final int mailCount = 10;
final String text = this.getResources().getString(R.string.welcome_message, username, mailCount);

3. Conclusion

Comme on peut le voir Android met à disposition plusieurs méthodes pour manipuler les chaînes de caractères et les rendre aussi flexibles que possible tout en simplifiant un maximum le travail des traducteurs par exemple. Il ne reste plus qu'à exploiter ces possibilités pour créer un code simple et efficace.

Saturday 25 June 2011

Apache 2 : mod_macro

internet.pngIl y a des logiciels, des outils, des modules ou on sait directement que l’on ne pourra plus s’en passer. Soit parce que c’est génial et révolutionnaire soit par ce que c’est très pratique et qu’il fallait y penser. C’est exactement ce que je me suis dis en découvrant le mod_macro pour Apache 2. Il y a quelques semaines je ne soupçonnais par l’existence d’un tel module. On m’en a parlé, j’ai laissé mariner et puis j’ai finalement mis la main à la pâte. Et là j’en ai eu la larme à l’œil. Combien de fois je me suis arraché les cheveux sur ma configuration de Apache, combien de copier/coller de virtual hosts j’ai fait… Avec mod_macro tout ça c’est terminé.

Pour résumer, ce module permet de factoriser sa configuration de Apache. On définit des macros puis on les appelle un peu comme les fonctions avec un langage de scripts. On peut faire des macros pour plus ou moins tout ainsi en organisant bien son système et en sachant factoriser sa configuration correctement on peut grandement se simplifier la vie.

Pour installer le mod_macro sur Debian et dérivées, rien de plus simple :
# aptitude install libapache2-mod-macro
# a2enmod macro


Ensuite, il s’agit de ne pas faire n’importe quoi. Afin de gérer mes macros, j’ai créé un fichier macro.conf dans le répertoire /etc/apache2/conf.d/ qui est chargé au démarrage de Apache. Comme je l’ai dit précédemment, on peut se servir des macros pour faire énormément de choses donc je n’aborderai pas tout ici.

Admettons que nous disposons des 2 hôtes virtuels suivants (exemple bidon mais c’est pour montrer le principe) :
<VirtualHost [ipv6]:80 ipv4:80>
  DocumentRoot /var/www/toto
  ServerName   toto.domaine.tld
  ServerAlias  toto.domaine.tld
  ServerAdmin  admin@toto.com

  ErrorLog     /var/log/apache2/toto_error.log
  TransferLog  /var/log/apache2/toto_access.log
</VirtualHost>


<VirtualHost [ipv6]:80 ipv4:80>
  DocumentRoot /var/www/titi
  ServerName   titi.domaine.tld
  ServerAlias  titi.domaine.tld
  ServerAdmin  admin@titi.com

  ErrorLog     /var/log/apache2/titi_error.log
  TransferLog  /var/log/apache2/titi_access.log
</VirtualHost>


Il y a quand même pas mal de points communs entre ces 2 hôtes virtuels. Imaginez s’il y en avait 20 comme ça, la configuration devient vite lourde à gérer. Avec une seule et unique macro on va bien se simplifier la vie. Dans le fichier /etc/apache2/conf.d/macro.conf on écrit donc la macro suivante :
<Macro Domain $sub $domain $root>
  DocumentRoot /var/www/$root
  ServerName   $sub.$domain
  ServerAlias  $sub.$domain
  ServerAdmin  admin@$domain

  ErrorLog     /var/log/apache2/$domain_error.log
  TransferLog  /var/log/apache2/$domain_access.log
</Macro>


Vous voyez le principe. On regroupe les éléments communs aux hôtes virtuels pour les mettre dans une macro qui s’appelle Domain et qui prend 3 paramètres sub, le sous-domaine à utiliser, domain, le domaine à utiliser, et root le répertoire où se trouve les fichiers à rendre disponible sur le web.
Le fichier contenant les virtual hosts peut alors se simplifier en :
<VirtualHost [ipv6]:80 ipv4:80>
  Use Domain toto domaine.tld rep_toto
</VirtualHost>

<VirtualHost [ipv6]:80 ipv4:80>
  Use Domain titi domaine.tld rep_titi
</VirtualHost>


L’utilisation de la macro se fait avec la syntaxe très script-like Use NomMacro [paramètres]. Il faut impérativement donner tous les paramètres à la macro sans quoi la vérification de la configuration échouera.

L’exemple d’utilisation donné ici est simple mais on peut faire des choses plus complexes en utilisant des macros dans d’autres macros, etc… Il faut juste trouver la configuration qui convient le mieux pour son serveur. En tout cas je ne me séparerai plus du mod_macro que je trouve vraiment intéressant pour gérer les hôtes virtuels (chose que je trouve très ennuyante).

Tuesday 12 April 2011

Apache 2 en mode multithreadé

internet.pngVous le savez (ou pas) les installations classiques d’Apache 2 (avec PHP et MySQL bien souvent) sur Ubuntu (et même Debian) se basent sur une version bien spécifique du serveur web : la version prefork. Son comportement est donc de créer des processus (lourds) pour traiter les différents clients qui veulent accéder aux pages web. L’inconvénient c’est que la multiplication des processus pour le système d’exploitation c’est … lourd. Pour le soulager un peu, on peut utiliser une version d’Apache pas forcément ultra connue s’appelant worker. Cela permet de traiter les clients avec des threads (processus légers) et c’est particulièrement intéressant pour les processeurs récents (ou même assez vieux en fait).

Pour installer la version worker d’Apache, rien de plus simple :
# aptitude install apache2-mpm-worker

Ah ouais, mais il veut me virer le mod PHP5 ? Ça y est le voici l’inconvénient, le mod PHP5 n’est pas thread safe. On ne peut donc pas l’utiliser avec la version multithread de Apache. Mais comme PHP est quand même ultra répandu sur le web et que l’on ne peut se passer de ce magnifique blog (j’entends quelqu’un qui me dit que je devrais mettre plus de contenu pour qu’il soit magnifique), il existe tout de même une solution pour faire l’interprétation des scripts PHP.

On va utiliser la technique FastCGI. À la base CGI était utilisé pour faire du contenu dynamique sur le web avec plein de langages de programmation (Perl, C, script shell, etc…). En fait, il n’y a pas vraiment de limite de langages. FastCGI peut donc parfaitement interpréter du PHP. Pour activer cela, on installe alors 2 petits paquets :
# aptitude install libapache2-mod-fcgid php5-cgi

Si mod_fcgid n’est pas automatiquement activé dans Apache 2, on fera aussi un petit :
# a2enmod fcgid

Dans le cas où on a besoin de faire des modifications dans la configuration de PHP, on ira plus voir /etc/php5/apache2/php.ini mais plutôt /etc/php5/cgi/php.ini.

L’inconvénient c’est que, contrairement à mod_php5 pour apache2-mpm-prefork, les pages PHP ne seront pas interprétées sans modifier les différents VirtualHost qui peuvent servir des scripts PHP. Il faudra donc ajouter dans chaque directive Directory contenant désignant des répertoires avec du PHP les directives suivantes :
AddHandler fcgid-script .php
FCGIWrapper /usr/lib/cgi-bin/php5 .php
Options ExecCGI


La ligne AddHandler permet de spécifier quelle extension de fichier est à exécuter via FastCGI. FCGIWrapper donne le programme à exécuter pour traiter l’extension donnée. Et il ne faut pas oublier l’option ExecCGI sans quoi le PHP ne sera pas interprété.

Au final, cela pourra donner un VirtualHost dans le genre de celui-ci :
<VirtualHost *:80>
  DocumentRoot /var/www/mon_site

  <Directory "/var/www/mon_site">
    AddHandler fcgid-script .php
    FCGIWrapper /usr/lib/cgi-bin/php5 .php
    Options ExecCGI Indexes FollowSymLinks MultiViews
  </Directory>
</VirtualHost>


Comme vous pouvez le voir, ça peut vite être lourd si on a beaucoup de VirtualHost à changer. C’est pour ça que je vous encourage donc d’utiliser le mod_macro (merci Romain pour l’astuce) pour vous simplifier votre future administration du serveur web. Une fois tous les VirtualHost modifiés, il faudra redémarrer le serveur Apache.
# /etc/init.d/apache2 restart

Et là, si votre Apache avait l’habitude d’être un gros consommateur de ressources, il devrait se calmer.

Monday 24 January 2011

GNOME Split en version 1.0

astuce.pngJ’aurais du en parler plus tôt, beaucoup plus tôt même. Le 18 novembre 2010 a été pour moi l’occasion de partager la version 1.0 de GNOME Split, nom de code Stable Isotope.

Cette version est donc sortie plus ou moins un an après la toute première version tout public de GNOME Split. Elle apporte principalement des corrections de bugs plutôt gênants et qui étaient là depuis pas mal de temps.

split-view.png
Comme on peut le voir l’interface n’a pas changé et j’avoue qu’elle me plaît bien comme elle est actuellement. Donc a priori, ça ne devrait pas (ou peu) changer par la suite. Voyons tout de même les corrections et quelques nouveautés qu’apporte la version 1.0 par rapport à la 0.9.

  • Amélioration des performances : les opérations de découpages et d’assemblages prennent en moyenne 2 fois moins de temps par rapport aux versions précédentes.
  • Prise en compte des cas où un ou plusieurs fichiers à assembler ne sont pas disponibles.
  • Meilleure gestion des exceptions et des erreurs dans le code.
  • Fenêtre de préférences légèrement revue pour la rendre plus compacte.
  • Correction générale de l’assistant, les pages ne se dupliquent plus.
  • Meilleure gestion de la fermeture des flux de fichiers lors d’un arrêt brutal (CTRL + C par exemple).
  • Affichage du pourcentage d’avancement dans le titre de la fenêtre.
  • Correction d’un bug qui ne permettait pas de découper des fichiers de plus de 2 Gio.
  • Mise à jour des traductions (traduction française complète).

J’espère que cette nouvelle version répondra aux attentes de beaucoup de personnes. Et nous voilà donc sur le chemin vers la 2.0 qui devra permettre après toutes les versions intermédiaires de découper un fichier en cryptant les données via mot de passe et aussi d’uploader des fichiers directement sur des sites web dédiés afin de les partager.

Comme toujours, les archives de code sont et le dépôt pour les ubunteros est ici.

Thursday 6 January 2011

Et quand l'activité a besoin d'un objet ?

mobile.pngJe ne me souviens pas avoir parlé de programmation Android par ici. ce billet est donc l’occasion de commencer l’exploration du merveilleux OS mobile que nous fournit gracieusement Google. J’ai un smartphone qui carbure avec Android depuis bientôt 2 ans et je ne m’étais intéressé que vaguement à la programmation d’applications dessus. Dans mon parcours universitaire, j’ai eu l’occasion d’aborder ce sujet et mon projet tuteuré consiste principalement à faire une application pour Android. Trêve de blabla, passons à l’action.

Je ne vais pas refaire un cours sur Android, nombre de tutoriaux et d’exemples sont disponibles sur la toile. Dans le cadre de mon projet, j’avais donc un souci pour passer de l’information d’une activité à une autre. En effet, seuls les types primitifs et quelques autres trucs peuvent être passés d’une activité à une autre. Malheureusement, pas moyen de faire voyager un objet “simple” sans modification. Il faut qu’il implémente soit Serializable (connu par tous les bons programmeurs Java) soit Parcelable (propre à Android), “pour les surprendre on peut aussi faire les deux” (private joke).

Dans le cas présent, nous allons voir comment faire en implémentant l’interface Parcelable car cela demande un peu plus de code et de compréhension. Considérons un objet Message, sa classe (de base) s’écrirait très simplement.

class_message.png
Pour pouvoir faire naviguer cet objet entre plusieurs activités, on va donc le faire implémenter l’interface citée précédemment. Et c’est ici qu’il faut penser à quelques ajouts bien précis. L’objet implémentant Parcelable doit contenir un champ static appelé CREATOR de type Parcelable.Creator. De plus, 2 méthodes seront à redéfinir. Notre classe message se transforme alors comme la suivante.

class_message_parcelable.png
À ce stade, tous nos objets de type Message pourront être transférés d’une activité à une autre. Pour cela, on va donc utiliser un Bundle avec la méthode putParcelable(Parcelable).

class_sender.png
À noter qu'en tant qu’identifiant de l’objet dans le bundle, j’ai mis son nom complet (package + classe) ce n’est pas un hasard. Maintenant, on peut voir comment récupérer l’objet dans l’activité qui va le réceptionner.

class_receiver.png
Voilà qui est fait. Remarquez qu’il n’y a pas besoin de “caster” l’objet de type Parcelable récupéré, je vous laisse deviner grâce à quoi. Je ne prétends pas que ma méthode soit la meilleure, ni la plus sécurisée, etc… Tout ce que je sais, c’est que pour l’instant ça marche. L’expérience venant en codant, j’en saurai davantage sur l’efficacité de cette technique plus tard. Toutes améliorations et/ou remarques sont les bienvenues.

Tuesday 19 October 2010

My Book World, et que la lumière soit

bash.pngÇa commence à faire un moment que j’ai mon My Book World et je dois avouer que c’est terriblement pratique et efficace. Mais, depuis que je vis dans mon petit studio d’étudiant, la lumière blanche émise par les LED du disque externe est assez embêtante pour dormir.

Outre l’idée géniale du “tout est fichier”, GNU/Linux permet une personnalisation du système incroyable. Comme le My Book World utilise un système GNU/Linux léger autant en profiter non ? C’est ainsi que je me suis dit “hop un petit coup de echo dans les fichiers qui vont bien et je vais maîtriser les LED”. Grave erreur, enfin non, mais c’est un peu plus compliqué à cause justement du système minimal.

1. Activer SSH

Première chose, il faut activer le service SSH si ce n’est pas déjà fait. Pour cela, on se connecte sur l’interface web, on passe en Mode Avancé puis dans l’onglet Système on clique sur Avancés. Là, on coche la case Activer en face de Accès SSH.

ssh-mybookworld.png
On peut donc ensuite se logger avec… SSH. Le login est root et le mot de passe welc0me. Je vous invite bien évidemment à changer ce dernier à coup de passwd une fois connecté.
~$ ssh root@adresse_ip
~ # passwd

2. Vérification connexion Internet

Hé oui, au titre on le devine. On va avoir besoin d’une connexion Internet pour les quelques opérations à venir. Pour cela, il faut vérifier les paramètres réseaux. Dans l’interface d’administration, en mode avancé, cliquer sur l’onglet Réseau puis sur Réseau local. Si vous utilisez le client DHCP ça devrait être tout bon. En revanche, si comme moi vous utilisez le l’adressage en mode statique assurez-vous de bien avoir mis au moins un serveur DNS accessible (8.8.8.8 pour moi).

dns-mybookworld.png
Normalement, vous devriez pouvoir tester un ping sur une machine extérieure au réseau local depuis le SSH.
~ # ping respawner.fr
PING respawner.fr (88.191.119.214): 56 data bytes
84 bytes from 88.191.119.214: icmp_seq=0 ttl=56 time=30.9 ms

3. Installation de cron

Par défaut, il n’y a pas de cron sur le système du My Book World. Il est tout de même possible de l’ajouter car on va l’utiliser pour planifier l’extinction et l’allumage des LED. Il est existe un utilitaire nommé optware permettant d’installer des paquets IPK qui va nous faciliter la vie. On commence alors par installer optware. Toujours dans notre session SSH, on entre les commandes suivantes.
~ # wget http://mybookworld.wikidot.com/local--files/optware/setup-whitelight.sh
~ # sh setup-whitelight.sh


Maintenant, on met à jour (un peu à la façon APT) la liste des paquets avec :
~ # /opt/bin/ipkg update

Puis, on peut enfin installer cron :
~ # /opt/bin/ipkg install cron

4. Configuration

Comme on peut le voir, le binaire ipkg installe tous les paquets dans le dossier /opt/. C’est un bon moyen pour être certain de ne pas exploser le système. Le souci c’est que, du coup, cron ne se lancera pas au démarrage du disque dur externe. On va donc créer un lien du fichier /opt/etc/init.d/S10cron vers /etc/init.d/S10cron pour corriger le problème.
~ # ln -s /opt/etc/init.d/S10cron /etc/init.d/S10cron

Et puis, pour tester que notre cron fonctionne, on va mettre à jour l’heure via un serveur NTP. On édite (avec vi par exemple) alors le fichier /opt/etc/crontab pour y ajouter à la fin la ligne suivante :
* 4 * * * root ntpdate pool.ntp.org

Pour que l’ajout dans le fichier soit pris en compte, on redémarre le cron.
~ # /opt/etc/init.d/S10cron

5. Au tour des LED

On va enfin pouvoir nous occuper des LED. Comme je le disais plus haut, on peut contrôler les LED avec de simple echo de valeur dans les fichiers qui vont bien. Il suffira alors de mettre 192 pour éteindre ou 255 pour allumer les LED dans le fichier /sys/class/leds/oxnas-wd810-leds:sw/brightness. On peut tester rapidement les effets avec ces 2 commandes :
echo 192 > "/sys/class/leds/oxnas-wd810-leds:sw/brightness"
echo 255 > "/sys/class/leds/oxnas-wd810-leds:sw/brightness"


Mais bon, le but pour nous est de faire ça automatiquement. Par conséquent, ces 2 commandes prendront place dans le fichier /opt/etc/crontab. On ajoute donc à la fin de ce dernier les lignes suivantes :
30 23 * * * root echo 192 > "/sys/class/leds/oxnas-wd810-leds:sw/brightness"
30 9  * * * root echo 255 > "/sys/class/leds/oxnas-wd810-leds:sw/brightness"


On enregistre et on redémarre le cron. Et voilà, le tour est joué. Avec la configuration donnée ici, on constatera alors que les LED s’éteindront à 23h30 pour se rallumer à 9h30.

- page 1 of 12