blob: 8a54b46ea062de2129007b077f1d4e413fea508b [file] [log] [blame]
Guido van Rossumc7b68821994-04-28 09:53:33 +00001#
2# A class to hand a unix-style or mmdf-style mailboxes
3#
4# Jack Jansen, CWI, March 1994.
5#
6import rfc822
Jack Jansen97157791995-10-23 13:59:53 +00007import os
8import regex
Guido van Rossumc7b68821994-04-28 09:53:33 +00009
10class _Mailbox:
11 def __init__(self, fp):
12 self.fp = fp
13 self.seekp = 0
14
15 def seek(self, pos):
16 self.seekp = pos
17
18 def next(self):
19 while 1:
20 self.fp.seek(self.seekp)
21 try:
22 self._search_start()
23 except EOFError:
24 self.seekp = self.fp.tell()
25 return None
26 start = self.fp.tell()
27 self._search_end()
28 self.seekp = stop = self.fp.tell()
29 if start <> stop:
30 break
31 return rfc822.Message(_Subfile(self.fp, start, stop))
32
33class _Subfile:
34 def __init__(self, fp, start, stop):
35 self.fp = fp
36 self.start = start
37 self.stop = stop
38 self.pos = self.start
39
Guido van Rossum2922c6d1994-05-06 14:28:19 +000040 def read(self, length = None):
Guido van Rossumc7b68821994-04-28 09:53:33 +000041 if self.pos >= self.stop:
42 return ''
Guido van Rossum2922c6d1994-05-06 14:28:19 +000043 if length is None:
Guido van Rossumc7b68821994-04-28 09:53:33 +000044 length = self.stop - self.pos
Guido van Rossumc7b68821994-04-28 09:53:33 +000045 self.fp.seek(self.pos)
46 self.pos = self.pos + length
47 return self.fp.read(length)
48
Guido van Rossum2922c6d1994-05-06 14:28:19 +000049 def readline(self, length = None):
Guido van Rossumc7b68821994-04-28 09:53:33 +000050 if self.pos >= self.stop:
51 return ''
Guido van Rossum2922c6d1994-05-06 14:28:19 +000052 if length is None:
Guido van Rossumc7b68821994-04-28 09:53:33 +000053 length = self.stop - self.pos
Guido van Rossumc7b68821994-04-28 09:53:33 +000054 self.fp.seek(self.pos)
55 data = self.fp.readline(length)
56 if len(data) < length:
57 length = len(data)
58 self.pos = self.pos + length
59 return data
60
61 def tell(self):
62 return self.pos - self.start
63
Jack Jansen97157791995-10-23 13:59:53 +000064 def seek(self, pos, whence=0):
65 if whence == 0:
66 self.pos = self.start + pos
67 elif whence == 1:
68 self.pos = self.pos + pos
69 elif whence == 2:
70 self.pos = self.stop + pos
Guido van Rossumc7b68821994-04-28 09:53:33 +000071
72 def close(self):
73 pass
74
75class UnixMailbox(_Mailbox):
76 def _search_start(self):
77 while 1:
78 line = self.fp.readline()
79 if not line:
80 raise EOFError
81 if line[:5] == 'From ':
82 return
83
84 def _search_end(self):
85 while 1:
86 pos = self.fp.tell()
87 line = self.fp.readline()
88 if not line:
89 return
90 if line[:5] == 'From ':
91 self.fp.seek(pos)
92 return
93
94class MmdfMailbox(_Mailbox):
95 def _search_start(self):
96 while 1:
97 line = self.fp.readline()
98 if not line:
99 raise EOFError
100 if line[:5] == '\001\001\001\001\n':
101 return
102
103 def _search_end(self):
104 while 1:
105 pos = self.fp.tell()
106 line = self.fp.readline()
107 if not line:
108 return
109 if line == '\001\001\001\001\n':
110 self.fp.seek(pos)
111 return
112
Jack Jansen97157791995-10-23 13:59:53 +0000113class MHMailbox:
114 def __init__(self, dirname):
115 pat = regex.compile('^[0-9][0-9]*$')
116 self.dirname = dirname
117 files = os.listdir(self.dirname)
118 self.boxes = []
119 for f in files:
120 if pat.match(f) == len(f):
121 self.boxes.append(f)
122
123 def next(self):
124 if not self.boxes:
125 return None
126 fn = self.boxes[0]
127 del self.boxes[0]
128 fp = open(os.path.join(self.dirname, fn))
129 return rfc822.Message(fp)
130
131
Guido van Rossumc7b68821994-04-28 09:53:33 +0000132if __name__ == '__main__':
133 import posix
134 import time
135 import sys
136 import string
Jack Jansen97157791995-10-23 13:59:53 +0000137## mbox = '/usr/mail/'+posix.environ['USER']
138## fp = open(mbox, 'r')
139## mb = UnixMailbox(fp)
140
141 mbox = posix.environ['HOME']+'/Mail/inbox'
142 mb = MHMailbox(mbox)
143
Guido van Rossumc7b68821994-04-28 09:53:33 +0000144 msgs = []
145 while 1:
146 msg = mb.next()
147 if not msg:
148 break
149 msgs.append(msg)
150 if len(sys.argv) > 1:
151 num = string.atoi(sys.argv[1])
152 print 'Message %d body:'%num
153 msg = msgs[num-1]
154 msg.rewindbody()
155 sys.stdout.write(msg.fp.read())
156 sys.exit(0)
157 print 'Mailbox',mbox,'has',len(msgs),'messages:'
158 for msg in msgs:
159 f = msg.getheader('from')
160 s = msg.getheader('subject')
161 d = (msg.getheader('date'))
162 print '%20.20s %18.18s %-30.30s'%(f, d[5:], s)
163