Bubble Sweat Bubble

Les périgrinations d'un mec normal dans un monde qui ne l'est franchement pas

Aller au contenu | Aller au menu | Aller à la recherche

23déc. 2009

Emacs : gestion transparente de GPG

La gestion des fichiers GPG est très pratique sous emacs : chiffrement et déchiffrement à la volée sont par exemple au programme.

Pour profiter de tout cela, il suffit d'ajouter ceci à son .emacs :

; load epa
(require 'epa-file)
(epa-file-enable)
 
; use epa with files *.gpg et *.asc
(setq epa-file-name-regexp "\\.\\(gpg\\|asc\\)$")
(setq epa-file-cache-passphrase-for-symmetric-encryption t)
 
(require 'pgg)
 
; default mode to gpg
(setq pgg-default-scheme 'gpg)
 
; forgot passphrase after 600 seconds
(setq pgg-passphrase-cache-expiry 600)
 
; gpg default ID to use
(setq pgg-default-user-id "Your GPG default ID")

22déc. 2009

Emacs : sauvegarder sa session et la restaurer à chaque lancement

Une extension très pratique d'Emacs est la possibilité de conserver sa session de travail à chaque lancement. Il suffit de rajouter ceci à son .emacs :

(require 'session)
 
; save session
(add-hook 'after-init-hook 'session-initialize)
(setq session-initialize '(de-saveplace session places keys menus))
(desktop-save-mode 1)
 
; always load locked desktop when started in daemon mode
(if (daemonp)
     (setq desktop-load-locked-desktop t)
  )

Par défaut, session ne conserve pas les fichiers distants. Si vous le voulez (cela peut grandement ralentir le lancement d'Emacs) :

; save remote files too
(setq desktop-files-not-to-save "^$")

22déc. 2009

Emacs : compiler automatiquement son fichier .emacs

Compiler ses fichiers lisps peut grandement améliorer leur temps de chargement. Ceci s'applique bien sûr également au fichier .emacs lorsque celui-ci commence à se remplir de plusieurs dizaines de lignes. Voici un petit bout de code à rajouter à son fichier .emacs afin qui celui-ci se compile automatiquement à chaque enregistrement :

(add-hook 'after-save-hook
    (lambda()
      (require 'bytecomp)
      (if (string= (buffer-file-name)
                   (expand-file-name (concat
                                      (getenv "HOME")
                                      "/.emacs")))
          (byte-compile-file (buffer-file-name)))
      )
)

22déc. 2009

Emacs : accéder à des fichiers distants avec TRAMP

TRAMP c'est quoi ?

TRAMP (Transparent Remote (file) Access, Multiple Protocol) est une extension pour Emacs permettant d'accéder à des machines distantes comme si leurs ressources étaient disponibles en local. De façon générale, cela permet d'ouvrir des fichiers distants, de naviguer dans l'arborescence des fichiers avec dired, d'exécuter des commandes shells, ... Les plus habitués à Emacs auront de suite compris l'intérêt : toutes ses possibilités sont donc accessibles sur les machines distantes ! Pour cela, il suffit de pouvoir s'y connecter via rsh, rlogin, telnet, ssh ou toute autre méthode de connexion similaire (par exemple sudo). Le transfert de fichiers sera effectué au choix parmi les commandes rcp, rsync, scp ou pscp (sous Windows).

TRAMP est livré avec Emacs depuis la version 22. Pour les versions précédentes, il suffit de le télécharger ici : ftp://ftp.gnu.org/gnu/tramp/.

Configuration générale

Syntaxe TRAMP

La syntaxe par défaut pour accéder à un fichier distant est /machine:localname. Personnellement je trouve que cette syntaxe manque de clarté et puis je suis habitué à la norme URL/URI. J'ai donc activé la syntaxe URL de TRAMP ce qui donne ceci : /protocol://machine:port/localname. Voici les commandes à rajouter dans votre .emacs afin d'activer cette fonction :

; use /protocol://host[:port]/path/to/file
  (setq tramp-syntax 'url)
  (require 'tramp)

Backups

À moins d'avoir une bonne connexion à Internet, il est souvent préférable d'enregistrer les fichiers temporaires et les backups des fichiers distants localement :

; turn off backup-directory-alist for tramp
  (add-to-list 'backup-directory-alist
               (cons tramp-file-name-regexp nil))
 
  ; set a dedicated auto-save directory
  (setq tramp-auto-save-directory "~/.emacs.d/tramp-autosave")

Protocoles par défaut

On peut configurer le protocole à utiliser (si non spécifié) en général ou par machine. Par exemple, pour qu'emacs utilise SSH par défaut pour toutes les machines sauf pour root@localhost, cas dans lequel il doit utiliser sudo :

; default method to SSH
  (setq tramp-default-method "ssh")
 
  ; use sudo for root@localhost
  (add-to-list 'tramp-default-method-alist
               '("\\`localhost\\'" "\\`root\\'" "sudo"))

Rebonds

Une fonctionnalité très pratique de TRAMP est sa gestion des rebonds. Par exemple si vous ne pouvez accéder à la machine web1 qu'en passant par example.com, il suffit de rajouter ceci à la configuration .emacs :

; when web[0-9] is requested, connect to example.com first
  (add-to-list 'tramp-default-proxies-alist
               '("\\`web[0-9]\\'" nil "/ssh://example.com")
               )

Ainsi, lorsqu'emacs devra se connecter à web1, il ouvrira d'abord une connection ssh à example.com puis sur cette machine lancera une nouvelle connection ssh à web1. Cette fonctionnalité permet donc d'accéder à n'importe quelle machine à laquelle vous avez accès, quelque que soit le nombre de rebonds nécessaires.

Exemple de configuration

Un bon exemple vaut mieux qu'un long discours, voici donc ma configuration TRAMP :

; use /[protocol:]//host[:port]/path/to/file
  (setq tramp-syntax 'url)
  (require 'tramp)
 
  ; enable partial completion mode
  (partial-completion-mode 1)
 
  ; turn off backup-directory-alist for tramp
  (add-to-list 'backup-directory-alist
               (cons tramp-file-name-regexp nil))
 
  ; set a dedicated auto-save directory
  (setq tramp-auto-save-directory "~/.emacs.d/tramp-autosave")
 
  ; default method to SSH
  (setq tramp-default-method "ssh")
 
  ; use sudo for root@localhost
  (add-to-list 'tramp-default-method-alist
               '("\\`localhost\\'" "\\`root\\'" "sudo"))
 
  ; set the prompt pattern
  (setq tramp-shell-prompt-pattern "[^>$#]?[>$#] *")
  (setq shell-prompt-pattern "[^>$#]?[>$#] *")
 
  ; make sure terminal is defined to dumb
  (setq tramp-terminal-type "dumb")
 
  ; when web[0-9] is requested, connect to example.com first
  (add-to-list 'tramp-default-proxies-alist
               '("\\`web[0-9]\\'" nil "/ssh://example.com")
               )

Utilisation avancée

Éditer des fichiers distants est bien pratique mais il y a encore mieux : naviguer dans les dossiers via dired, exécuter des shells distants via shell', des terminaux distants via term'', bref tout ce que votre emacs vous permet. Pour cela, rien de plus facile : il suffit que le répertoire courant soit sur la machine distante pour que toutes les commandes shells soient exécutées sur cette machine.

Par exemple, si vous ouvrez le dossier /mon/dossier sur la machine example.com via /ssh://example.com/mon/dossier, toutes les commandes exécutées depuis ce buffer auront lieu sur example.com dans le dossier /mon/dossier. Voici les commandes les plus pratiques :

* M-x shell => ouvre un shell simple
* M-x term => ouvre un terminal complet
* M-! => exécute n'importe quelle commande shell

Il est donc très facile de créer des macros à lancer sur des machines distantes pour réaliser des commandes répétitives. Grâce à la puissance de TRAMP et la souplesse d'Emacs et de ses macros, on peut donc réaliser tout un jeu de commandes pour réaliser toutes les tâches répétitives quelque soit la machine concernée. La seule limite étant d'y avoir accès !

23déc. 2008

Classe DateTime de PHP5

Depuis la version 5.1 une nouvelle classe a fait son apparition : DateTime. Cette classe expérimentale dans les versions 5.1 est depuis officiellement incluse depuis les versions 5.2 de PHP. La liste des fonctions disponibles est ici. Il suffit de regarder toutes les fonctions commençant par "date_".

Quelques exemples d'utilisations :

<?php
// crée un nouvel objet DateTime
$d = new DateTime('2008-12-26 23:59:59');
echo $d->format('c');
 
// crée un nouvel objet DateTime à partir d'un timestamp UNIX
$ts = time();
$d = new DateTime('@' . $ts);
echo $d->format('c');
 
try {
    // le constructeur lance une exception si la chaîne de date n'est pas valide
    $d = new DateTime("2008-12-32");
} catch (Exception $e) {
    echo "date non valide";
}
 
// l'appel à date_create ne lance pas d'exception
$d = date_create("2008-12-32");
if ($d === FALSE) {
    echo "date non valide";
} else {
    // date valide
}

J'ai effectué quelques comparaisons avec les fonctions classiques strtotime et date afin de voir si DateTime est ou non plus lente. J'ai donc écrit un script pour tester les temps de réponses d'un appel à la fonction date avec un appel à strtotime ou avec un timestamp puis la même chose en utilisant DateTime. Afin d'avoir des valeurs plus cohérentes, j'ai fait la moyenne sur 1000 itérations à chaque fois. Voici le script utilisé :

$nb_iters = 1000;
$values = array();
echo "with strtotime: ";
for ($i = 0; $i < $nb_iters; $i++) {
    $s = microtime();
    $ts = strtotime('2008-12-25');
    $str = date('c', $ts);
    $e = microtime();
    $values[] = $e - $s;
}
printf("%.06f s\n", array_sum($values) / $nb_iters);
 
$values = array();
echo "without strtotime: ";
for ($i = 0; $i < $nb_iters; $i++) {
    $s = microtime();
    $str = date('c', $ts);
    $e = microtime();
    $values[] = $e - $s;
}
printf("%.06f s\n", array_sum($values) / $nb_iters);
 
$values = array();
echo "with datetime: ";
for ($i = 0; $i < $nb_iters; $i++) {
    $s = microtime();
    $d = new DateTime('2008-12-26');
    $str = $d->format('c');
    $e = microtime();
    $values[] = $e - $s;
}
printf("%.06f s\n", array_sum($values) / $nb_iters);
 
$values = array();
echo "with datetime given a timestamp: ";
for ($i = 0; $i < $nb_iters; $i++) {
    $s = microtime();
    $d = new DateTime("@$ts");
    $str = $d->format('c');
    $e = microtime();
    $values[] = $e - $s;
}
printf("%.06f s\n", array_sum($values) / $nb_iters);

Le résultat obtenu :

with strtotime: 0.000028 s
without strtotime: 0.000012 s
with datetime: 0.000024 s
with datetime given a timestamp: 0.000054 s

Comme on peut le voir, DateTime se révèle plus rapide qu'un appel conjoint de date et de strtotime. En revanche, si l'on possède déjà un timestamp, mieux vaut utiliser directement la fonction date puisqu'elle est deux fois plus rapide. DateTime se révèle donc très intéressant pour gérer des dates au format chaînes. En revanche, et c'est lié au design de DateTime, l'utilisation de cette classe avec un timestamp doit être évitée tant que possible. En effet la classe ne gère pas en natif le passage d'un timestamp à la construction et parse donc la chaîne donnée ce qui donne des temps de construction très lent (le double d'un appel avec une chaîne classique).

25mar. 2008

La killer app du futur sur Mac OS X : un (bon) client pour les mails !

ThunderbirdCeci est la chronique d'une défaite. La mienne en l'occurrence : après cinq mois passés sur Mac je n'ai toujours pas réussi à trouver un logiciel de mails digne de ce nom !

Pour le moment j'utilise Apple Mail mais je ne demande qu'à le quitter...après tout, je ne demande pas grand chose :

  • un support IMAP complet (pour mon gmail :))
  • un support des identités multiples facile à configurer et efficace à l'usage
  • une intégration complète dans le système (ical, carnet d'adresses, ...)

J'utilisais au début Thunderbird mais le manque d'intégration avec le système m'a poussé à le quitter. Surtout pour le carnet d'adresse. Parce que maintenir deux carnets d'adresses sur son ordinateur n'est même pas envisageable à moyen terme. La preuve : j'ai laissé tomber ;)

Voici donc un petit état des lieux de mon expérience sur Mac OS X.

Lire la suite

20mar. 2008

Google Translate API

Google vient de lancer une nouvelle API dédiée à la traduction de textes. Les langues supportées sont les mêmes que celles affichées dans Google Translate.

On a tous fait l'expérience des traductions parfois (souvent) bancales de Google Translate mais là où cette API devient vraiment intéressante c'est qu'elle permet aussi la détection de langue.

Plus d'infos sur la page dédiée de l'API.

20mar. 2008

J'aime pas Olivier Martinez

Sérieusement son jeu d'acteur est au moins aussi mauvais que le reste....
Et une petite compil de tous les sites qui sont d'accord avec moi :

20mar. 2008

Premier bilan 5 mois après mon switch vers l'univers Mac

Cela fait maintenant 5 mois que j'utilise exclusivement un mac pour travailler, surfer, glander...enfin bref pour faire tout ce que je faisais avec mon ordinateur. Le temps est donc venu pour un petit bilan.

Historique

Je viens du monde PC mais sous GNU/Linux. Je n'ai plus utilisé de Windows sur mes PC depuis 8 ans maintenant. Les raisons qui m'ont fait choisir un mac lorsque j'ai renouvelé mon matos :

  • le design
  • architecture Intel (j'aime pas le powerpc ça a toujours été plus lent)
  • système basé sur un Unix (BSD)

Ce qui me faisait peur :

  • le changement (et oui !)
  • le clavier un peu bizarre de prime abord du mac
  • les souris avec un seul bouton

Comme je me déplace parfois et que j'ai besoin de pouvoir travailler quand même j'ai choisi un MacBook Pro 17'' : j'aime bien les grands écrans ;)

Lire la suite

15déc. 2007

Configurer le support GPG pour Thunderbird sous Mac OS X

Un petit tutoriel pour expliquer comment activer le support de GnuPG dans Thunderbird sous Mac OS X parce que je me suis bien pris la tête pour trouver...
  1. Installer gpg et gpg-agent (sudo port install gnupg2 && sudo port install gpg-agent)
  2. Installer l'extension Enigmail pour Thunderbird
  3. Créer un dossier .MacOSX dans votre dossier utilisateur (par exemple /Users/toto/.MacOSX)
  4. Enregistrer dans ce dossier le fichier environment.plist joint à ce post en prenant soint de remplacer "/Users/toto" par "/Users/votre_login"
  5. Enregistrer l'application Gpg-Agent jointe dans votre dossier/Applications
  6. Modifier votre fichier /Users/toto/.profile pour y rajouter la ligne : eval $(cat ~/.gnupg/.gpg-agent)
  7. Dans "Préférences système > Comptes > Ouverture", ajouter le lancement de l'application Gpg-Agent
  8. Redémarrer votre session
  9. C'est gagné !

- page 1 de 4