#! /usr/bin/env python

"""Classes to handle Unix style, MMDF style, and MH style mailboxes."""


import rfc822
import os

class _Mailbox:
    def __init__(self, fp):
        self.fp = fp
        self.seekp = 0

    def seek(self, pos, whence=0):
        if whence==1:           # Relative to current position
            self.pos = self.pos + pos
        if whence==2:           # Relative to file's end
            self.pos = self.stop + pos
        else:                   # Default - absolute position
            self.pos = self.start + 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, length = None):
        if self.pos >= self.stop:
            return ''
        remaining = self.stop - self.pos
        if length is None or length < 0:
            length = remaining
        elif length > remaining:
            length = remaining
        self.fp.seek(self.pos)
        data = self.fp.read(length)
        self.pos = self.fp.tell()
        return data

    def readline(self, length = None):
        if self.pos >= self.stop:
            return ''
        if length is None:
            length = self.stop - self.pos
        self.fp.seek(self.pos)
        data = self.fp.readline(length)
        self.pos = self.fp.tell()
        return data

    def readlines(self, sizehint = -1):
        lines = []
        while 1:
            line = self.readline()
            if not line:
                break
            lines.append(line)
            if sizehint >= 0:
                sizehint = sizehint - len(line)
                if sizehint <= 0:
                    break
        return lines

    def tell(self):
        return self.pos - self.start

    def seek(self, pos, whence=0):
        if whence == 0:
            self.pos = self.start + pos
        elif whence == 1:
            self.pos = self.pos + pos
        elif whence == 2:
            self.pos = self.stop + pos

    def close(self):
        del self.fp


class UnixMailbox(_Mailbox):
    def _search_start(self):
        while 1:
            pos = self.fp.tell()
            line = self.fp.readline()
            if not line:
                raise EOFError
            if line[:5] == 'From ' and self._isrealfromline(line):
                self.fp.seek(pos)
                return

    def _search_end(self):
        self.fp.readline()      # Throw away header line
        while 1:
            pos = self.fp.tell()
            line = self.fp.readline()
            if not line:
                return
            if line[:5] == 'From ' and self._isrealfromline(line):
                self.fp.seek(pos)
                return

    # An overridable mechanism to test for From-line-ness.
    # You can either specify a different regular expression
    # or define a whole new _isrealfromline() method.
    # Note that this only gets called for lines starting with
    # the 5 characters "From ".

    _fromlinepattern = r"From \s*[^\s]+\s+\w\w\w\s+\w\w\w\s+\d?\d\s+" \
                       r"\d?\d:\d\d(:\d\d)?(\s+[^\s]+)?\s+\d\d\d\d\s*$"
    _regexp = None

    def _isrealfromline(self, line):
        if not self._regexp:
            import re
            self._regexp = re.compile(self._fromlinepattern)
        return self._regexp.match(line)


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


class MHMailbox:
    def __init__(self, dirname):
        import re
        pat = re.compile('^[0-9][0-9]*$')
        self.dirname = dirname
        files = os.listdir(self.dirname)
        self.boxes = []
        for f in files:
            if pat.match(f):
                self.boxes.append(f)

    def next(self):
        if not self.boxes:
            return None
        fn = self.boxes[0]
        del self.boxes[0]
        fp = open(os.path.join(self.dirname, fn))
        return rfc822.Message(fp)


class Maildir:
    # Qmail directory mailbox

    def __init__(self, dirname):
        import string
        self.dirname = dirname
        self.boxes = []

        # check for new mail
        newdir = os.path.join(self.dirname, 'new')
        for file in os.listdir(newdir):
            if len(string.split(file, '.')) > 2:
                self.boxes.append(os.path.join(newdir, file))

        # Now check for current mail in this maildir
        curdir = os.path.join(self.dirname, 'cur')
        for file in os.listdir(curdir):
            if len(string.split(file, '.')) > 2:
                self.boxes.append(os.path.join(curdir, file))

    def next(self):
        if not self.boxes:
            return None
        fn = self.boxes[0]
        del self.boxes[0]
        fp = open(os.path.join(self.dirname, fn))
        return rfc822.Message(fp)


class BabylMailbox(_Mailbox):
    def _search_start(self):
        while 1:
            line = self.fp.readline()
            if not line:
                raise EOFError
            if line == '*** EOOH ***\n':
                return

    def _search_end(self):
        while 1:
            pos = self.fp.tell()
            line = self.fp.readline()
            if not line:
                return
            if line == '\037\014\n':
                self.fp.seek(pos)
                return


def _test():
    import time
    import sys
    import string
    import os

    args = sys.argv[1:]
    if not args:
        for key in 'MAILDIR', 'MAIL', 'LOGNAME', 'USER':
            if os.environ.has_key(key):
                mbox = os.environ[key]
                break
        else:
            print "$MAIL, $LOGNAME nor $USER set -- who are you?"
            return
    else:
        mbox = args[0]
    if mbox[:1] == '+':
        mbox = os.environ['HOME'] + '/Mail/' + mbox[1:]
    elif not '/' in mbox:
        mbox = '/usr/mail/' + mbox
    if os.path.isdir(mbox):
        if os.path.isdir(os.path.join(mbox, 'cur')):
            mb = Maildir(mbox)
        else:
            mb = MHMailbox(mbox)
    else:
        fp = open(mbox, 'r')
        mb = UnixMailbox(fp)

    msgs = []
    while 1:
        msg = mb.next()
        if msg is None:
            break
        msgs.append(msg)
        if len(args) <= 1:
            msg.fp = None
    if len(args) > 1:
        num = string.atoi(args[1])
        print 'Message %d body:'%num
        msg = msgs[num-1]
        msg.rewindbody()
        sys.stdout.write(msg.fp.read())
    else:
        print 'Mailbox',mbox,'has',len(msgs),'messages:'
        for msg in msgs:
            f = msg.getheader('from') or ""
            s = msg.getheader('subject') or ""
            d = msg.getheader('date') or ""
            print '%20.20s   %18.18s   %-30.30s'%(f, d[5:], s)


if __name__ == '__main__':
    _test()
