Emacs 24

St IGNUciusLa future mouture d’EMACS, version 24, apporte de nombreux changements, en particulier au niveau de la standardisation en introduisant plusieurs fonctions génériques qui simplifient beaucoup les modes et unifient leur comportement.

Un outil d’auto-complétion pcomplete a été introduit. Il s’agit d’un moteur d’auto-complétion programmable, qui sera notamment utilisé dans shell-mode, avec un comportement comme celui de bash ou zsh. Pour les modes, completion-at-point est une commande générique d’EMACS permettant de standardiser les systèmes de complétion. En effet jusqu’ici, les différents modes majeurs avaient chacun leurs petites fonction d’auto-complétion plus ou moins bien codées, et surtout avec des comportements différents.

EMACS est désormais lié à gtk3 et propose une meilleure intégration au thème gtk de l’environnement. Ce n’est guère important pour ceux qui virent l’interface, mais c’est un pas en avant.

Changement intéressant, EMACS 24 incorpore un gestionnaire de paquets qu’on peut accéder avec M-x list-packages. Cela permet d’installer facilement des modes et d’autres outils. Seul bémol, le dépôt par défaut est celui du projet GNU qui nécessite une attribution de droit d’auteur, donc il n’y a pas beaucoup de paquets. Heureusement, des dépôts alternatifs ont déjà vu le jour.

Voici venir la fin d’une ère. L’illustre paquet color-theme voit en effet ses derniers jours dans EMACS 23 et sera remplacé par un système de thèmes intégré à l’éditeur. Ce système est non seulement plus léger, il enlève aussi certains bugs ennuyeux de color-theme (comme quand on change thème dans une même session par exemple).

cc-mode, le mode majeur pour C peut maintenant deviner le style de code du buffer. Cela évitera bien des griefs en modifiant le fichier de quelqu’un qui indente son code différemment.

Le développement d’EMACS est passé du vénérable CVS à bazaar il y a peu. En conséquence, le support des dvcs dans vc-mode a été amélioré.

De nouveaux modes font aussi leur apparition dans cette nouvelle version.

occur-mode permet de lister toutes les lignes correspondant à une regexp particulière dans un buffer à l’intérieur d’un buffer temporaire. On peut faire des changements dans ce buffer temporaire qui seront automatiquement appliqués au buffer original.

Les deux modes mineurs electric-pair-mode et electric-indent-mode ont été intégré. Leur but est de proposer plus de standardisation en evitant aux modes d’implémenter leur propres fonctions électrique.

Un mode de gestion de mot de passe qui se lie à Gnome-keyring ou KDE Wallet a été ajouté. Pratique quand on utilise tramp pour accéder à son code via FTP ou SSH.

EMACS s’intègre maintenant avec le système de notification du bureau. Pratique quand on reçoit un hl dans ERC ou dans jabber.el.

Enfin, un morceau particulièrement juteux, soap-client et soap-inspect ont été ajoutés. Ils permettent de se connecter à un serveur SOAP et le débugger les doigts dans le pif. Voici une fonction super utile pour moi :-) .

Il y a bien sûr beaucoup beaucoup d’autres changements, mais je vous ai listé ceux qui m’intéresse en particulier. Vous pouvez jeter un oeil sur le blog qui m’a inspiré pour plus d’informations.

Ah et tant que j’y suis, voici la conversion de mon thème etenil-pastel pour EMACS 24:

(deftheme etenil-pastel
  "Theme for etenil")

