Blog
Berkeley is famous for LSD and BSD UNIX. I don't think that it is a coincidence.
Adieu castget, vive poca
Pour charger mes podcasts, j'utilisais https://castget.johndal.com/. Depuis quelques années, les outils de « balado-diffusion » semblent s'éloigner des standards du Web. En particulier, certains spécifient le même fichier avec des paramètres /file?param=value
, ce que castget ne sait pas gérer. Comme il avait d'autres limitations (renommage des épisodes téléchargés), je teste https://github.com/brokkr/poca.
Et pour réécrire mes souscriptions, voici un script trivial :
#!/usr/bin/env python3 # import configparser config = configparser.ConfigParser() config.read('castgetrc') for entry in config.sections(): output, url, title, album, artist = '', '', '', '', '' for key in config[entry]: if 'url' == key: url = config[entry][key] elif 'spool' == key: title = config[entry][key].split('/')[-1] elif 'id3album' == key: album = config[entry][key].strip('"') elif 'id3leadartist' == key: artist = config[entry][key] if 0 == len(album): album = entry output += ' <!-- =========================== -->\n' output += ' <subscription category="Podcasts">\n' output += ' <title>' + title + '</title>\n' output += ' <url>' + url + '</url>\n' output += ' <from_the_top>yes</from_the_top>\n' output += ' <rename divider="_" space="_">\n' output += ' <episode_title/>\n' output += ' <date/>\n' output += ' </rename>\n' output += ' <metadata>\n' output += ' <album>' + album + '</album>\n' if 0 < len(artist): output += ' <artist>' + artist + '</artist>\n' output += ' </metadata>\n' output += ' </subscription>\n' print(output)
Mutt, folder_browser et ordre
Lorsqu'on utilise des Maildir, Mutt n'est pas capable de trier correctement les boîtes (folders) par date de dernière modification. Il existe un patch (cf. https://dev.mutt.org/trac/wiki/PatchList, chercher maildir-mtime
) pour les versions 1.4 et 1.5 de Mutt ; je n'ai pas testé.
Pour rappel :
- un maildir se présente comme un répertoire contenant trois sous-répertoires
cur/
,new/
ettmp/
; - les messages arrivent dans
tmp/
; - une fois reçus, ils sont « copiés » dans
new/
; - lorsque le MUA parcoure la boîte, il les « déplace » dans
cur/
.
Il n'y a ni déplacement ni copie mais ça n'est pas le sujet. Bref, à la fin, le mtime et l'atime de ces trois sous-répertoires a changé… mais pas ceux du répertoire parent, justement le répertoire que l'on voudrait voir modifié !
Mutt a pourtant une option sort_browser
:
- .muttrc
set sort_browser=reverse-date
Pour l'exploiter, il faut que les maildirs voient leur mtime changé. Pour cela, utilisons le script suivant :
- mtime_maildirs
#!/usr/bin/env perl # # $Id: 3fe93bc26d54c058edfb7a25d4667f887b1e8f8d $ # use Getopt::Std; use File::stat; if ( $#ARGV == 0 ) { exit 1; } else { my %opts; getopts( 'd:', \%opts ); opendir( MD, $opts{'d'} ) or die "$opts{'d'}: $?\n"; foreach ( sort readdir(MD) ) { if ( -d "$opts{'d'}/$_/new" and -d "$opts{'d'}/$_/cur" and -d "$opts{'d'}/$_/tmp" ) { my $mtime = stat("$opts{'d'}/$_/new")->mtime; utime( $mtime, $mtime, "$opts{'d'}/$_" ) or do { warn "$_: $?\n"; } } } closedir(MD); }
Il attend une option -d path/to/maildir/collection
et change le mtime des maildirs trouvés1) à partir de celui de leur new/
.
À utiliser avec cron(8)
ou via OfflineIMAP avec postsynchook
par exemple :
- .offlineimaprc
[account foo] ... postsynchook = mtime_maildirs -d ~/mail/foo/ && notmuch new
Et voilà, lorsqu'on veut changer de maildir ou lorsqu'on déplace des messages en sélectionnant un maildir de destination, les plus « récents » apparaissent en premier (voir folder_format
pour choisir les informations à afficher).
Tenir ses notes à jour, vim à la rescousse
Commençons par les notes : soit un répertoire log/
(au milieu d'un dépôt Git, il va sans dire) dans le lequel je crée un répertoire par mois ; en ce moment, je travaille dans log/2016-06/
. Dans chacun de ces répertoires, j'ai un fichier par jour ; aujourd'hui 8 juin 2016, j'ai édité log/2016-06/08
. Dans ces fichiers texte, je note (un peu pêle-mêle) mes activités de la journée, des notes de lecture, etc.
Au fil du temps, mes fichiers sont de plus en plus formatés ; j'ai tenté Markdown et orgmode sans être convaincu. Du coup, je nomme mes fichiers .dl
(comme daily log, j'étais inspiré…) et j'ai défini un fichier de syntaxe Vim.
Un fichier type se présente comme suit :
# $Id: 00a0d740eb33b69967c9e84ef53de06e91b26a60$ # * Journée - première activité pas tout à fait triviale détails divers - seconde activité, cf. [tkt #1234] {1h} - lecture, notes diverses - [[http://vimdoc.sourceforge.net/htmldoc/usr_44.html][Your own syntax highlighted]] - réunion "titre supra sérieux" {1h30} * discussion homérique sur la taille de l'étiquette * quadricapilosection sur la couleur de l'étiquette * ... - dernière activité technique, cf. [tkt #1235] * détail *vraiment intéressant* impliquant `du code en ligne` | code en bloc... | code en bloc encore... * TODO - tâche prévue no1 - tâche prévue no2 - finir tâches d'hier ! * Perso - prendre du pain
Dans ~/.vim/ftdetect/dl.vim
, ajoutons notre nouveau type :
- ~/.vim/ftdetect/dl.vim
autocmd BufNewFile,BufRead *.dl set filetype=dl
Dans ~/.vim/ftdetect/dl.vim
, définissons la syntaxe et les couleurs :
- ~/ftplugin/dl.vim
" Vim syntax file " Language: Dayly Log files " Maintainer: Pascal Cabaud " Last Change: 2016-06-08 if !exists("main_syntax") if exists("b:current_syntax") finish endif let main_syntax = 'dl' endif " to avoid portability problems set magic " case sensitive syntax case match syn keyword dlTodo TODO FIXME XXX NOTE: NB: PS: DONE syn match dlSections /^\* .*$/ syn match dlComment /^\#.*$/ contains=dlTodo syn match dlBold /\*\w[^\*]*\w\*/ syn match dlTickets /\[\(tkt\|dsi\|eila\|rdm\) \#\(\d\+\|XXX\)\]/ contains=dlTodo syn match dlCode /^\s\{2,}|\s.*$/ syn match dlTime /{\d*\(h\d*\|mn\)}/ syn match dlTask /^\s\{2}- .*$/ contains=dlTickets,dlTime,dlCode,dlTodo,dlString,dlBold syn match dlUrl /\[\[[[:alpha:]\+]*:\/\/[^\]]*\]\[[^\]]*\]\]/ syn region dlString start='"' end='"' syn region dlCode start='`' end='`' hi def link dlTodo Todo hi def link dlSections Delimiter hi def link dlComment Comment hi def link dlTickets Identifier hi def link dlString String hi def link dlTime PreProc hi def link dlCode Typedef hi def link dlTask Keyword hi def link dlBold Todo hi def link dlUrl PreProc
Et voilà :
Tips Mutt et GnuPG
J'utilise GnuPG et depuis de longues années, je trainais dans mon .muttrc
des options diverses autant que nombreuses jusqu'à ce que je découvre crypt_use_gpgme. Il ne reste plus alors qu'à indiquer la clef par défaut et quelques préférences pour ne plus avoir que :
- .muttrc
set crypt_autosign=yes set crypt_replysign=yes set crypt_replysignencrypted=yes set crypt_use_gpgme set pgp_sign_as=0x7034D172
plus besoin des options pgp_…_command
.
Si on utilise Mutt avec un backend IMAP ou POP et/ou si on envoie les mails sans passer par daemon local, il faut s'authentifier. Pour ne pas taper de mot de passe à longueur de temps, on peut utiliser imap_pass
, pop_pass
et smtp_pass
. Oui, mais un mot de passe dans un fichier de configuration, saymal©™ ! Utilisons plutôt un script et des variables personnalisées :
- Mutt permet de lancer un script dans sa configuration avec quelque chose comme :
- .muttrc
source "macommande |"
(bien noter le pipe à la fin) et dont la sortie constitue des directives de configuration (commands dans la terminologie Mutt).
- Mutt accepte des variables personnalisées sous réserve qu'elles se nomment
my_…
Pour gérer mes mots de passe, j'utilise passwod store qui stocke les mots de passe dans des fichiers chiffrés avec GnuPG (et versionne le tout avec Git).
Soit donc le script trivial :
- mutt_passwds.sh
#!/bin/sh /bin/echo -n "set my_pass_back1=" && pass show work/back1-mailhost
Dans mon ${HOME}/.muttrc
, plus qu'à ajouter :
- .muttrc
source "~/bin/mutt_passwds.sh |" ... set smtp_url="smtps://account1@server1.at.work" set smtp_pass=$my_pass_back1
Évidemment, rien n'oblige à se limiter à une seule variable my_pass_back1
, par exemple si on utilise les folder hooks mais c'est une autre histoire !
Pour conclure, au lancement Mutt appelle pass(1)
qui lance GnuPG ; comme on a configuré ce dernier pour utiliser un agent et un « pinentry program » (cf. OfflineIMAP et password store), une invite de saisie de la passphrase s'ouvre lorsqu'il est nécessaire.
cur
, new
et tmp
est un maildir.