#!/usr/bin/env python # -*- coding: utf-8 -*- # Author: Daniel Kahn Gillmor # License: GPLv3+ # 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" from __future__ import print_function 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), '└')