(custom-theme-set-faces
 'etenil-pastel
 '(default ((t (:background "#111111" :foreground "#cccccc"))))
 '(cursor ((t (:background "#cccccc" :foreground "#111111"))))
 '(region ((t (:slant italic :background "#444444"))))
 '(mode-line ((t (:background "#444444" :foreground "#cccccc"))))
 '(mode-line-inactive ((t (:background "#444444" :foreground "#888888"))))
 '(fringe ((t (:background "#444444"))))
 '(minibuffer-prompt ((t (:foreground "#cccccc"))))
 '(font-lock-builtin-face ((t (:foreground "#88cc66"))))
 '(font-lock-comment-face ((t (:foreground "#555555"))))
 '(font-lock-constant-face ((t (:foreground "#cc6666" :weight bold))))
 '(font-lock-function-name-face ((t (:foreground "#cccc66"))))
 '(font-lock-keyword-face ((t (:foreground "#88cc66"))))
 '(font-lock-string-face ((t (:foreground "#cc6688"))))
 '(font-lock-type-face ((t (:foreground "#66cccc" :underline t))))
 '(font-lock-variable-name-face ((t (:foreground "#6688cc"))))
 '(font-lock-warning-face ((t (:foreground "#bb0000"))))
 '(isearch ((t (:background "#cd00cd" :foreground "#b0e2ff"))))
 '(lazy-highlight ((t (:background "#afeeee"))))
 '(link ((t (:foreground "#0000ff" :underline t))))
 '(link-visited ((t (:foreground "#8b008b" :underline t))))
 '(button ((t (:underline t))))
 '(header-line ((t (:background "#444444" :foreground "#111111")))))

(provide-theme 'etenil-pastel)

;; Local Variables:
;; no-byte-compile: t
;; End:

;;; etenil-pastel-theme.el  ends here

Migration de Dotclear à WordPress

Vous l’aurez sans doute remarqué, j’ai récemment passé mon blog de Dotclear à WordPress. La raison étant que Dotclear comporte de nombreux bugs gênants (par exemple désactiver le plugin antispam fait que le moteur ne fonctionne plus. Bizarre pour un plugin…). Et qu’une connaissance blogueur m’a conseillé WordPress suite à mes désagréments.

L’installation de WordPress se fait les doigts dans le pif comme vous l’imaginez, par contre migrer le contenu de Dotclear dans  WordPress n’a pas été de la tarte. Il y a bien un plugin de migration dans WordPress, mais il a apparemment été écrit pour une version de Dotclear assez ancienne et ne fonctionne pas avec la 2.2. Je l’ai donc patché et j’ai pu migrer assez proprement le tout. Le seul attrape-nigaud qui reste est qu’il faut convertir tous les articles de dotclear au format xhtml avant de lancer l’import, sinon ça ne fonctionne pas.

Voici le patch à appliquer sur le plugin:

--- dotclear-importer.php    2010-06-19 18:22:27.000000000 +0100
+++ new.php    2012-02-04 14:50:59.154447247 +0000
@@ -129,7 +129,7 @@
         $dbprefix = get_option('dcdbprefix');
 
         // Get Categories
-        return $dcdb->get_results('SELECT * FROM '.$dbprefix.'categorie', ARRAY_A);
+        return $dcdb->get_results('SELECT * FROM '.$dbprefix.'category', ARRAY_A);
     }
 
     function get_dc_users()
@@ -153,9 +153,10 @@
         $dbprefix = get_option('dcdbprefix');
 
         // Get Posts
-        return $dcdb->get_results('SELECT '.$dbprefix.'post.*, '.$dbprefix.'categorie.cat_libelle_url AS post_cat_name
-                        FROM '.$dbprefix.'post INNER JOIN '.$dbprefix.'categorie
-                        ON '.$dbprefix.'post.cat_id = '.$dbprefix.'categorie.cat_id', ARRAY_A);
+        $query = 'SELECT '.$dbprefix.'post.*, '.$dbprefix.'category.cat_url AS post_cat_name '
+          . 'FROM '.$dbprefix.'post INNER JOIN '.$dbprefix.'category '
+          . 'ON '.$dbprefix.'post.cat_id = '.$dbprefix.'category.cat_id';
+        return $dcdb->get_results($query, ARRAY_A);
     }
 
     function get_dc_comments()
@@ -177,7 +178,7 @@
         set_magic_quotes_runtime(0);
         $dbprefix = get_option('dcdbprefix');
 
-        return $dcdb->get_results('SELECT * FROM '.$dbprefix.'link ORDER BY position', ARRAY_A);
+        return $dcdb->get_results('SELECT * FROM '.$dbprefix.'link ORDER BY link_position', ARRAY_A);
     }
 
     function cat2wp($categories='')
