此包提供了一个从文件名和/或实际内容猜测MIME类型的实用程序。它基于freedesktop.org的shared-mime-info数据库。
shared-mime-info是一个可扩展的常见MIME类型数据库。它提供强大的MIME类型检测机制以及多语言类型描述。
此包需要已安装并可供访问的shared-mime-info。最简单的方法是在系统范围内安装它,例如在Ubuntu上安装shared-mime-info包。规范还描述了其他安装和扩展数据库的方法。
请注意,此包当前不是线程安全的,因为数据只应在模块导入时加载一次。如果因此出现任何问题,将来可能会进行更改。
使用此包的最简单方法是导入根模块中的getType函数
>>> from z3c.sharedmimeinfo import getType
此函数尝试猜测shared-mime-info规范文档中指定的MIME类型,并始终返回一些可用的MIME类型,使用application/octet-stream或text/plain作为后备。它可以通过文件名、其内容或两者来检测MIME类型,因此接受两个参数:文件名(字符串)和/或文件(类似于文件的对象)。至少应提供其中之一。
如上所述,它至少需要一个参数,因此您不能不带参数调用它
>>> getType()
Traceback (most recent call last):
...
TypeError: Either filename or file should be provided or both of them
通过filename参数传递文件名
>>> print getType(filename='document.doc')
application/msword
通过file参数传递文件内容,该参数接受类似于文件的对象。让我们使用我们的测试辅助函数打开一个示例文件并尝试猜测其类型
>>> print getType(file=openSample('png'))
image/png
如果无法检测到MIME类型,则返回text/plain或application/octet-stream。函数将尝试通过检查前32个字节来猜测是文本还是二进制
>>> print getType(filename='somefile', file=openSample('text'))
text/plain
>>> print getType(filename='somefile', file=openSample('binary'))
application/octet-stream
由 getType 和其他函数(见下文)返回的对象实际上是扩展的 Unicode 字符串对象,提供有关 MIME 类型的额外信息。它们提供 IMIMEType 接口
>>> from zope.interface.verify import verifyObject
>>> from z3c.sharedmimeinfo.interfaces import IMIMEType
>>> mt = getType(filename='document.doc')
>>> verifyObject(IMIMEType, mt)
True
由于它们实际上是 Unicode 对象,因此可以像字符串一样进行比较
>>> mt == 'application/msword'
True
它们还提供了 media 和 subtype 属性
>>> mt.media
u'application'
>>> mt.subtype
u'msword'
最后,它们提供了 title 属性,它是一个可翻译的消息
>>> mt.title
u'application/msword'
>>> from zope.i18nmessageid.message import Message
>>> isinstance(mt.title, Message)
True
让我们检查共享-mime-info附带并受此包支持的 i18n 功能。如上所述,MIME 类型标题消息 ID 实际上是其 <media>/<subtype>,但如果我们将其翻译,我们将得到一个友好的字符串
>>> from zope.i18n import translate
>>> translate(mt.title)
u'Word document'
>>> translate(mt.title, target_language='ru')
u'\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442 Word'
>>> from z3c.sharedmimeinfo.mimetype import MIMEType
我们也可以使用 MIMEType 类手动创建 IMIMEType 对象
>>> from z3c.sharedmimeinfo.mimetype import MIMEType
我们可以通过两个参数指定媒体和子类型,或者以“media/subtype”形式作为单个参数创建它们
>>> MIMEType('text/plain')
<MIMEType text/plain>
>>> MIMEType('image', 'png')
<MIMEType image/png>
注意,MIMEType 对象是缓存的,因此如果您为相同的 MIME 类型创建另一个对象,您将获得相同的对象
>>> mt = MIMEType('text/plain')
>>> mt2 = MIMEType('text/plain')
>>> mt2 is mt
True
上面描述的 getType 函数实际上是 IMIMETypesUtility 对象的方法。IMIMETypesUtility 是猜测 MIME 类型的核心组件。
让我们直接导入实用工具并与之互动
>>> from z3c.sharedmimeinfo.utility import mimeTypesUtility
>>> from z3c.sharedmimeinfo.interfaces import IMIMETypesUtility
>>> verifyObject(IMIMETypesUtility, mimeTypesUtility)
True
它有三种获取 MIME 类型的方法。这三种方法是 getType(如上所述)、getTypeByFileName 和 getTypeByContents。
MIME 类型实用工具的 getTypeByFileName 方法通过文件名查找类型
>>> mt = mimeTypesUtility.getTypeByFileName('example.doc')
shared-mime-info 数据库非常棒,它甚至可以检测类似于 Makefile 的文件名
>>> print mimeTypesUtility.getTypeByFileName('Makefile')
text/x-makefile
此外,它知道扩展名字母大小写之间的区别。例如,当 .c 是纯 C 文件时,应将 .C 检测为 C++ 文件
>>> print mimeTypesUtility.getTypeByFileName('hello.C')
text/x-c++src
>>> print mimeTypesUtility.getTypeByFileName('main.c')
text/x-csrc
如果它无法从文件名确定类型,则方法将返回 None
>>> print mimeTypesUtility.getTypeByFileName('somefilename')
None
getTypeByContents 方法接受一个文件对象和两个可选参数:min_priority 和 max_priority,可以用来指定要使用的“魔术”规则的范围。默认情况下,min_priority 是 0,max_priority 是 100,因此将使用所有规则。有关详细信息,请参阅 shared-mime-info 规范。
我们有一些应该通过内容检测的示例文件
>>> fdoc = openSample('doc')
>>> print mimeTypesUtility.getTypeByContents(fdoc)
application/msword
>>> fhtml = openSample('html')
>>> print mimeTypesUtility.getTypeByContents(fhtml)
text/html
>>> fpdf = openSample('pdf')
>>> print mimeTypesUtility.getTypeByContents(fpdf)
application/pdf
>>> fpng = openSample('png')
>>> print mimeTypesUtility.getTypeByContents(fpng)
image/png
如果我们传递没有已知魔术字节的文件,它将返回 None
>>> funknown = openSample('binary')
>>> print mimeTypesUtility.getTypeByContents(funknown)
None
>>> del fdoc, fhtml, fpdf, fpng, funknown