home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Lib / mailbox.py < prev    next >
Text File  |  1997-10-22  |  4KB  |  208 lines

  1. #! /usr/bin/env python
  2.  
  3. """Classes to handle Unix style, MMDF style, and MH style mailboxes."""
  4.  
  5.  
  6. import rfc822
  7. import os
  8.  
  9. class _Mailbox:
  10.     def __init__(self, fp):
  11.         self.fp = fp
  12.         self.seekp = 0
  13.  
  14.     def seek(self, pos, whence=0):
  15.         if whence==1:        # Relative to current position
  16.             self.pos = self.pos + pos
  17.         if whence==2:        # Relative to file's end
  18.             self.pos = self.stop + pos
  19.         else:            # Default - absolute position
  20.             self.pos = self.start + pos
  21.  
  22.     def next(self):
  23.         while 1:
  24.             self.fp.seek(self.seekp)
  25.             try:
  26.                 self._search_start()
  27.             except EOFError:
  28.                 self.seekp = self.fp.tell()
  29.                 return None
  30.             start = self.fp.tell()
  31.             self._search_end()
  32.             self.seekp = stop = self.fp.tell()
  33.             if start <> stop:
  34.                 break
  35.         return rfc822.Message(_Subfile(self.fp, start, stop))
  36.  
  37. class _Subfile:
  38.     def __init__(self, fp, start, stop):
  39.         self.fp = fp
  40.         self.start = start
  41.         self.stop = stop
  42.         self.pos = self.start
  43.  
  44.     def read(self, length = None):
  45.         if self.pos >= self.stop:
  46.             return ''
  47.         if length is None:
  48.             length = self.stop - self.pos
  49.         self.fp.seek(self.pos)
  50.         self.pos = self.pos + length
  51.         return self.fp.read(length)
  52.  
  53.     def readline(self, length = None):
  54.         if self.pos >= self.stop:
  55.             return ''
  56.         if length is None:
  57.             length = self.stop - self.pos
  58.         self.fp.seek(self.pos)
  59.         data = self.fp.readline(length)
  60.         if len(data) < length:
  61.             length = len(data)
  62.         self.pos = self.pos + length
  63.         return data
  64.  
  65.     def tell(self):
  66.         return self.pos - self.start
  67.  
  68.     def seek(self, pos, whence=0):
  69.             if whence == 0:
  70.             self.pos = self.start + pos
  71.         elif whence == 1:
  72.             self.pos = self.pos + pos
  73.         elif whence == 2:
  74.             self.pos = self.stop + pos
  75.  
  76.     def close(self):
  77.         pass
  78.  
  79. class UnixMailbox(_Mailbox):
  80.     def _search_start(self):
  81.         while 1:
  82.             line = self.fp.readline()
  83.             if not line:
  84.                 raise EOFError
  85.             if line[:5] == 'From ':
  86.                 return
  87.  
  88.     def _search_end(self):
  89.         while 1:
  90.             pos = self.fp.tell()
  91.             line = self.fp.readline()
  92.             if not line:
  93.                 return
  94.             if line[:5] == 'From ':
  95.                 self.fp.seek(pos)
  96.                 return
  97.  
  98. class MmdfMailbox(_Mailbox):
  99.     def _search_start(self):
  100.         while 1:
  101.             line = self.fp.readline()
  102.             if not line:
  103.                 raise EOFError
  104.             if line[:5] == '\001\001\001\001\n':
  105.                 return
  106.  
  107.     def _search_end(self):
  108.         while 1:
  109.             pos = self.fp.tell()
  110.             line = self.fp.readline()
  111.             if not line:
  112.                 return
  113.             if line == '\001\001\001\001\n':
  114.                 self.fp.seek(pos)
  115.                 return
  116.  
  117. class MHMailbox:
  118.     def __init__(self, dirname):
  119.     import re
  120.     pat = re.compile('^[0-9][0-9]*$')
  121.     self.dirname = dirname
  122.     files = os.listdir(self.dirname)
  123.     self.boxes = []
  124.     for f in files:
  125.         if pat.match(f):
  126.         self.boxes.append(f)
  127.  
  128.     def next(self):
  129.     if not self.boxes:
  130.         return None
  131.     fn = self.boxes[0]
  132.     del self.boxes[0]
  133.     fp = open(os.path.join(self.dirname, fn))
  134.     return rfc822.Message(fp)
  135.         
  136.     
  137. class BabylMailbox(_Mailbox):
  138.     def _search_start(self):
  139.     while 1:
  140.         line = self.fp.readline()
  141.         if not line:
  142.         raise EOFError
  143.         if line == '*** EOOH ***\n':
  144.         return
  145.  
  146.     def _search_end(self):
  147.     while 1:
  148.         pos = self.fp.tell()
  149.         line = self.fp.readline()
  150.         if not line:
  151.         return
  152.         if line == '\037\014\n':
  153.         self.fp.seek(pos)
  154.         return
  155.  
  156.  
  157. def _test():
  158.     import time
  159.     import sys
  160.     import string
  161.     import os
  162.  
  163.     args = sys.argv[1:]
  164.     if not args:
  165.         for key in 'MAIL', 'LOGNAME', 'USER':
  166.             if os.environ.has_key(key):
  167.                 mbox = os.environ[key]
  168.                 break
  169.         else:
  170.             print "$MAIL, $LOGNAME nor $USER set -- who are you?"
  171.             return
  172.     else:
  173.         mbox = args[0]
  174.     if mbox[:1] == '+':
  175.         mbox = os.environ['HOME'] + '/Mail/' + mbox[1:]
  176.     elif not '/' in mbox:
  177.         mbox = '/usr/mail/' + mbox
  178.     if os.path.isdir(mbox):
  179.         mb = MHMailbox(mbox)
  180.     else:
  181.         fp = open(mbox, 'r')
  182.         mb = UnixMailbox(fp)
  183.     
  184.     msgs = []
  185.     while 1:
  186.         msg = mb.next()
  187.         if not msg:
  188.             break
  189.         msgs.append(msg)
  190.         msg.fp = None
  191.     if len(args) > 1:
  192.         num = string.atoi(args[1])
  193.         print 'Message %d body:'%num
  194.         msg = msgs[num-1]
  195.         msg.rewindbody()
  196.         sys.stdout.write(msg.fp.read())
  197.     else:
  198.         print 'Mailbox',mbox,'has',len(msgs),'messages:'
  199.         for msg in msgs:
  200.             f = msg.getheader('from')
  201.             s = msg.getheader('subject')
  202.             d = (msg.getheader('date'))
  203.             print '%20.20s   %18.18s   %-30.30s'%(f, d[5:], s)
  204.  
  205.  
  206. if __name__ == '__main__':
  207.     _test()
  208.