@@ -308,11 +309,11 @@
                 $uinfo = ( get_userdatabylogin( $user_id ) ) ? get_userdatabylogin( $user_id ) : 1;
                 $authorid = ( is_object( $uinfo ) ) ? $uinfo->ID : $uinfo ;
 
-                $Title = $wpdb->escape(csc ($post_titre));
-                $post_content = textconv ($post_content);
+                $Title = $wpdb->escape(csc ($post_title));
+                $post_content = textconv ($post_content_xhtml);
                 $post_excerpt = "";
-                if ($post_chapo != "") {
-                    $post_excerpt = textconv ($post_chapo);
+                if ($post_excerpt_xhtml != "") {
+                    $post_excerpt = textconv ($post_excerpt_xhtml);
                     $post_content = $post_excerpt ."\n<!--more-->\n".$post_content;
                 }
                 $post_excerpt = $wpdb->escape ($post_excerpt);
@@ -395,8 +396,8 @@
                 // WordPressify Data
                 $comment_ID = (int) ltrim($comment_id, '0');
                 $comment_post_ID = (int) $postarr[$post_id];
-                $comment_approved = $comment_pub;
-                $name = $wpdb->escape(csc ($comment_auteur));
+                $comment_approved = '1';
+                $name = $wpdb->escape(csc ($comment_author));
                 $email = $wpdb->escape($comment_email);
                 $web = "http://".$wpdb->escape($comment_site);
                 $message = $wpdb->escape(textconv ($comment_content));

Bon week-end à tous!!

Trouver un outil de statistiques

stats.jpg

Voici un problème de longue durée pour moi : trouver un outil de statistiques fiable, sans trop de bugs, sans javascript et qui est chez moi, donc pas de Google analytics ou autre mocheté du genre (et libre aussi).

J’en ai donc essayé quelques uns qui ont pignon sur rue, comme Piwik et Open Web Analytics.

Piwik a une interface assez sympathique, mais assez peu ergonomique à mon goût. La dernière fois que j’ai testé la carte du monde était encore en flash (beurk), et le tag à mettre sur le site était en javascript. De plus, l’interface très ajaxée était assez lourde à charger, et me forçait à utiliser l’application pour piwik sur mon téléphone plutôt qu’aller directement sur l’interface.

Suite à cette expérience, j’ai donc installé Open Web Analytics, dont on m’a dit du bien. L’interface est plus légère que Piwik, même si elle contient encore beaucoup d’ajax. Quelques points sont assez mal pensés, comme par exemple la section navigateur des visiteurs qui n’affiche pas de camembert des navigateurs, mais une table avec le graphe des visites. Le point le plus ennuyeux reste qu’OWA ne fonctionne pas en HTTPS (les graphes ne s’affichent pas), et qu’il y a encore beaucoup de bugs. Le tag javascript pour le blog est quant à lui très embêtant et « rafraichit » (en fait il envoie des infos en sous-main) la page toutes les 5s, ce qui est très désagréable.

Finalement j’ai donc recouru à un outil un peu moins connu que j’avais utilisé il y a assez longtemps. Il s’agit de Crawltrack, spécialisé dans l’identification des crawlers et la détection d’attaques, mais qui est aussi un outil de statistiques de visites. L’avantage, c’est que son interface est statique (pas d’ajax) et très simple. Le tag à mettre sur le site est quant à lui en PHP, et donc on a les statistiques même si le visiteur utilise noscript. De plus le tag ne pourrit pas la vie du visiteur comme celui d’OWA. Les points négatifs sont qu’on a moins d’informations qu’avec les autres (pas de mouchard en javascript), et qu’il force à avoir PHP sur le serveur.

J’ai aussi entendu parler d’AWstats qui lui est un analyseur de log d’Apache. On m’a dit qu’il était très simple et peu invasif, mais je n’ai pas encore eu le courage de l’essayer. Si jamais Crawltrack ne me satisfait pas je l’essayerais et vous donnerais mon avis!

Graphe de dannysullivan, CC-by

Beets

Si comme moi vous détestez que votre collection de musique soit mal rangée, avec des noms d’auteurs légèrement différents qui mettent le souc et des noms de musique avec des caractères bizarres, beets est fait pour vous.

Beets est en fait le couteau Suisse libre de la gestion de collection musicale. Une fois qu’on lui a précisé où se trouve sa collection, on peut importer sa musique dedans, ce qui provoque un gros nettoyage.

L’outil utilise musicbrainz et une série de plugins pour trouver les métadonnées correspondant aux morceaux que vous avez. Il calcule ensuite la similitude entre ce qu’il a trouvé et les fichiers existants pour déterminer le choix le plus pertinent. Dans la majorité des cas, la similitude est suffisante (plus de 95%), et il corrige automatiquement. Lorsqu’il est indécis il fait appel à vous.

À l’usage c’est assez simple. hormis la première importation qui peut être assez longue (collection existante), par la suite on ajoute simplement tout nouvel album qu’on acquiert avec la commande beet import qui nettoie et copie les nouveaux fichiers vers votre collection.

Pour installer beets, il vous faut pip (python-pip ou quelque chose comme ça), puis installez grâce à pip et configurez:

$ sudo pip install beets ... $ cat << ~/.beetsconfig.ini [beets] directory: ~/Music library: ~/beetslibrary.blb 

Faites ctrl+D pour sauver, puis lancer l’import de votre collection. Notez l’option -C qui indique de ne pas copier les fichiers vers sa collection (normal, ils y sont déjà):

$ beet import -C ~/Music 

Et voilà, plus qu’à répondre aux questions et être patient.

Appréciez bien votre musique!

Encore un thème pour EMACS

Edit

Petit oubli au niveau de la couleur des fonctions. Maintenant corrigé.

Au vu des commentaires de mon dernier billet, j’ai décidé de faire un nouveau thème pour EMACS, cette fois ci dans des tons pastel afin d’être plus doux et reposant pour les séances de codes prolongées.

Alors pour éviter un long discours stérile, voici ce que ça donne:

pastel.png

Et le code qui va bien:

(eval-when-compile
  (require 'color-theme))
(defun color-theme-etenil-pastel () "Etenil's dark side theme." (interactive)
  (color-theme-install
   '(color-theme-etenil-pastel
     ((foreground-color . "#cccccc")
      (background-color . "#111111")
      (background-mode . dark))
     (default ((t (nil))))
     (region ((t (:background "#444" :italic t))))
     (underline ((t (:underline t))))
     (modeline ((t (:foreground "#cccccc" :background "#333"))))
     (modeline-buffer-id ((t (:foreground "#cccccc" :background "#333"))))
     (modeline-mousable ((t (:foreground "#cccccc" :background "#333"))))
     (modeline-mousable-minor-mode ((t (:foreground "white" :background "#333" :bold t))))
     (italic ((t (:italic t))))
     (bold-italic ((t (:bold t :italic t))))
     (font-lock-comment-face ((t (:foreground "#555555"))))
     (font-lock-variable-name-face ((t (:foreground "#6688CC"))))
     (font-lock-string-face ((t (:foreground "#CC6688"))))
     (font-lock-keyword-face ((t (:foreground "#88CC66"))))
     (font-lock-builtin-face ((t (:foreground "#88CC66"))))
     (font-lock-constant-face ((t (:foreground "#CC6666" :bold t))))
     (font-lock-function-name-face ((t (:foreground "#CCCC66" :italic t))))
     (font-lock-type-face ((t (:foreground "#66CCCC" :underline t))))
     ; ERC
     (erc-current-nick-face ((t (:foreground "#CCCC66"))))
     (erc-my-nick-face ((t (:foreground "#CCCC66"))))
     (erc-default-face ((t (:foreground "#CCCCCC"))))
     (erc-keyword-face ((t (:foreground "#88CC66"))))
     (erc-input-face ((t (:foreground "#6688CC"))))
     (erc-notice-face ((t (:foreground "#555"))))
     (erc-timestamp-face ((t (:foreground "#88CC66"))))
     (erc-underline-face ((t (:foreground "c5af75"))))
     (erc-error-face ((t (:foreground "#CC6688"))))
     ; Others...
     (text-cursor ((t (:background "CCCC66" :foreground "#444"))))
     (bold ((t (:bold)))))))

J’attends vos commentaires avec impatience!

Le tout est sous CC-by.