1#! /usr/bin/env python
2
3# View a single MIME multipart message.
4# Display each part as a box.
5
6import string
7from types import *
8from Tkinter import *
9from ScrolledText import ScrolledText
10
11class MimeViewer:
12    def __init__(self, parent, title, msg):
13        self.title = title
14        self.msg = msg
15        self.frame = Frame(parent, {'relief': 'raised', 'bd': 2})
16        self.frame.packing = {'expand': 0, 'fill': 'both'}
17        self.button = Checkbutton(self.frame,
18                             {'text': title,
19                              'command': self.toggle})
20        self.button.pack({'anchor': 'w'})
21        headertext = msg.getheadertext(
22                lambda x: x != 'received' and x[:5] != 'x400-')
23        height = countlines(headertext, 4)
24        if height:
25            self.htext = ScrolledText(self.frame,
26                              {'height': height,
27                               'width': 80,
28                               'wrap': 'none',
29                               'relief': 'raised',
30                               'bd': 2})
31            self.htext.packing = {'expand': 1, 'fill': 'both',
32                                  'after': self.button}
33            self.htext.insert('end', headertext)
34        else:
35            self.htext = Frame(self.frame,
36                               {'relief': 'raised', 'bd': 2})
37            self.htext.packing = {'side': 'top',
38                                  'ipady': 2,
39                                  'fill': 'x',
40                                  'after': self.button}
41        body = msg.getbody()
42        if type(body) == StringType:
43            self.pad = None
44            height = countlines(body, 10)
45            if height:
46                self.btext = ScrolledText(self.frame,
47                                  {'height': height,
48                                   'width': 80,
49                                   'wrap': 'none',
50                                   'relief': 'raised',
51                                   'bd': 2})
52                self.btext.packing = {'expand': 1,
53                                      'fill': 'both'}
54                self.btext.insert('end', body)
55            else:
56                self.btext = None
57            self.parts = None
58        else:
59            self.pad = Frame(self.frame,
60                             {'relief': 'flat', 'bd': 2})
61            self.pad.packing = {'side': 'left', 'ipadx': 10,
62                                'fill': 'y', 'after': self.htext}
63            self.parts = []
64            for i in range(len(body)):
65                p = MimeViewer(self.frame,
66                               '%s.%d' % (title, i+1),
67                               body[i])
68                self.parts.append(p)
69            self.btext = None
70        self.collapsed = 1
71    def pack(self):
72        self.frame.pack(self.frame.packing)
73    def destroy(self):
74        self.frame.destroy()
75    def show(self):
76        if self.collapsed:
77            self.button.invoke()
78    def toggle(self):
79        if self.collapsed:
80            self.explode()
81        else:
82            self.collapse()
83    def collapse(self):
84        self.collapsed = 1
85        for comp in self.htext, self.btext, self.pad:
86            if comp:
87                comp.forget()
88        if self.parts:
89            for part in self.parts:
90                part.frame.forget()
91        self.frame.pack({'expand': 0})
92    def explode(self):
93        self.collapsed = 0
94        for comp in self.htext, self.btext, self.pad:
95            if comp: comp.pack(comp.packing)
96        if self.parts:
97            for part in self.parts:
98                part.pack()
99        self.frame.pack({'expand': 1})
100
101def countlines(str, limit):
102    i = 0
103    n = 0
104    while  n < limit:
105        i = string.find(str, '\n', i)
106        if i < 0: break
107        n = n+1
108        i = i+1
109    return n
110
111def main():
112    import sys
113    import getopt
114    import mhlib
115    opts, args = getopt.getopt(sys.argv[1:], '')
116    for o, a in opts:
117        pass
118    message = None
119    folder = 'inbox'
120    for arg in args:
121        if arg[:1] == '+':
122            folder = arg[1:]
123        else:
124            message = string.atoi(arg)
125
126    mh = mhlib.MH()
127    f = mh.openfolder(folder)
128    if not message:
129        message = f.getcurrent()
130    m = f.openmessage(message)
131
132    root = Tk()
133    tk = root.tk
134
135    top = MimeViewer(root, '+%s/%d' % (folder, message), m)
136    top.pack()
137    top.show()
138
139    root.minsize(1, 1)
140
141    tk.mainloop()
142
143if __name__ == '__main__': main()
144