Apply diff3.txt (plus additional documentation)
from SF patch http://www.python.org/sf/554192 This adds two new functions to mimetypes: guess_all_extensions() which returns a list of all known extensions for a mime type, and add_type() which adds one mapping between a mime type and an extension.
This commit is contained in:
parent
2c519981fb
commit
5ccaf8f129
|
@ -47,6 +47,20 @@ IANA types are supported; when \var{strict} is false, some additional
|
|||
non-standard but commonly used MIME types are also recognized.
|
||||
\end{funcdesc}
|
||||
|
||||
\begin{funcdesc}{guess_all_extensions}{type\optional{, strict}}
|
||||
Guess the extensions for a file based on its MIME type, given by
|
||||
\var{type}.
|
||||
The return value is a list of strings giving all possible filename extensions,
|
||||
including the leading dot (\character{.}). The extensions are not guaranteed
|
||||
to have been associated with any particular data stream, but would be mapped
|
||||
to the MIME type \var{type} by \function{guess_type()}. If no extension can
|
||||
be guessed for \var{type}, \code{None} is returned.
|
||||
|
||||
Optional \var{strict} has the same meaning as with the
|
||||
\function{guess_type()} function.
|
||||
\end{funcdesc}
|
||||
|
||||
|
||||
\begin{funcdesc}{guess_extension}{type\optional{, strict}}
|
||||
Guess the extension for a file based on its MIME type, given by
|
||||
\var{type}.
|
||||
|
@ -83,6 +97,17 @@ not exist or cannot be read, \code{None} is returned.
|
|||
\end{funcdesc}
|
||||
|
||||
|
||||
\begin{funcdesc}{add_type}{type, ext\optional{, strict}}
|
||||
Add a mapping from the mimetype \var{type} to the extension \var{ext}.
|
||||
When the extension is already known, the new type will replace the old
|
||||
one. When the type is already known the extension will be added
|
||||
to the list of known extensions.
|
||||
|
||||
When \var{strict} is the mapping will added to the official
|
||||
MIME types, otherwise to the non-standard ones.
|
||||
\end{funcdesc}
|
||||
|
||||
|
||||
\begin{datadesc}{inited}
|
||||
Flag indicating whether or not the global data structures have been
|
||||
initialized. This is set to true by \function{init()}.
|
||||
|
|
162
Lib/mimetypes.py
162
Lib/mimetypes.py
|
@ -26,16 +26,20 @@ import os
|
|||
import posixpath
|
||||
import urllib
|
||||
|
||||
__all__ = ["guess_type","guess_extension","read_mime_types","init"]
|
||||
__all__ = [
|
||||
"guess_type","guess_extension","guess_all_extensions",
|
||||
"add_type","read_mime_types","init"
|
||||
]
|
||||
|
||||
knownfiles = [
|
||||
"/etc/mime.types",
|
||||
"/usr/local/etc/httpd/conf/mime.types",
|
||||
"/usr/local/lib/netscape/mime.types",
|
||||
"/usr/local/etc/httpd/conf/mime.types", # Apache 1.2
|
||||
"/usr/local/etc/mime.types", # Apache 1.3
|
||||
]
|
||||
|
||||
inited = 0
|
||||
inited = False
|
||||
|
||||
|
||||
class MimeTypes:
|
||||
|
@ -46,17 +50,38 @@ class MimeTypes:
|
|||
URL, and can guess a reasonable extension given a MIME type.
|
||||
"""
|
||||
|
||||
def __init__(self, filenames=()):
|
||||
def __init__(self, filenames=(), strict=True):
|
||||
if not inited:
|
||||
init()
|
||||
self.encodings_map = encodings_map.copy()
|
||||
self.suffix_map = suffix_map.copy()
|
||||
self.types_map = types_map.copy()
|
||||
self.common_types = common_types.copy()
|
||||
self.types_map = ({}, {}) # dict for (non-strict, strict)
|
||||
self.types_map_inv = ({}, {})
|
||||
for (ext, type) in types_map.items():
|
||||
self.add_type(type, ext, True)
|
||||
for (ext, type) in common_types.items():
|
||||
self.add_type(type, ext, False)
|
||||
for name in filenames:
|
||||
self.read(name)
|
||||
self.read(name, strict)
|
||||
|
||||
def guess_type(self, url, strict=1):
|
||||
def add_type(self, type, ext, strict=True):
|
||||
"""Add a mapping between a type and and extension.
|
||||
|
||||
When the extension is already known, the new
|
||||
type will replace the old one. When the type
|
||||
is already known the extension will be added
|
||||
to the list of known extensions.
|
||||
|
||||
If strict is true, information will be added to
|
||||
list of standard types, else to the list of non-standard
|
||||
types.
|
||||
"""
|
||||
self.types_map[strict][ext] = type
|
||||
exts = self.types_map_inv[strict].setdefault(type, [])
|
||||
if ext not in exts:
|
||||
exts.append(ext)
|
||||
|
||||
def guess_type(self, url, strict=True):
|
||||
"""Guess the type of a file based on its URL.
|
||||
|
||||
Return value is a tuple (type, encoding) where type is None if
|
||||
|
@ -72,7 +97,7 @@ class MimeTypes:
|
|||
mapped to '.tar.gz'. (This is table-driven too, using the
|
||||
dictionary suffix_map.)
|
||||
|
||||
Optional `strict' argument when false adds a bunch of commonly found,
|
||||
Optional `strict' argument when False adds a bunch of commonly found,
|
||||
but non-standard types.
|
||||
"""
|
||||
scheme, url = urllib.splittype(url)
|
||||
|
@ -103,22 +128,44 @@ class MimeTypes:
|
|||
base, ext = posixpath.splitext(base)
|
||||
else:
|
||||
encoding = None
|
||||
types_map = self.types_map
|
||||
common_types = self.common_types
|
||||
types_map = self.types_map[True]
|
||||
if ext in types_map:
|
||||
return types_map[ext], encoding
|
||||
elif ext.lower() in types_map:
|
||||
return types_map[ext.lower()], encoding
|
||||
elif strict:
|
||||
return None, encoding
|
||||
elif ext in common_types:
|
||||
return common_types[ext], encoding
|
||||
elif ext.lower() in common_types:
|
||||
return common_types[ext.lower()], encoding
|
||||
types_map = self.types_map[False]
|
||||
if ext in types_map:
|
||||
return types_map[ext], encoding
|
||||
elif ext.lower() in types_map:
|
||||
return types_map[ext.lower()], encoding
|
||||
else:
|
||||
return None, encoding
|
||||
|
||||
def guess_extension(self, type, strict=1):
|
||||
def guess_all_extensions(self, type, strict=True):
|
||||
"""Guess the extensions for a file based on its MIME type.
|
||||
|
||||
Return value is a list of strings giving the possible filename
|
||||
extensions, including the leading dot ('.'). The extension is not
|
||||
guaranteed to have been associated with any particular data
|
||||
stream, but would be mapped to the MIME type `type' by
|
||||
guess_type(). If no extension can be guessed for `type', None
|
||||
is returned.
|
||||
|
||||
Optional `strict' argument when false adds a bunch of commonly found,
|
||||
but non-standard types.
|
||||
"""
|
||||
type = type.lower()
|
||||
extensions = self.types_map_inv[True].get(type, [])
|
||||
if not strict:
|
||||
for ext in self.types_map_inv[False].get(type, []):
|
||||
if ext not in extensions:
|
||||
extensions.append(ext)
|
||||
if len(extensions):
|
||||
return extensions
|
||||
|
||||
def guess_extension(self, type, strict=True):
|
||||
"""Guess the extension for a file based on its MIME type.
|
||||
|
||||
Return value is a string giving a filename extension,
|
||||
|
@ -131,25 +178,31 @@ class MimeTypes:
|
|||
Optional `strict' argument when false adds a bunch of commonly found,
|
||||
but non-standard types.
|
||||
"""
|
||||
type = type.lower()
|
||||
for ext, stype in self.types_map.items():
|
||||
if type == stype:
|
||||
return ext
|
||||
if not strict:
|
||||
for ext, stype in common_types.items():
|
||||
if type == stype:
|
||||
return ext
|
||||
return None
|
||||
extensions = self.guess_all_extensions(type, strict)
|
||||
if extensions is not None:
|
||||
extensions = extensions[0]
|
||||
return extensions
|
||||
|
||||
def read(self, filename):
|
||||
"""Read a single mime.types-format file, specified by pathname."""
|
||||
def read(self, filename, strict=True):
|
||||
"""
|
||||
Read a single mime.types-format file, specified by pathname.
|
||||
|
||||
If strict is true, information will be added to
|
||||
list of standard types, else to the list of non-standard
|
||||
types.
|
||||
"""
|
||||
fp = open(filename)
|
||||
self.readfp(fp)
|
||||
fp.close()
|
||||
|
||||
def readfp(self, fp):
|
||||
"""Read a single mime.types-format file."""
|
||||
map = self.types_map
|
||||
def readfp(self, fp, strict=True):
|
||||
"""
|
||||
Read a single mime.types-format file.
|
||||
|
||||
If strict is true, information will be added to
|
||||
list of standard types, else to the list of non-standard
|
||||
types.
|
||||
"""
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
|
@ -162,11 +215,11 @@ class MimeTypes:
|
|||
if not words:
|
||||
continue
|
||||
type, suffixes = words[0], words[1:]
|
||||
suffixes = [ '.' + suff for suff in suffixes ]
|
||||
for suff in suffixes:
|
||||
map['.' + suff] = type
|
||||
self.add_type(type, suff, strict)
|
||||
|
||||
|
||||
def guess_type(url, strict=1):
|
||||
def guess_type(url, strict=True):
|
||||
"""Guess the type of a file based on its URL.
|
||||
|
||||
Return value is a tuple (type, encoding) where type is None if the
|
||||
|
@ -188,7 +241,23 @@ def guess_type(url, strict=1):
|
|||
return guess_type(url, strict)
|
||||
|
||||
|
||||
def guess_extension(type, strict=1):
|
||||
def guess_all_extensions(type, strict=True):
|
||||
"""Guess the extensions for a file based on its MIME type.
|
||||
|
||||
Return value is a list of strings giving the possible filename
|
||||
extensions, including the leading dot ('.'). The extension is not
|
||||
guaranteed to have been associated with any particular data
|
||||
stream, but would be mapped to the MIME type `type' by
|
||||
guess_type(). If no extension can be guessed for `type', None
|
||||
is returned.
|
||||
|
||||
Optional `strict' argument when false adds a bunch of commonly found,
|
||||
but non-standard types.
|
||||
"""
|
||||
init()
|
||||
return guess_all_extensions(type, strict)
|
||||
|
||||
def guess_extension(type, strict=True):
|
||||
"""Guess the extension for a file based on its MIME type.
|
||||
|
||||
Return value is a string giving a filename extension, including the
|
||||
|
@ -203,12 +272,27 @@ def guess_extension(type, strict=1):
|
|||
init()
|
||||
return guess_extension(type, strict)
|
||||
|
||||
def add_type(self, type, ext, strict=True):
|
||||
"""Add a mapping between a type and and extension.
|
||||
|
||||
When the extension is already known, the new
|
||||
type will replace the old one. When the type
|
||||
is already known the extension will be added
|
||||
to the list of known extensions.
|
||||
|
||||
If strict is true, information will be added to
|
||||
list of standard types, else to the list of non-standard
|
||||
types.
|
||||
"""
|
||||
init()
|
||||
return add_type(type, ext, strict)
|
||||
|
||||
|
||||
def init(files=None):
|
||||
global guess_extension, guess_type
|
||||
global guess_all_extensions, guess_extension, guess_type
|
||||
global suffix_map, types_map, encodings_map, common_types
|
||||
global inited
|
||||
inited = 1
|
||||
global add_type, inited
|
||||
inited = True
|
||||
db = MimeTypes()
|
||||
if files is None:
|
||||
files = knownfiles
|
||||
|
@ -217,10 +301,12 @@ def init(files=None):
|
|||
db.readfp(open(file))
|
||||
encodings_map = db.encodings_map
|
||||
suffix_map = db.suffix_map
|
||||
types_map = db.types_map
|
||||
types_map = db.types_map[True]
|
||||
guess_all_extensions = db.guess_all_extensions
|
||||
guess_extension = db.guess_extension
|
||||
guess_type = db.guess_type
|
||||
common_types = db.common_types
|
||||
add_type = db.add_type
|
||||
common_types = db.types_map[False]
|
||||
|
||||
|
||||
def read_mime_types(file):
|
||||
|
|
|
@ -321,6 +321,11 @@ Extension modules
|
|||
|
||||
Library
|
||||
|
||||
- mimetypes has two new functions: guess_all_extensions() which
|
||||
returns a list of all known extensions for a mime type, and
|
||||
add_type() which adds one mapping between a mime type and
|
||||
an extension to the database.
|
||||
|
||||
- New module: sets, defines the class Set that implements a mutable
|
||||
set type using the keys of a dict to represent the set. There's
|
||||
also a class ImmutableSet which is useful when you need sets of sets
|
||||
|
|
Loading…
Reference in New Issue