"""Mailcap file handling.  See RFC 1524."""

import os
import string


# Part 1: top-level interface.

def getcaps():
    """Return a dictionary containing the mailcap database.
    
    The dictionary maps a MIME type (in all lowercase, e.g. 'text/plain')
    to a list of dictionaries corresponding to mailcap entries.  The list
    collects all the entries for that MIME type from all available mailcap
    files.  Each dictionary contains key-value pairs for that MIME type,
    where the viewing command is stored with the key "view".

    """
    caps = {}
    for mailcap in listmailcapfiles():
        try:
            fp = open(mailcap, 'r')
        except:
            continue
        morecaps = readmailcapfile(fp)
        fp.close()
        for key in morecaps.keys():
            if not caps.has_key(key):
                caps[key] = morecaps[key]
            else:
                caps[key] = caps[key] + morecaps[key]
    return caps

def listmailcapfiles():
    """Return a list of all mailcap files found on the system."""
    # XXX Actually, this is Unix-specific
    if os.environ.has_key('MAILCAPS'):
        str = os.environ['MAILCAPS']
        mailcaps = string.splitfields(str, ':')
    else:
        if os.environ.has_key('HOME'):
            home = os.environ['HOME']
        else:
            # Don't bother with getpwuid()
            home = '.' # Last resort
        mailcaps = [home + '/.mailcap', '/etc/mailcap',
                '/usr/etc/mailcap', '/usr/local/etc/mailcap']
    return mailcaps


# Part 2: the parser.

def readmailcapfile(fp):
    """Read a mailcap file and return a dictionary keyed by MIME type.

    Each MIME type is mapped to an entry consisting of a list of
    dictionaries; the list will contain more than one such dictionary
    if a given MIME type appears more than once in the mailcap file.
    Each dictionary contains key-value pairs for that MIME type, where
    the viewing command is stored with the key "view".
    """
    caps = {}
    while 1:
        line = fp.readline()
        if not line: break
        # Ignore comments and blank lines
        if line[0] == '#' or string.strip(line) == '':
            continue
        nextline = line
        # Join continuation lines
        while nextline[-2:] == '\\\n':
            nextline = fp.readline()
            if not nextline: nextline = '\n'
            line = line[:-2] + nextline
        # Parse the line
        key, fields = parseline(line)
        if not (key and fields):
            continue
        # Normalize the key
        types = string.splitfields(key, '/')
        for j in range(len(types)):
            types[j] = string.strip(types[j])
        key = string.lower(string.joinfields(types, '/'))
        # Update the database
        if caps.has_key(key):
            caps[key].append(fields)
        else:
            caps[key] = [fields]
    return caps

def parseline(line):
    """Parse one entry in a mailcap file and return a dictionary.

    The viewing command is stored as the value with the key "view",
    and the rest of the fields produce key-value pairs in the dict.
    """
    fields = []
    i, n = 0, len(line)
    while i < n:
        field, i = parsefield(line, i, n)
        fields.append(field)
        i = i+1 # Skip semicolon
    if len(fields) < 2:
        return None, None
    key, view, rest = fields[0], fields[1], fields[2:]
    fields = {'view': view}
    for field in rest:
        i = string.find(field, '=')
        if i < 0:
            fkey = field
            fvalue = ""
        else:
            fkey = string.strip(field[:i])
            fvalue = string.strip(field[i+1:])
        if fields.has_key(fkey):
            # Ignore it
            pass
        else:
            fields[fkey] = fvalue
    return key, fields

def parsefield(line, i, n):
    """Separate one key-value pair in a mailcap entry."""
    start = i
    while i < n:
        c = line[i]
        if c == ';':
            break
        elif c == '\\':
            i = i+2
        else:
            i = i+1
    return string.strip(line[start:i]), i


# Part 3: using the database.

def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]):
    """Find a match for a mailcap entry.
    
    Return a tuple containing the command line, and the mailcap entry
    used; (None, None) if no match is found.  This may invoke the
    'test' command of several matching entries before deciding which
    entry to use.

    """
    entries = lookup(caps, MIMEtype, key)
    # XXX This code should somehow check for the needsterminal flag. 
    for e in entries:
        if e.has_key('test'):
            test = subst(e['test'], filename, plist)
            if test and os.system(test) != 0:
                continue
        command = subst(e[key], MIMEtype, filename, plist)
        return command, e
    return None, None

def lookup(caps, MIMEtype, key=None):
    entries = []
    if caps.has_key(MIMEtype):
        entries = entries + caps[MIMEtype]
    MIMEtypes = string.splitfields(MIMEtype, '/')
    MIMEtype = MIMEtypes[0] + '/*'
    if caps.has_key(MIMEtype):
        entries = entries + caps[MIMEtype]
    if key is not None:
        entries = filter(lambda e, key=key: e.has_key(key), entries)
    return entries

def subst(field, MIMEtype, filename, plist=[]):
    # XXX Actually, this is Unix-specific
    res = ''
    i, n = 0, len(field)
    while i < n:
        c = field[i]; i = i+1
        if c <> '%':
            if c == '\\':
                c = field[i:i+1]; i = i+1
            res = res + c
        else:
            c = field[i]; i = i+1
            if c == '%':
                res = res + c
            elif c == 's':
                res = res + filename
            elif c == 't':
                res = res + MIMEtype
            elif c == '{':
                start = i
                while i < n and field[i] <> '}':
                    i = i+1
                name = field[start:i]
                i = i+1
                res = res + findparam(name, plist)
            # XXX To do:
            # %n == number of parts if type is multipart/*
            # %F == list of alternating type and filename for parts
            else:
                res = res + '%' + c
    return res

def findparam(name, plist):
    name = string.lower(name) + '='
    n = len(name)
    for p in plist:
        if string.lower(p[:n]) == name:
            return p[n:]
    return ''


# Part 4: test program.

def test():
    import sys
    caps = getcaps()
    if not sys.argv[1:]:
        show(caps)
        return
    for i in range(1, len(sys.argv), 2):
        args = sys.argv[i:i+2]
        if len(args) < 2:
            print "usage: mailcap [MIMEtype file] ..."
            return
        MIMEtype = args[0]
        file = args[1]
        command, e = findmatch(caps, MIMEtype, 'view', file)
        if not command:
            print "No viewer found for", type
        else:
            print "Executing:", command
            sts = os.system(command)
            if sts:
                print "Exit status:", sts

def show(caps):
    print "Mailcap files:"
    for fn in listmailcapfiles(): print "\t" + fn
    print
    if not caps: caps = getcaps()
    print "Mailcap entries:"
    print
    ckeys = caps.keys()
    ckeys.sort()
    for type in ckeys:
        print type
        entries = caps[type]
        for e in entries:
            keys = e.keys()
            keys.sort()
            for k in keys:
                print "  %-15s" % k, e[k]
            print

if __name__ == '__main__':
    test()
