blob: a909366fd481365efce693ced2f3aebc54ace39b [file] [log] [blame]
Guido van Rossumac8a9f31997-09-30 19:05:50 +00001"""Guess the MIME type of a file.
2
Fred Drake5109ffd1998-05-18 16:27:20 +00003This module defines two useful functions:
Guido van Rossumac8a9f31997-09-30 19:05:50 +00004
Barry Warsaw107771a2001-10-25 21:49:18 +00005guess_type(url, strict=1) -- guess the MIME type and encoding of a URL.
Guido van Rossumac8a9f31997-09-30 19:05:50 +00006
Barry Warsaw107771a2001-10-25 21:49:18 +00007guess_extension(type, strict=1) -- guess the extension for a given MIME type.
Fred Drake5109ffd1998-05-18 16:27:20 +00008
Guido van Rossumac8a9f31997-09-30 19:05:50 +00009It also contains the following, for tuning the behavior:
10
11Data:
12
13knownfiles -- list of files to parse
14inited -- flag set when init() has been called
Fred Drakeeeee4ec2001-08-03 21:01:44 +000015suffix_map -- dictionary mapping suffixes to suffixes
Guido van Rossumac8a9f31997-09-30 19:05:50 +000016encodings_map -- dictionary mapping suffixes to encodings
17types_map -- dictionary mapping suffixes to types
18
19Functions:
20
21init([files]) -- parse a list of files, default knownfiles
22read_mime_types(file) -- parse one file, return a dictionary or None
Guido van Rossumac8a9f31997-09-30 19:05:50 +000023"""
24
Fred Drakeeeee4ec2001-08-03 21:01:44 +000025import os
Guido van Rossumac8a9f31997-09-30 19:05:50 +000026import posixpath
Guido van Rossum1c5fb1c1998-10-12 15:12:28 +000027import urllib
Guido van Rossumac8a9f31997-09-30 19:05:50 +000028
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +000029__all__ = [
30 "guess_type","guess_extension","guess_all_extensions",
31 "add_type","read_mime_types","init"
32]
Skip Montanaro03d90142001-01-25 15:29:22 +000033
Guido van Rossumac8a9f31997-09-30 19:05:50 +000034knownfiles = [
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +000035 "/etc/mime.types",
Guido van Rossumac8a9f31997-09-30 19:05:50 +000036 "/usr/local/etc/httpd/conf/mime.types",
37 "/usr/local/lib/netscape/mime.types",
Fred Drake13a2c272000-02-10 17:17:14 +000038 "/usr/local/etc/httpd/conf/mime.types", # Apache 1.2
39 "/usr/local/etc/mime.types", # Apache 1.3
Guido van Rossumac8a9f31997-09-30 19:05:50 +000040 ]
41
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +000042inited = False
Guido van Rossumac8a9f31997-09-30 19:05:50 +000043
Fred Drakeeeee4ec2001-08-03 21:01:44 +000044
45class MimeTypes:
46 """MIME-types datastore.
47
48 This datastore can handle information from mime.types-style files
49 and supports basic determination of MIME type from a filename or
50 URL, and can guess a reasonable extension given a MIME type.
51 """
52
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +000053 def __init__(self, filenames=(), strict=True):
Fred Drakeeeee4ec2001-08-03 21:01:44 +000054 if not inited:
55 init()
56 self.encodings_map = encodings_map.copy()
57 self.suffix_map = suffix_map.copy()
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +000058 self.types_map = ({}, {}) # dict for (non-strict, strict)
59 self.types_map_inv = ({}, {})
60 for (ext, type) in types_map.items():
61 self.add_type(type, ext, True)
62 for (ext, type) in common_types.items():
63 self.add_type(type, ext, False)
Fred Drakeeeee4ec2001-08-03 21:01:44 +000064 for name in filenames:
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +000065 self.read(name, strict)
Fred Drakeeeee4ec2001-08-03 21:01:44 +000066
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +000067 def add_type(self, type, ext, strict=True):
68 """Add a mapping between a type and and extension.
69
70 When the extension is already known, the new
71 type will replace the old one. When the type
72 is already known the extension will be added
73 to the list of known extensions.
74
75 If strict is true, information will be added to
76 list of standard types, else to the list of non-standard
77 types.
78 """
79 self.types_map[strict][ext] = type
80 exts = self.types_map_inv[strict].setdefault(type, [])
81 if ext not in exts:
82 exts.append(ext)
83
84 def guess_type(self, url, strict=True):
Fred Drakeeeee4ec2001-08-03 21:01:44 +000085 """Guess the type of a file based on its URL.
86
87 Return value is a tuple (type, encoding) where type is None if
88 the type can't be guessed (no or unknown suffix) or a string
89 of the form type/subtype, usable for a MIME Content-type
90 header; and encoding is None for no encoding or the name of
91 the program used to encode (e.g. compress or gzip). The
92 mappings are table driven. Encoding suffixes are case
93 sensitive; type suffixes are first tried case sensitive, then
94 case insensitive.
95
96 The suffixes .tgz, .taz and .tz (case sensitive!) are all
97 mapped to '.tar.gz'. (This is table-driven too, using the
98 dictionary suffix_map.)
Barry Warsaw107771a2001-10-25 21:49:18 +000099
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000100 Optional `strict' argument when False adds a bunch of commonly found,
Barry Warsaw107771a2001-10-25 21:49:18 +0000101 but non-standard types.
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000102 """
103 scheme, url = urllib.splittype(url)
104 if scheme == 'data':
105 # syntax of data URLs:
106 # dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
107 # mediatype := [ type "/" subtype ] *( ";" parameter )
108 # data := *urlchar
109 # parameter := attribute "=" value
110 # type/subtype defaults to "text/plain"
111 comma = url.find(',')
112 if comma < 0:
113 # bad data URL
114 return None, None
115 semi = url.find(';', 0, comma)
116 if semi >= 0:
117 type = url[:semi]
118 else:
119 type = url[:comma]
120 if '=' in type or '/' not in type:
121 type = 'text/plain'
122 return type, None # never compressed, so encoding is None
123 base, ext = posixpath.splitext(url)
Raymond Hettinger54f02222002-06-01 14:18:47 +0000124 while ext in self.suffix_map:
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000125 base, ext = posixpath.splitext(base + self.suffix_map[ext])
Raymond Hettinger54f02222002-06-01 14:18:47 +0000126 if ext in self.encodings_map:
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000127 encoding = self.encodings_map[ext]
128 base, ext = posixpath.splitext(base)
129 else:
130 encoding = None
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000131 types_map = self.types_map[True]
Raymond Hettinger54f02222002-06-01 14:18:47 +0000132 if ext in types_map:
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000133 return types_map[ext], encoding
Raymond Hettinger54f02222002-06-01 14:18:47 +0000134 elif ext.lower() in types_map:
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000135 return types_map[ext.lower()], encoding
Barry Warsaw107771a2001-10-25 21:49:18 +0000136 elif strict:
137 return None, encoding
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000138 types_map = self.types_map[False]
139 if ext in types_map:
140 return types_map[ext], encoding
141 elif ext.lower() in types_map:
142 return types_map[ext.lower()], encoding
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000143 else:
144 return None, encoding
145
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000146 def guess_all_extensions(self, type, strict=True):
147 """Guess the extensions for a file based on its MIME type.
148
149 Return value is a list of strings giving the possible filename
150 extensions, including the leading dot ('.'). The extension is not
151 guaranteed to have been associated with any particular data
152 stream, but would be mapped to the MIME type `type' by
153 guess_type(). If no extension can be guessed for `type', None
154 is returned.
155
156 Optional `strict' argument when false adds a bunch of commonly found,
157 but non-standard types.
158 """
159 type = type.lower()
160 extensions = self.types_map_inv[True].get(type, [])
161 if not strict:
162 for ext in self.types_map_inv[False].get(type, []):
163 if ext not in extensions:
164 extensions.append(ext)
165 if len(extensions):
166 return extensions
167
168 def guess_extension(self, type, strict=True):
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000169 """Guess the extension for a file based on its MIME type.
170
171 Return value is a string giving a filename extension,
172 including the leading dot ('.'). The extension is not
173 guaranteed to have been associated with any particular data
174 stream, but would be mapped to the MIME type `type' by
175 guess_type(). If no extension can be guessed for `type', None
176 is returned.
Barry Warsaw107771a2001-10-25 21:49:18 +0000177
178 Optional `strict' argument when false adds a bunch of commonly found,
179 but non-standard types.
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000180 """
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000181 extensions = self.guess_all_extensions(type, strict)
182 if extensions is not None:
183 extensions = extensions[0]
184 return extensions
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000185
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000186 def read(self, filename, strict=True):
187 """
188 Read a single mime.types-format file, specified by pathname.
189
190 If strict is true, information will be added to
191 list of standard types, else to the list of non-standard
192 types.
193 """
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000194 fp = open(filename)
Walter Dörwald51cc72c2003-01-03 21:02:36 +0000195 self.readfp(fp, strict)
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000196 fp.close()
197
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000198 def readfp(self, fp, strict=True):
199 """
200 Read a single mime.types-format file.
201
202 If strict is true, information will be added to
203 list of standard types, else to the list of non-standard
204 types.
205 """
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000206 while 1:
Fred Drakec019ecb2001-08-16 15:54:28 +0000207 line = fp.readline()
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000208 if not line:
209 break
210 words = line.split()
211 for i in range(len(words)):
212 if words[i][0] == '#':
213 del words[i:]
214 break
215 if not words:
216 continue
217 type, suffixes = words[0], words[1:]
218 for suff in suffixes:
Walter Dörwald8fa89722003-01-03 21:06:46 +0000219 self.add_type(type, '.' + suff, strict)
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000220
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000221def guess_type(url, strict=True):
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000222 """Guess the type of a file based on its URL.
223
224 Return value is a tuple (type, encoding) where type is None if the
225 type can't be guessed (no or unknown suffix) or a string of the
226 form type/subtype, usable for a MIME Content-type header; and
227 encoding is None for no encoding or the name of the program used
228 to encode (e.g. compress or gzip). The mappings are table
229 driven. Encoding suffixes are case sensitive; type suffixes are
230 first tried case sensitive, then case insensitive.
231
232 The suffixes .tgz, .taz and .tz (case sensitive!) are all mapped
233 to ".tar.gz". (This is table-driven too, using the dictionary
Fred Drake3130b7a1998-05-18 16:05:24 +0000234 suffix_map).
Barry Warsaw107771a2001-10-25 21:49:18 +0000235
236 Optional `strict' argument when false adds a bunch of commonly found, but
237 non-standard types.
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000238 """
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000239 init()
Barry Warsaw107771a2001-10-25 21:49:18 +0000240 return guess_type(url, strict)
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000241
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000242
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000243def guess_all_extensions(type, strict=True):
244 """Guess the extensions for a file based on its MIME type.
245
246 Return value is a list of strings giving the possible filename
247 extensions, including the leading dot ('.'). The extension is not
248 guaranteed to have been associated with any particular data
249 stream, but would be mapped to the MIME type `type' by
250 guess_type(). If no extension can be guessed for `type', None
251 is returned.
252
253 Optional `strict' argument when false adds a bunch of commonly found,
254 but non-standard types.
255 """
256 init()
257 return guess_all_extensions(type, strict)
258
259def guess_extension(type, strict=True):
Fred Drake5109ffd1998-05-18 16:27:20 +0000260 """Guess the extension for a file based on its MIME type.
261
262 Return value is a string giving a filename extension, including the
263 leading dot ('.'). The extension is not guaranteed to have been
Fred Drake49413411998-05-19 15:15:59 +0000264 associated with any particular data stream, but would be mapped to the
265 MIME type `type' by guess_type(). If no extension can be guessed for
266 `type', None is returned.
Barry Warsaw107771a2001-10-25 21:49:18 +0000267
268 Optional `strict' argument when false adds a bunch of commonly found,
269 but non-standard types.
Fred Drake5109ffd1998-05-18 16:27:20 +0000270 """
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000271 init()
Barry Warsaw107771a2001-10-25 21:49:18 +0000272 return guess_extension(type, strict)
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000273
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000274def add_type(self, type, ext, strict=True):
275 """Add a mapping between a type and and extension.
276
277 When the extension is already known, the new
278 type will replace the old one. When the type
279 is already known the extension will be added
280 to the list of known extensions.
281
282 If strict is true, information will be added to
283 list of standard types, else to the list of non-standard
284 types.
285 """
286 init()
287 return add_type(type, ext, strict)
288
Fred Drake5109ffd1998-05-18 16:27:20 +0000289
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000290def init(files=None):
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000291 global guess_all_extensions, guess_extension, guess_type
Barry Warsaw107771a2001-10-25 21:49:18 +0000292 global suffix_map, types_map, encodings_map, common_types
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000293 global add_type, inited
294 inited = True
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000295 db = MimeTypes()
296 if files is None:
297 files = knownfiles
298 for file in files:
299 if os.path.isfile(file):
300 db.readfp(open(file))
301 encodings_map = db.encodings_map
Fred Drakec81a0692001-08-16 18:14:38 +0000302 suffix_map = db.suffix_map
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000303 types_map = db.types_map[True]
304 guess_all_extensions = db.guess_all_extensions
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000305 guess_extension = db.guess_extension
306 guess_type = db.guess_type
Walter Dörwald5ccaf8f2002-09-06 16:15:58 +0000307 add_type = db.add_type
308 common_types = db.types_map[False]
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000309
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000310
311def read_mime_types(file):
312 try:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000313 f = open(file)
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000314 except IOError:
Guido van Rossum45e2fbc1998-03-26 21:13:24 +0000315 return None
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000316 db = MimeTypes()
Walter Dörwaldbb51ed32003-01-03 19:33:17 +0000317 db.readfp(f, True)
318 return db.types_map[True]
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000319
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000320
321suffix_map = {
322 '.tgz': '.tar.gz',
323 '.taz': '.tar.gz',
324 '.tz': '.tar.gz',
Fred Drakeeeee4ec2001-08-03 21:01:44 +0000325 }
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000326
327encodings_map = {
328 '.gz': 'gzip',
329 '.Z': 'compress',
330 }
331
Martin v. Löwisa3689fe2001-09-07 16:49:12 +0000332# Before adding new types, make sure they are either registered with IANA, at
333# http://www.isi.edu/in-notes/iana/assignments/media-types
334# or extensions, i.e. using the x- prefix
Barry Warsaw107771a2001-10-25 21:49:18 +0000335
336# If you add to these, please keep them sorted!
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000337types_map = {
Barry Warsaw107771a2001-10-25 21:49:18 +0000338 '.a' : 'application/octet-stream',
339 '.ai' : 'application/postscript',
340 '.aif' : 'audio/x-aiff',
341 '.aifc' : 'audio/x-aiff',
342 '.aiff' : 'audio/x-aiff',
343 '.au' : 'audio/basic',
344 '.avi' : 'video/x-msvideo',
345 '.bat' : 'text/plain',
346 '.bcpio' : 'application/x-bcpio',
347 '.bin' : 'application/octet-stream',
348 '.bmp' : 'image/x-ms-bmp',
349 '.c' : 'text/plain',
350 # Duplicates :(
351 '.cdf' : 'application/x-cdf',
352 '.cdf' : 'application/x-netcdf',
353 '.cpio' : 'application/x-cpio',
354 '.csh' : 'application/x-csh',
355 '.css' : 'text/css',
356 '.dll' : 'application/octet-stream',
357 '.doc' : 'application/msword',
358 '.dot' : 'application/msword',
359 '.dvi' : 'application/x-dvi',
360 '.eml' : 'message/rfc822',
361 '.eps' : 'application/postscript',
362 '.etx' : 'text/x-setext',
363 '.exe' : 'application/octet-stream',
364 '.gif' : 'image/gif',
365 '.gtar' : 'application/x-gtar',
366 '.h' : 'text/plain',
367 '.hdf' : 'application/x-hdf',
368 '.htm' : 'text/html',
369 '.html' : 'text/html',
370 '.ief' : 'image/ief',
371 '.jpe' : 'image/jpeg',
372 '.jpeg' : 'image/jpeg',
373 '.jpg' : 'image/jpeg',
374 '.js' : 'application/x-javascript',
375 '.ksh' : 'text/plain',
376 '.latex' : 'application/x-latex',
377 '.m1v' : 'video/mpeg',
378 '.man' : 'application/x-troff-man',
379 '.me' : 'application/x-troff-me',
380 '.mht' : 'message/rfc822',
381 '.mhtml' : 'message/rfc822',
382 '.mif' : 'application/x-mif',
383 '.mov' : 'video/quicktime',
384 '.movie' : 'video/x-sgi-movie',
385 '.mp2' : 'audio/mpeg',
386 '.mp3' : 'audio/mpeg',
387 '.mpa' : 'video/mpeg',
388 '.mpe' : 'video/mpeg',
389 '.mpeg' : 'video/mpeg',
390 '.mpg' : 'video/mpeg',
391 '.ms' : 'application/x-troff-ms',
392 '.nc' : 'application/x-netcdf',
393 '.nws' : 'message/rfc822',
394 '.o' : 'application/octet-stream',
395 '.obj' : 'application/octet-stream',
396 '.oda' : 'application/oda',
397 '.p12' : 'application/x-pkcs12',
398 '.p7c' : 'application/pkcs7-mime',
399 '.pbm' : 'image/x-portable-bitmap',
400 '.pdf' : 'application/pdf',
401 '.pfx' : 'application/x-pkcs12',
402 '.pgm' : 'image/x-portable-graymap',
403 '.pl' : 'text/plain',
404 '.png' : 'image/png',
405 '.pnm' : 'image/x-portable-anymap',
406 '.pot' : 'application/vnd.ms-powerpoint',
407 '.ppa' : 'application/vnd.ms-powerpoint',
408 '.ppm' : 'image/x-portable-pixmap',
409 '.pps' : 'application/vnd.ms-powerpoint',
410 '.ppt' : 'application/vnd.ms-powerpoint',
411 '.ps' : 'application/postscript',
412 '.pwz' : 'application/vnd.ms-powerpoint',
413 '.py' : 'text/x-python',
414 '.pyc' : 'application/x-python-code',
415 '.pyo' : 'application/x-python-code',
416 '.qt' : 'video/quicktime',
417 '.ra' : 'audio/x-pn-realaudio',
418 '.ram' : 'application/x-pn-realaudio',
419 '.ras' : 'image/x-cmu-raster',
420 '.rdf' : 'application/xml',
421 '.rgb' : 'image/x-rgb',
422 '.roff' : 'application/x-troff',
423 '.rtx' : 'text/richtext',
424 '.sgm' : 'text/x-sgml',
425 '.sgml' : 'text/x-sgml',
426 '.sh' : 'application/x-sh',
427 '.shar' : 'application/x-shar',
428 '.snd' : 'audio/basic',
429 '.so' : 'application/octet-stream',
430 '.src' : 'application/x-wais-source',
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000431 '.sv4cpio': 'application/x-sv4cpio',
Barry Warsaw107771a2001-10-25 21:49:18 +0000432 '.sv4crc' : 'application/x-sv4crc',
Guido van Rossum5e1222b2003-01-04 14:11:38 +0000433 '.swf' : 'application/x-shockwave-flash',
Barry Warsaw107771a2001-10-25 21:49:18 +0000434 '.t' : 'application/x-troff',
435 '.tar' : 'application/x-tar',
436 '.tcl' : 'application/x-tcl',
437 '.tex' : 'application/x-tex',
438 '.texi' : 'application/x-texinfo',
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000439 '.texinfo': 'application/x-texinfo',
Barry Warsaw107771a2001-10-25 21:49:18 +0000440 '.tif' : 'image/tiff',
441 '.tiff' : 'image/tiff',
442 '.tr' : 'application/x-troff',
443 '.tsv' : 'text/tab-separated-values',
444 '.txt' : 'text/plain',
445 '.ustar' : 'application/x-ustar',
446 '.vcf' : 'text/x-vcard',
447 '.wav' : 'audio/x-wav',
448 '.wiz' : 'application/msword',
449 '.xbm' : 'image/x-xbitmap',
450 '.xlb' : 'application/vnd.ms-excel',
451 # Duplicates :(
452 '.xls' : 'application/excel',
453 '.xls' : 'application/vnd.ms-excel',
454 '.xml' : 'text/xml',
455 '.xpm' : 'image/x-xpixmap',
456 '.xsl' : 'application/xml',
457 '.xwd' : 'image/x-xwindowdump',
458 '.zip' : 'application/zip',
Guido van Rossumac8a9f31997-09-30 19:05:50 +0000459 }
Eric S. Raymond51cc3bc2001-02-09 09:44:47 +0000460
Barry Warsaw107771a2001-10-25 21:49:18 +0000461# These are non-standard types, commonly found in the wild. They will only
462# match if strict=0 flag is given to the API methods.
463
464# Please sort these too
465common_types = {
466 '.jpg' : 'image/jpg',
467 '.mid' : 'audio/midi',
468 '.midi': 'audio/midi',
469 '.pct' : 'image/pict',
470 '.pic' : 'image/pict',
471 '.pict': 'image/pict',
472 '.rtf' : 'application/rtf',
473 '.xul' : 'text/xul'
474 }
475
476
Eric S. Raymond51cc3bc2001-02-09 09:44:47 +0000477if __name__ == '__main__':
478 import sys
Barry Warsaw107771a2001-10-25 21:49:18 +0000479 import getopt
480
Fred Drake698da022001-12-05 15:58:29 +0000481 USAGE = """\
482Usage: mimetypes.py [options] type
483
484Options:
485 --help / -h -- print this message and exit
486 --lenient / -l -- additionally search of some common, but non-standard
487 types.
488 --extension / -e -- guess extension instead of type
489
490More than one type argument may be given.
491"""
492
493 def usage(code, msg=''):
494 print USAGE
495 if msg: print msg
496 sys.exit(code)
497
Barry Warsaw107771a2001-10-25 21:49:18 +0000498 try:
499 opts, args = getopt.getopt(sys.argv[1:], 'hle',
500 ['help', 'lenient', 'extension'])
501 except getopt.error, msg:
502 usage(1, msg)
503
504 strict = 1
505 extension = 0
506 for opt, arg in opts:
507 if opt in ('-h', '--help'):
508 usage(0)
509 elif opt in ('-l', '--lenient'):
510 strict = 0
511 elif opt in ('-e', '--extension'):
512 extension = 1
513 for gtype in args:
514 if extension:
515 guess = guess_extension(gtype, strict)
516 if not guess: print "I don't know anything about type", gtype
517 else: print guess
518 else:
519 guess, encoding = guess_type(gtype, strict)
520 if not guess: print "I don't know anything about type", gtype
521 else: print 'type:', guess, 'encoding:', encoding