notmuch-mutt: support for messages that lack Message-ID headers
authorStefano Zacchiroli <zack@upsilon.cc>
Sun, 15 Feb 2015 12:39:08 +0000 (13:39 +0100)
committerDavid Bremner <david@tethera.net>
Mon, 16 Feb 2015 12:58:13 +0000 (08:58 -0400)
For those messages, compute a synthetic Message-ID based on the SHA1
of the whole message, in the same way that notmuch would do. See:
http://git.notmuchmail.org/git/notmuch/blob/HEAD:/lib/sha1.c

To do the above, rewrite get_message_id() to accumulate header lines,
parse them to check for Message-ID, and fallback to SHA1 computation
if it is not present.

Thanks to:
- Jan N. Klug for preliminary versions of this patch
- Tomi Ollila for suggesting an elegant implementation

contrib/notmuch-mutt/README
contrib/notmuch-mutt/notmuch-mutt

index c6614470e38fc3982db0a12881f243a638a061ca..9c3379eb0015121b26a8d38684bfbc1304227da5 100644 (file)
@@ -33,9 +33,11 @@ Requirements
 
 To *run* notmuch-mutt you will need Perl with the following libraries:
 
+- Digest::SHA <https://metacpan.org/release/Digest-SHA>
+  (Debian package: libdigest-sha-perl)
 - Mail::Box <https://metacpan.org/pod/Mail::Box>
   (Debian package: libmail-box-perl)
-- Mail::Internet <https://metacpan.org/pod/Mail::Internet>
+- Mail::Header <https://metacpan.org/pod/Mail::Header>
   (Debian package: libmailtools-perl)
 - String::ShellQuote <https://metacpan.org/pod/String::ShellQuote>
   (Debian package: libstring-shellquote-perl)
index 6d4d60c74cf870dc4797993e21a46200a51a70d9..126cbf4444da0cf0585b3aceb696075fab57d18e 100755 (executable)
@@ -13,11 +13,12 @@ use warnings;
 
 use File::Path;
 use Getopt::Long qw(:config no_getopt_compat);
-use Mail::Internet;
+use Mail::Header;
 use Mail::Box::Maildir;
 use Pod::Usage;
 use String::ShellQuote;
 use Term::ReadLine;
+use Digest::SHA;
 
 
 my $xdg_cache_dir = "$ENV{HOME}/.cache";
@@ -75,10 +76,29 @@ sub prompt($$) {
 }
 
 sub get_message_id() {
-    my $mail = Mail::Internet->new(\*STDIN);
-    my $mid = $mail->head->get("message-id") or return undef;
-    $mid =~ /^<(.*)>$/;        # get message-id value
-    return $1;
+    my $mid = undef;
+    my @headers = ();
+
+    while (<STDIN>) {  # collect header lines in @headers
+       push(@headers, $_);
+       last if $_ =~ /^$/;
+    }
+    my $head = Mail::Header->new(\@headers);
+    $mid = $head->get("message-id") or undef;
+
+    if ($mid) {  # Message-ID header found
+       $mid =~ /^<(.*)>$/;  # extract message id
+       $mid = $1;
+    } else {  # Message-ID header not found, synthesize a message id
+             # based on SHA1, as notmuch would do.  See:
+             # http://git.notmuchmail.org/git/notmuch/blob/HEAD:/lib/sha1.c
+       my $sha = Digest::SHA->new(1);
+       $sha->add($_) foreach(@headers);
+       $sha->addfile(\*STDIN);
+       $mid = 'notmuch-sha1-' . $sha->hexdigest;
+    }
+
+    return $mid;
 }
 
 sub search_action($$$@) {