--- trunk\Lib\mimetypes.py 2009-01-17 06:16:07.000000000 -0200 +++ src\Lib\mimetypes.py 2009-01-17 05:59:34.000000000 -0200 @@ -18,13 +18,16 @@ Functions: -init([files]) -- parse a list of files, default knownfiles +init([files]) -- parse a list of files, default knownfiles (on Windows, the + default values are taken from the registry) read_mime_types(file) -- parse one file, return a dictionary or None """ import os import posixpath import urllib +try: import _winreg +except ImportError: _winreg = None __all__ = [ "guess_type","guess_extension","guess_all_extensions", @@ -219,6 +222,36 @@ for suff in suffixes: self.add_type(type, '.' + suff, strict) + def read_registry(self, strict=True): + """ + Load the MIME types database from Windows registry. + + If strict is true, information will be added to + list of standard types, else to the list of non-standard + types. + """ + def enum_types(mimedb): + i = 0 + while True: + try: ctype = _winreg.EnumKey(mimedb, i) + except EnvironmentError: break + try: ctype = ctype.encode('ascii') # omit in 3.x! + except UnicodeEncodeError: pass + else: yield ctype + i += 1 + + with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, + '\MIME\Database\Content Type') as mimedb: + for ctype in enum_types(mimedb): + with _winreg.OpenKey(mimedb, ctype) as key: + try: suffix, datatype = _winreg.QueryValueEx(key, 'Extension') + except EnvironmentError: continue + if datatype != _winreg.REG_SZ: continue + try: suffix = suffix.encode('ascii') # omit in 3.x! + except UnicodeEncodeError: continue + self.add_type(ctype, suffix, strict) + + def guess_type(url, strict=True): """Guess the type of a file based on its URL. @@ -295,6 +328,8 @@ inited = True db = MimeTypes() if files is None: + if _winreg: + db.read_registry() files = knownfiles for file in files: if os.path.isfile(file): --- trunk\Lib\test\test_mimetypes.py 2009-01-17 06:17:08.000000000 -0200 +++ src\Lib\test\test_mimetypes.py 2009-01-17 05:50:10.000000000 -0200 @@ -1,6 +1,7 @@ import mimetypes import StringIO import unittest +import sys from test import test_support @@ -62,9 +63,35 @@ eq(all, []) +class Win32MimeTypesTestCase(unittest.TestCase): + def setUp(self): + # ensure all entries actually come from the registry + self.original_types_map = mimetypes.types_map.copy() + mimetypes.types_map.clear() + mimetypes.init() + self.db = mimetypes.MimeTypes() + + def tearDown(self): + # restore default settings + mimetypes.types_map.clear() + mimetypes.types_map.update(self.original_types_map) + + def test_registry_parsing(self): + # the original, minimum contents of the MIME database in the + # Windows registry is undocumented AFAIK. + # Use file types that should *always* exist: + eq = self.assertEqual + eq(self.db.guess_type("foo.txt"), ("text/plain", None)) + +if sys.platform != 'win32': + class Win32MimeTypesTestCase(unittest.TestCase): + pass + def test_main(): - test_support.run_unittest(MimeTypesTestCase) + test_support.run_unittest(MimeTypesTestCase, + Win32MimeTypesTestCase + ) if __name__ == "__main__": test_main() --- trunk\Doc\library\mimetypes.rst 2009-01-17 06:18:09.000000000 -0200 +++ src\Doc\library\mimetypes.rst 2009-01-17 06:21:52.000000000 -0200 @@ -77,9 +77,10 @@ Initialize the internal data structures. If given, *files* must be a sequence of file names which should be used to augment the default type map. If omitted, - the file names to use are taken from :const:`knownfiles`. Each file named in - *files* or :const:`knownfiles` takes precedence over those named before it. - Calling :func:`init` repeatedly is allowed. + the file names to use are taken from :const:`knownfiles`; on Windows, the + current registry settings are loaded. Each file named in *files* or + :const:`knownfiles` takes precedence over those named before it. Calling + :func:`init` repeatedly is allowed. .. function:: read_mime_types(filename) @@ -230,3 +231,8 @@ Load MIME type information from an open file. The file must have the format of the standard :file:`mime.types` files. + +.. method:: MimeTypes.read_registry() + + Load MIME type information from the Windows registry. Availability: Windows. +