1 # Mailcap file handling. See RFC 1524.
8 # Part 1: top-level interface.
12 for mailcap
in listmailcapfiles():
14 fp
= open(mailcap
, 'r')
17 morecaps
= readmailcapfile(fp
)
19 for key
in morecaps
.keys():
20 if not caps
.has_key(key
):
21 caps
[key
] = morecaps
[key
]
23 caps
[key
] = caps
[key
] + morecaps
[key
]
26 def listmailcapfiles():
27 # XXX Actually, this is Unix-specific
28 if os
.environ
.has_key('MAILCAPS'):
29 str = os
.environ
['MAILCAPS']
30 mailcaps
= string
.splitfields(str, ':')
32 if os
.environ
.has_key('HOME'):
33 home
= os
.environ
['HOME']
35 # Don't bother with getpwuid()
36 home
= '.' # Last resort
37 mailcaps
= [home
+ '/.mailcap', '/etc/mailcap',
38 '/usr/etc/mailcap', '/usr/local/etc/mailcap']
44 def readmailcapfile(fp
):
49 # Ignore comments and blank lines
50 if line
[0] == '#' or string
.strip(line
) == '':
53 # Join continuation lines
54 while nextline
[-2:] == '\\\n':
55 nextline
= fp
.readline()
56 if not nextline
: nextline
= '\n'
57 line
= line
[:-2] + nextline
59 key
, fields
= parseline(line
)
60 if not (key
and fields
):
63 types
= string
.splitfields(key
, '/')
64 for j
in range(len(types
)):
65 types
[j
] = string
.strip(types
[j
])
66 key
= string
.lower(string
.joinfields(types
, '/'))
69 caps
[key
].append(fields
)
78 field
, i
= parsefield(line
, i
, n
)
80 i
= i
+1 # Skip semicolon
83 key
, view
, rest
= fields
[0], fields
[1], fields
[2:]
84 fields
= {'view': view
}
86 i
= string
.find(field
, '=')
91 fkey
= string
.strip(field
[:i
])
92 fvalue
= string
.strip(field
[i
+1:])
93 if fields
.has_key(fkey
):
100 def parsefield(line
, i
, n
):
110 return string
.strip(line
[start
:i
]), i
113 # Part 3: using the database.
115 def findmatch(caps
, type, key
='view', filename
="/dev/null", plist
=[]):
116 entries
= lookup(caps
, type, key
)
118 if e
.has_key('test'):
119 test
= subst(e
['test'], filename
, plist
)
120 if test
and os
.system(test
) != 0:
122 command
= subst(e
[key
], type, filename
, plist
)
126 def lookup(caps
, type, key
=None):
128 if caps
.has_key(type):
129 entries
= entries
+ caps
[type]
130 types
= string
.splitfields(type, '/')
131 type = types
[0] + '/*'
132 if caps
.has_key(type):
133 entries
= entries
+ caps
[type]
135 entries
= filter(lambda e
, key
=key
: e
.has_key(key
), entries
)
138 def subst(field
, type, filename
, plist
=[]):
139 # XXX Actually, this is Unix-specific
143 c
= field
[i
]; i
= i
+1
146 c
= field
[i
:i
+1]; i
= i
+1
149 c
= field
[i
]; i
= i
+1
158 while i
< n
and field
[i
] <> '}':
160 name
= field
[start
:i
]
162 res
= res
+ findparam(name
, plist
)
164 # %n == number of parts if type is multipart/*
165 # %F == list of alternating type and filename for parts
170 def findparam(name
, plist
):
171 name
= string
.lower(name
) + '='
174 if string
.lower(p
[:n
]) == name
:
179 # Part 4: test program.
187 for i
in range(1, len(sys
.argv
), 2):
188 args
= sys
.argv
[i
:i
+2]
190 print "usage: mailcap [type file] ..."
194 command
, e
= findmatch(caps
, type, 'view', file)
196 print "No viewer found for", type
198 print "Executing:", command
199 sts
= os
.system(command
)
201 print "Exit status:", sts
204 print "Mailcap files:"
205 for fn
in listmailcapfiles(): print "\t" + fn
207 if not caps
: caps
= getcaps()
208 print "Mailcap entries:"
219 print " %-15s" % k
, e
[k
]
222 if __name__
== '__main__':