summaryrefslogtreecommitdiff
path: root/email-print-mime-structure
diff options
context:
space:
mode:
Diffstat (limited to 'email-print-mime-structure')
-rwxr-xr-xemail-print-mime-structure77
1 files changed, 77 insertions, 0 deletions
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), '└')