# Mailcap file handling.  See RFC 1524.

import os
import string
import tempfile


# Part 1: top-level interface.

def getcaps():
    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():
    # 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):
    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):
	    cotinue
	# 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):
    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):
    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, type, key='view', filename="/dev/null", plist=[]):
    entries = lookup(caps, type, key)
    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], type, filename, plist)
	return command, e
    return None, None

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

def subst(field, type, 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 + type
	    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 [type file] ..."
	    return
	type = args[0]
	file = args[1]
	command, e = findmatch(caps, type, '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()
