It's probably too specific to my setup, but here it is anyway.
I keep the archive in a normal maildir, which I index with the mairix tool (you could do the same thing with maildir-utils or notmuch). New messages get put into the maildir by mutt's auto-move feature after I've read them.
Then I have a few keys bound in mutt:
macro pager,index M '<pipe-message>gmane<enter>'
macro pager,index B '<pipe-message>rmairix-gmane<enter>'
(you can tell from the names that these predate public-inbox entirely).
The "gmane" script just opens a browser pointing to the current message in the archive, from which I then 'y'ank the URL into the clipboard or pasting. The network round-trip was necessary for gmane, since the article ids were not predictable. For public-inbox, it's not necessary, but old habits die hard (and it's a nice cross-check that the link you're sending out isn't broken).
Here's that script:
-- >8 -- #!/bin/sh
mid() {
exec webview "http://public-inbox.org/git/$1"
}article() {
exec webview "http://public-inbox.org/git/?q=gmane:$1"
}find_mid() {
perl -ne 'if(/^message-id:\s*<([^>]+)>/i) { print $1, "\n"; exit 0 }'
}case "$#" in
0) id=`find_mid`
case "$id" in
"") echo >&2 "fatal: unable to extract message-id from stdin"; exit 1 ;;
*) mid "$id" ;;
esac
;;
1) case "$1" in
*@*) mid "$1" ;;
*) article "$1" ;;
esac
;;
*) echo >&2 "fatal: don't know how to handle $# arguments"; exit 100 ;;
esac
-- 8< --The "webview" command is just a personal wrapper that decides which browser to use. You could replace it with "firefox" or "chromium" or whatever.
The "rmairix-gmane" script picks out gmane/public-inbox references and re-opens them in mutt. It looks like this:
-- >8 -- #!/usr/bin/env perl use URI; use URI::Escape;
if (@ARGV) {
show_gmane_article($_) foreach @ARGV;
}
else {
while(<>) {
if (m{http://[^/]*gmane.org/[-\w/.]+}) {
show_gmane_url($&);
}
if (m{https?://public-inbox.org/git/([^/]+)}) {
show_mid(uri_unescape($1));
}
}
}
exit 0;sub show_mid {
system("rmairix -t m:" . quotemeta(shift) . " </dev/tty");
}sub show_gmane_url {
my ($group, $article) = extract_article(shift);
show_gmane_article($article);
}sub show_gmane_article {
my $article = shift;
my $mid = gmane_to_mid($article);
show_mid($mid) if defined $mid;
}sub gmane_to_mid {
my $want = shift; open(my $map, "-|", qw(gunzip -c), "$ENV{HOME}/.gmane-to-mid.gz");
while (<$map>) {
chomp;
my ($nr, $mid) = split / /, $_, 2;
return $mid if $nr == $want;
}
}sub extract_article {
my @path = URI->new(shift)->path_segments; # first one is always empty in absolute URL
shift @path unless length($path[0]);
# group is always next
my $group = shift @path;
# and then look for numbers starting from the back. E.g.,
# focus=N for threads, or just "N" for articles
while (@path) {
local $_ = pop @path;
return ($group, $&) if /\d+/;
} return ($group, undef);
}
-- 8< --
The two extra bits you'd need are:
- the ~/.gmane-to-mid.gz mapping. I don't remember if I made this
myself or stole it from one that Eric posted. I'm happy to share if
anybody wants it. - rmairix is a personal wrapper around mairix that ssh's to my imap
server to do the search and then starts mutt on the result. Naturally I also use it for general queries like
rmairix -t f:peff sanitize thread
I hope that helps. I suspect it may be more useful to people as inspiration and not as running code. I'm happy to answer any questions or give any guidance I can.
-Peff