mirror of https://github.com/python/cpython
160 lines
4.7 KiB
Python
Executable File
160 lines
4.7 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
|
|
# View a single MIME multipart message.
|
|
# Display each part as a box.
|
|
|
|
import os
|
|
import sys
|
|
import getopt
|
|
import mailbox
|
|
from tkinter import *
|
|
from tkinter.scrolledtext import ScrolledText
|
|
|
|
MBOXPATH = os.environ['HOME'] + '/Mail'
|
|
|
|
class Error(Exception):
|
|
pass
|
|
|
|
def getcurrent(self):
|
|
"""Return the current message. Raise Error when there is none."""
|
|
seqs = self.get_sequences()
|
|
try:
|
|
return max(seqs['cur'])
|
|
except (ValueError, KeyError):
|
|
raise Error("no cur message")
|
|
|
|
|
|
class MimeViewer:
|
|
def __init__(self, parent, title, msg):
|
|
self.title = title
|
|
self.msg = msg
|
|
self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
|
|
self.frame.packing = {'expand': 0, 'fill': 'both'}
|
|
self.button = Checkbutton(self.frame,
|
|
{'text': title,
|
|
'command': self.toggle})
|
|
self.button.pack({'anchor': 'w'})
|
|
headertext = []
|
|
for item in msg.items():
|
|
headertext.append("%s: %s" % item)
|
|
headertext = '\n'.join(headertext)
|
|
height = countlines(headertext, 4)
|
|
if height:
|
|
self.htext = ScrolledText(self.frame,
|
|
{'height': height,
|
|
'width': 80,
|
|
'wrap': 'none',
|
|
'relief': 'raised',
|
|
'bd': 2})
|
|
self.htext.packing = {'expand': 1, 'fill': 'both',
|
|
'after': self.button}
|
|
self.htext.insert('end', headertext)
|
|
else:
|
|
self.htext = Frame(self.frame,
|
|
{'relief': 'raised', 'bd': 2})
|
|
self.htext.packing = {'side': 'top',
|
|
'ipady': 2,
|
|
'fill': 'x',
|
|
'after': self.button}
|
|
body = msg.get_payload()
|
|
if type(body) == str:
|
|
self.pad = None
|
|
height = countlines(body, 10)
|
|
if height:
|
|
self.btext = ScrolledText(self.frame,
|
|
{'height': height,
|
|
'width': 80,
|
|
'wrap': 'none',
|
|
'relief': 'raised',
|
|
'bd': 2})
|
|
self.btext.packing = {'expand': 1,
|
|
'fill': 'both'}
|
|
self.btext.insert('end', body)
|
|
else:
|
|
self.btext = None
|
|
self.parts = None
|
|
else:
|
|
self.pad = Frame(self.frame,
|
|
{'relief': 'flat', 'bd': 2})
|
|
self.pad.packing = {'side': 'left', 'ipadx': 10,
|
|
'fill': 'y', 'after': self.htext}
|
|
self.parts = []
|
|
for i in range(len(body)):
|
|
p = MimeViewer(self.frame,
|
|
'%s.%d' % (title, i+1),
|
|
body[i])
|
|
self.parts.append(p)
|
|
self.btext = None
|
|
self.collapsed = 1
|
|
def pack(self):
|
|
self.frame.pack(self.frame.packing)
|
|
def destroy(self):
|
|
self.frame.destroy()
|
|
def show(self):
|
|
if self.collapsed:
|
|
self.button.invoke()
|
|
def toggle(self):
|
|
if self.collapsed:
|
|
self.explode()
|
|
else:
|
|
self.collapse()
|
|
def collapse(self):
|
|
self.collapsed = 1
|
|
for comp in self.htext, self.btext, self.pad:
|
|
if comp:
|
|
comp.forget()
|
|
if self.parts:
|
|
for part in self.parts:
|
|
part.frame.forget()
|
|
self.frame.pack({'expand': 0})
|
|
def explode(self):
|
|
self.collapsed = 0
|
|
for comp in self.htext, self.btext, self.pad:
|
|
if comp: comp.pack(comp.packing)
|
|
if self.parts:
|
|
for part in self.parts:
|
|
part.pack()
|
|
self.frame.pack({'expand': 1})
|
|
|
|
def countlines(str, limit):
|
|
i = 0
|
|
n = 0
|
|
while n < limit:
|
|
i = str.find('\n', i)
|
|
if i < 0: break
|
|
n = n+1
|
|
i = i+1
|
|
return n
|
|
|
|
def main():
|
|
opts, args = getopt.getopt(sys.argv[1:], '')
|
|
for o, a in opts:
|
|
pass
|
|
message = None
|
|
folder = 'inbox'
|
|
for arg in args:
|
|
if arg[:1] == '+':
|
|
folder = arg[1:]
|
|
else:
|
|
message = int(arg)
|
|
|
|
mh = mailbox.MH(MBOXPATH)
|
|
f = mh.get_folder(folder)
|
|
if message is None:
|
|
message = getcurrent(f)
|
|
m = mailbox.MHMessage(f.get(message))
|
|
|
|
root = Tk()
|
|
tk = root.tk
|
|
|
|
top = MimeViewer(root, '+%s/%d' % (folder, message), m)
|
|
top.pack()
|
|
top.show()
|
|
|
|
root.minsize(1, 1)
|
|
|
|
tk.mainloop()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|