Package: mailscripts Version: 0.10-1 Severity: wishlist Tags: patch Hi!
notmuch has held the `printmimestructure` utility in its source repo for a half-dozen years, but we've never shipped it and made it accessible to non-developers. It's pretty handy for debugging e-mail formatting issues and writing specifications about e-mail, so i want to contribute it to mailscripts. I've imported the original history from the notmuch repo, cleaned up the source a little bit, renamed it `email-print-mime-structure` (to match the "conventions" we're starting to establish in mailscripts), and added a manpage for it. This is on the "email-print-mime-structure" branch at https://salsa.debian.org/dkg/mailscripts.git -- maybe you can merge from there directly? I'm attaching a monolithic patch here, but the series on that branch is a more sensible thing to merge, as it preserves history and some justifications in the commit messages that could be handy in future code archeology. Please adopt! If you don't want me to maintain it in mailscrits, i'll continue keeping it in the `notmuch` tree, but i'd really rather it be easier for others to get at. See also: https://salsa.debian.org/dkg/mailscripts/merge_requests/2 (if you want to put mailscripts into a shared repo on salsa, i'd be happy to make merge requests against it directly for things like this, let me know what workflow you prefer) --dkg
diff --git a/Makefile b/Makefile index 48cb2fa..352f6f0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,7 @@ MANPAGES=mdmv.1 mbox2maildir.1 \ notmuch-slurp-debbug.1 notmuch-extract-patch.1 maildir-import-patch.1 \ email-extract-openpgp-certs.1 \ + email-print-mime-structure.1 \ notmuch-import-patch.1 all: $(MANPAGES) @@ -10,5 +11,6 @@ clean: %.1: %.1.pod pod2man --section=1 --date="Debian Project" --center="User Commands" \ + --utf8 \ --name=$(subst .1,,$@) \ $^ $@ diff --git a/debian/control b/debian/control index 8667a6c..6d3a54f 100644 --- a/debian/control +++ b/debian/control @@ -55,3 +55,7 @@ Description: collection of scripts for manipulating e-mail on Debian maildir-import-patch -- import a git patch series into a maildir . notmuch-import-patch -- import a git patch series into notmuch + . + email-print-mime-structure -- tree view of a message's MIME structure + . + email-extract-openpgp-certs -- extract OpenPGP certificates from a message diff --git a/debian/mailscripts.install b/debian/mailscripts.install index d6f69f5..99216c1 100644 --- a/debian/mailscripts.install +++ b/debian/mailscripts.install @@ -5,3 +5,4 @@ maildir-import-patch /usr/bin notmuch-import-patch /usr/bin notmuch-extract-patch/notmuch-extract-patch /usr/bin email-extract-openpgp-certs /usr/bin +email-print-mime-structure /usr/bin diff --git a/debian/mailscripts.manpages b/debian/mailscripts.manpages index ab761b2..6d7cb30 100644 --- a/debian/mailscripts.manpages +++ b/debian/mailscripts.manpages @@ -5,3 +5,4 @@ maildir-import-patch.1 notmuch-import-patch.1 notmuch-extract-patch.1 email-extract-openpgp-certs.1 +email-print-mime-structure.1 diff --git a/email-print-mime-structure b/email-print-mime-structure new file mode 100755 index 0000000..7adeb2b --- /dev/null +++ b/email-print-mime-structure @@ -0,0 +1,77 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright (C) 2019 Daniel Kahn Gillmor +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or (at +# your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. +''' +This script reads a MIME message from stdin and produces a treelike +representation on it stdout. + +Example: +0 dkg@alice:~$ printmimestructure < 'Maildir/cur/1269025522.M338697P12023.monkey,S=6459,W=6963:2,Sa' +└┬╴multipart/signed 6546 bytes + ├─╴text/plain inline 895 bytes + └─╴application/pgp-signature inline [signature.asc] 836 bytes +0 dkg@alice:~$ + +If you want to number the parts, i suggest piping the output through +something like "cat -n" +''' +import email +import sys + +def print_part(z, prefix): + fname = '' if z.get_filename() is None else ' [' + z.get_filename() + ']' + cset = '' if z.get_charset() is None else ' (' + z.get_charset() + ')' + disp = z.get_params(None, header='Content-Disposition') + if (disp is None): + disposition = '' + else: + disposition = '' + for d in disp: + if d[0] in [ 'attachment', 'inline' ]: + disposition = ' ' + d[0] + if z.is_multipart(): + nbytes = len(z.as_string()) + else: + nbytes = len(z.get_payload()) + + print('{}{}{}{}{} {:d} bytes'.format( + prefix, + z.get_content_type(), + cset, + disposition, + fname, + nbytes, + )) + +def test(z, prefix=''): + if (z.is_multipart()): + print_part(z, prefix+'┬╴') + if prefix.endswith('└'): + prefix = prefix.rpartition('└')[0] + ' ' + if prefix.endswith('├'): + prefix = prefix.rpartition('├')[0] + '│' + parts = z.get_payload() + i = 0 + while (i < parts.__len__()-1): + test(parts[i], prefix + '├') + i += 1 + test(parts[i], prefix + '└') + # FIXME: show epilogue? + else: + print_part(z, prefix+'─╴') + +test(email.message_from_file(sys.stdin), '└') diff --git a/email-print-mime-structure.1.pod b/email-print-mime-structure.1.pod new file mode 100644 index 0000000..ab1ec05 --- /dev/null +++ b/email-print-mime-structure.1.pod @@ -0,0 +1,62 @@ +=encoding utf8 + +=head1 NAME + +email-print-mime-structure - display a tree-like view of the MIME structure of an e-mail + +=head1 SYNOPSIS + +B<email-print-mime-structure> <B<message.eml> + +=head1 DESCRIPTION + +B<email-print-mime-structure> reads a MIME message from stdin and +produces a treelike representation to stdout. + +If the user wants the parts numbered, they can feed the output through +something like "cat -n". + + +=head1 OPTIONS + +None. + +=head1 EXAMPLE + +=over 4 + + $ email-print-mime-structure <test.eml + └┬╴multipart/signed 6546 bytes + ├─╴text/plain inline 895 bytes + └─╴application/pgp-signature inline [signature.asc] 836 bytes + +=back + +=head1 LIMITATIONS + +B<email-print-mime-structure> currently does not try to decrypt +encrypted e-mails, so it cannot display the MIME structure that is +inside the message's cryptographic envelope. + +B<email-print-mime-structure>'s output is not stable, and is not +intended to be interpreted by machines, so please do not depend on it +in scripts! + +B<email-print-mime-structure> displays some data from within the +e-mail, but does not sanitize it before display. Some particularly +cleverly-malformed MIME parameters might be able to induce apparent +formatting changes or emit arbitrary characters to stdout. + +B<email-print-mime-structure> expects to be run in a UTF-8-friendly +environment. + +=head1 SEE ALSO + +https://tools.ietf.org/html/rfc2045, https://tools.ietf.org/html/rfc2049 + +=head1 AUTHOR + +B<email-print-mime-structure> and this manpage were written by Daniel +Kahn Gillmor and Jameson Graef Rollins, with suggestions and feedback +from many others in the community that develops the notmuch mail user +agent. It originated in the notmuch source tree.
signature.asc
Description: PGP signature