Commits

Guido van Rossum  committed 2197dd2

Jack's module for parsing UNIX mailbox files

  • Participants
  • Parent commits b344354
  • Branches legacy-trunk

Comments (0)

Files changed (1)

File Lib/mailbox.py

+#
+# A class to hand a unix-style or mmdf-style mailboxes
+#
+# Jack Jansen, CWI, March 1994.
+#
+import rfc822
+
+class _Mailbox:
+	def __init__(self, fp):
+		self.fp = fp
+		self.seekp = 0
+
+	def seek(self, pos):
+		self.seekp = pos
+
+	def next(self):
+		while 1:
+			self.fp.seek(self.seekp)
+			try:
+				self._search_start()
+			except EOFError:
+				self.seekp = self.fp.tell()
+				return None
+			start = self.fp.tell()
+			self._search_end()
+			self.seekp = stop = self.fp.tell()
+			if start <> stop:
+				break
+		return rfc822.Message(_Subfile(self.fp, start, stop))
+
+class _Subfile:
+	def __init__(self, fp, start, stop):
+		self.fp = fp
+		self.start = start
+		self.stop = stop
+		self.pos = self.start
+
+	def read(self, *args):
+		if self.pos >= self.stop:
+			return ''
+		if args == ():
+			length = self.stop - self.pos
+		else:
+			length = args[0]
+		self.fp.seek(self.pos)
+		self.pos = self.pos + length
+		return self.fp.read(length)
+
+	def readline(self, *args):
+		if self.pos >= self.stop:
+			return ''
+		if args == ():
+			length = self.stop - self.pos
+		else:
+			length = args[0]
+		self.fp.seek(self.pos)
+		data = self.fp.readline(length)
+		if len(data) < length:
+			length = len(data)
+		self.pos = self.pos + length
+		return data
+
+	def tell(self):
+		return self.pos - self.start
+
+	def seek(self, pos):
+		self.pos = pos + self.start
+
+	def close(self):
+		pass
+
+class UnixMailbox(_Mailbox):
+	def _search_start(self):
+		while 1:
+			line = self.fp.readline()
+			if not line:
+				raise EOFError
+			if line[:5] == 'From ':
+				return
+
+	def _search_end(self):
+		while 1:
+			pos = self.fp.tell()
+			line = self.fp.readline()
+			if not line:
+				return
+			if line[:5] == 'From ':
+				self.fp.seek(pos)
+				return
+
+class MmdfMailbox(_Mailbox):
+	def _search_start(self):
+		while 1:
+			line = self.fp.readline()
+			if not line:
+				raise EOFError
+			if line[:5] == '\001\001\001\001\n':
+				return
+
+	def _search_end(self):
+		while 1:
+			pos = self.fp.tell()
+			line = self.fp.readline()
+			if not line:
+				return
+			if line == '\001\001\001\001\n':
+				self.fp.seek(pos)
+				return
+
+if __name__ == '__main__':
+	import posix
+	import time
+	import sys
+	import string
+	mbox = '/usr/mail/'+posix.environ['USER']
+	fp = open(mbox, 'r')
+	mb = UnixMailbox(fp)
+	msgs = []
+	while 1:
+		msg = mb.next()
+		if not msg:
+			break
+		msgs.append(msg)
+	if len(sys.argv) > 1:
+		num = string.atoi(sys.argv[1])
+		print 'Message %d body:'%num
+		msg = msgs[num-1]
+		msg.rewindbody()
+		sys.stdout.write(msg.fp.read())
+		sys.exit(0)
+	print 'Mailbox',mbox,'has',len(msgs),'messages:'
+	for msg in msgs:
+		f = msg.getheader('from')
+		s = msg.getheader('subject')
+		d = (msg.getheader('date'))
+		print '%20.20s   %18.18s   %-30.30s'%(f, d[5:], s)
+