-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Fix an issue that native (Python and platform) MIME=>ext conversions are not patched. - Allow user config to overwrite the patch. - Patch mimetypes.init() to defer patching and improve the performance, and allow unittest mockings for the user config directory to work for the mimetypes module.
- Loading branch information
Showing
3 changed files
with
165 additions
and
56 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,103 @@ | ||
import mimetypes as _mimetypes | ||
import os | ||
from mimetypes import * | ||
|
||
from .. import Config | ||
|
||
__all__ = _mimetypes.__all__ | ||
WSB_USER_MIMETYPES = 'mime.types' | ||
|
||
|
||
def _patch_mimetypes(): | ||
patch_types_map = { | ||
# WebScrapBook related | ||
'.htz': 'application/html+zip', | ||
'.maff': 'application/x-maff', | ||
'.wsba': 'application/wsba+zip', | ||
|
||
# Some common types | ||
'.md': 'text/markdown', | ||
'.mkd': 'text/markdown', | ||
'.mkdn': 'text/markdown', | ||
'.mdwn': 'text/markdown', | ||
'.mdown': 'text/markdown', | ||
'.markdown': 'text/markdown', | ||
'.rss': 'application/rss+xml', | ||
'.atom': 'application/atom+xml', | ||
'.woff': 'font/woff', | ||
'.woff2': 'font/woff2', | ||
'.webp': 'image/webp', | ||
'.weba': 'audio/weba', | ||
'.webm': 'video/webm', | ||
'.oga': 'audio/ogg', | ||
'.ogv': 'video/ogg', | ||
'.ogx': 'application/ogg', # IANA | ||
'.ogg': 'application/ogg', # MAFF | ||
'.vtt': 'text/vtt', | ||
'.swf': 'application/x-shockwave-flash', # Apache, nginx, etc. | ||
'.jar': 'application/java-archive', | ||
'.class': 'application/java-vm', | ||
'.epub': 'application/epub+zip', | ||
'.7z': 'application/x-7z-compressed', | ||
'.rar': 'application/vnd.rar', | ||
|
||
# .js is mapped to application/javascript or application/x-javascript in some OS | ||
# ref: https://www.ietf.org/rfc/rfc9239.txt | ||
# text/javascript is mapped to .es in Debian 12 | ||
'.js': 'text/javascript', | ||
|
||
# .bmp is mapped to image/x-ms-bmp in Python < 3.11 | ||
# ref: https://github.com/python/cpython/issues/86194 | ||
'.bmp': 'image/bmp', | ||
|
||
# .ico is mapped to image/vnd.microsoft.icon in Python, | ||
# which is not actually used by Microsoft softwares and causes | ||
# a compatibility issue in IE9. | ||
# ref: https://en.wikipedia.org/wiki/ICO_%28file_format%29#MIME_type | ||
'.ico': 'image/x-icon', | ||
|
||
# .zip is mapped to application/x-zip-compressed in Windows | ||
'.zip': 'application/zip', | ||
} | ||
|
||
def patch_db(db): | ||
# apply the patch | ||
patch_types_map_inv = {} | ||
for ext, type in patch_types_map.items(): | ||
db.types_map[True][ext] = type | ||
patch_types_map_inv.setdefault(type, []).append(ext) | ||
for type, exts in patch_types_map_inv.items(): | ||
entry = db.types_map_inv[True].setdefault(type, []) | ||
for ext in exts: | ||
try: | ||
entry.remove(ext) | ||
except ValueError: | ||
pass | ||
entry[0:0] = exts | ||
|
||
# add custom user MIME types mapping | ||
_mimetypes.knownfiles += [os.path.join(Config.user_config_dir(), 'mime.types')] | ||
|
||
# WebScrapBook related | ||
_mimetypes.add_type('application/html+zip', '.htz') | ||
_mimetypes.add_type('application/x-maff', '.maff') | ||
_mimetypes.add_type('application/wsba+zip', '.wsba') | ||
|
||
# Some common types | ||
_mimetypes.add_type('text/markdown', '.md') | ||
_mimetypes.add_type('text/markdown', '.mkd') | ||
_mimetypes.add_type('text/markdown', '.mkdn') | ||
_mimetypes.add_type('text/markdown', '.mdwn') | ||
_mimetypes.add_type('text/markdown', '.mdown') | ||
_mimetypes.add_type('text/markdown', '.markdown') | ||
_mimetypes.add_type('application/rss+xml', '.rss') | ||
_mimetypes.add_type('application/atom+xml', '.atom') | ||
_mimetypes.add_type('font/woff', '.woff') | ||
_mimetypes.add_type('font/woff2', '.woff2') | ||
_mimetypes.add_type('image/webp', '.webp') | ||
_mimetypes.add_type('audio/weba', '.weba') | ||
_mimetypes.add_type('video/webm', '.webm') | ||
_mimetypes.add_type('audio/ogg', '.oga') | ||
_mimetypes.add_type('video/ogg', '.ogv') | ||
_mimetypes.add_type('application/ogg', '.ogx') # IANA | ||
_mimetypes.add_type('application/ogg', '.ogg') # MAFF | ||
_mimetypes.add_type('text/vtt', '.vtt') | ||
_mimetypes.add_type('application/x-shockwave-flash', '.swf') # Apache, nginx, etc. | ||
_mimetypes.add_type('application/java-archive', '.jar') | ||
_mimetypes.add_type('application/java-vm', '.class') | ||
_mimetypes.add_type('application/epub+zip', '.epub') | ||
_mimetypes.add_type('application/x-7z-compressed', '.7z') | ||
_mimetypes.add_type('application/vnd.rar', '.rar') | ||
|
||
# .js is mapped to application/javascript or application/x-javascript in some OS | ||
# ref: https://www.ietf.org/rfc/rfc9239.txt | ||
# text/javascript is mapped to .es in Debian 12 | ||
_mimetypes.add_type('text/javascript', '.js') | ||
|
||
# .bmp is mapped to image/x-ms-bmp in Python < 3.11 | ||
# ref: https://github.com/python/cpython/issues/86194 | ||
_mimetypes.add_type('image/bmp', '.bmp') | ||
|
||
# .ico is mapped to image/vnd.microsoft.icon in Python, | ||
# which is not actually used by Microsoft softwares and causes | ||
# a compatibility issue in IE9. | ||
# ref: https://en.wikipedia.org/wiki/ICO_%28file_format%29#MIME_type | ||
_mimetypes.add_type('image/x-icon', '.ico') | ||
|
||
# .zip is mapped to application/x-zip-compressed in Windows | ||
_mimetypes.add_type('application/zip', '.zip') | ||
# load user mappings | ||
for file in (os.path.join(Config.user_config_dir(), WSB_USER_MIMETYPES),): | ||
if os.path.isfile(file): | ||
db.read(file) | ||
|
||
if _mimetypes.inited: | ||
patch_db(_mimetypes._db) | ||
else: | ||
# patch init | ||
patched = False | ||
_init = _mimetypes.init | ||
|
||
def init(files=None): | ||
nonlocal patched | ||
_init(files) | ||
if not patched: | ||
patch_db(_mimetypes._db) | ||
patched = True | ||
|
||
_mimetypes.init = init | ||
|
||
|
||
_patch_mimetypes() | ||
|
||
# export all attributes | ||
from mimetypes import * # noqa: E402 | ||
|
||
__all__ = _mimetypes.__all__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters