1 """Mailcap file handling. See RFC 1524."""
5 __all__ = [
"getcaps",
"findmatch"]
10 """Return a dictionary containing the mailcap database.
12 The dictionary maps a MIME type (in all lowercase, e.g. 'text/plain')
13 to a list of dictionaries corresponding to mailcap entries. The list
14 collects all the entries for that MIME type from all available mailcap
15 files. Each dictionary contains key-value pairs for that MIME type,
16 where the viewing command is stored with the key "view".
22 fp =
open(mailcap,
'r')
27 for key
in morecaps.keys():
28 if not caps.has_key(key):
29 caps[key] = morecaps[key]
31 caps[key] = caps[key] + morecaps[key]
35 """Return a list of all mailcap files found on the system."""
37 if os.environ.has_key(
'MAILCAPS'):
38 str = os.environ[
'MAILCAPS']
39 mailcaps = str.split(
':')
41 if os.environ.has_key(
'HOME'):
42 home = os.environ[
'HOME']
46 mailcaps = [home +
'/.mailcap',
'/etc/mailcap',
47 '/usr/etc/mailcap',
'/usr/local/etc/mailcap']
54 """Read a mailcap file and return a dictionary keyed by MIME type.
56 Each MIME type is mapped to an entry consisting of a list of
57 dictionaries; the list will contain more than one such dictionary
58 if a given MIME type appears more than once in the mailcap file.
59 Each dictionary contains key-value pairs for that MIME type, where
60 the viewing command is stored with the key "view".
67 if line[0] ==
'#' or line.strip() ==
'':
71 while nextline[-2:] ==
'\\\n':
72 nextline = fp.readline()
73 if not nextline: nextline =
'\n'
74 line = line[:-2] + nextline
77 if not (key
and fields):
80 types = key.split(
'/')
81 for j
in range(len(types)):
82 types[j] = types[j].
strip()
92 """Parse one entry in a mailcap file and return a dictionary.
94 The viewing command is stored as the value with the key "view",
95 and the rest of the fields produce key-value pairs in the dict.
105 key, view, rest = fields[0], fields[1], fields[2:]
106 fields = {
'view': view}
113 fkey = field[:i].
strip()
114 fvalue = field[i+1:].
strip()
115 if fields.has_key(fkey):
119 fields[fkey] = fvalue
123 """Separate one key-value pair in a mailcap entry."""
133 return line[start:i].
strip(), i
138 def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]):
139 """Find a match for a mailcap entry.
141 Return a tuple containing the command line, and the mailcap entry
142 used; (None, None) if no match is found. This may invoke the
143 'test' command of several matching entries before deciding which
147 entries =
lookup(caps, MIMEtype, key)
150 if e.has_key(
'test'):
151 test =
subst(e[
'test'], filename, plist)
152 if test
and os.system(test) != 0:
154 command =
subst(e[key], MIMEtype, filename, plist)
160 if caps.has_key(MIMEtype):
161 entries = entries + caps[MIMEtype]
162 MIMEtypes = MIMEtype.split(
'/')
163 MIMEtype = MIMEtypes[0] +
'/*'
164 if caps.has_key(MIMEtype):
165 entries = entries + caps[MIMEtype]
167 entries =
filter(
lambda e, key=key: e.has_key(key), entries)
170 def subst(field, MIMEtype, filename, plist=[]):
175 c = field[i]; i = i+1
178 c = field[i:i+1]; i = i+1
181 c = field[i]; i = i+1
190 while i < n
and field[i] !=
'}':
192 name = field[start:i]
203 name = name.lower() +
'='
206 if p[:n].
lower() == name:
219 for i
in range(1, len(sys.argv), 2):
220 args = sys.argv[i:i+2]
222 print "usage: mailcap [MIMEtype file] ..."
226 command, e =
findmatch(caps, MIMEtype,
'view', file)
228 print "No viewer found for", type
230 print "Executing:", command
231 sts = os.system(command)
233 print "Exit status:", sts
236 print "Mailcap files:"
240 print "Mailcap entries:"
251 print " %-15s" % k, e[k]
254 if __name__ ==
'__main__':