Improving MIME type detection for some common file types when they are missing from the system MIME database
Also allow the user to specify their own database via mime.types in the kitty config directory. See #3056
This commit is contained in:
parent
e160cbf32b
commit
75a94bcd96
@ -24,6 +24,9 @@ To update |kitty|, :doc:`follow the instructions <binary>`.
|
||||
- Fix selections created by dragging upwards not being auto-cleared when
|
||||
screen contents change (:pull:`3028`)
|
||||
|
||||
- Allow adding MIME definitions to kitty by placing a ``mime.types`` file in
|
||||
the kitty config directory (:iss:`3056`)
|
||||
|
||||
|
||||
0.19.1 [2020-10-06]
|
||||
-------------------
|
||||
|
||||
@ -81,7 +81,11 @@ lines. The various available criteria are:
|
||||
|
||||
``mime``
|
||||
A comma separated list of MIME types, for example: ``text/*, image/*,
|
||||
application/pdf``
|
||||
application/pdf``. You can add MIME types to kitty by creating the
|
||||
:file:`mime.types` in the kitty configuration directory. Useful if your
|
||||
system MIME database does not have definitions you need. This file is
|
||||
in the standard format of one definition per line, like: ``text/plain rst
|
||||
md``.
|
||||
|
||||
``ext``
|
||||
A comma separated list of file extensions, for example: ``jpeg, tar.gz``
|
||||
|
||||
@ -7,7 +7,7 @@ import re
|
||||
from contextlib import suppress
|
||||
from functools import lru_cache
|
||||
from hashlib import md5
|
||||
from mimetypes import guess_type
|
||||
from kitty.guess_mime_type import guess_type
|
||||
from typing import TYPE_CHECKING, Dict, List, Set, Optional, Iterator, Tuple, Union
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -136,7 +136,7 @@ def sanitize(text: str) -> str:
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
def mime_type_for_path(path: str) -> str:
|
||||
return guess_type(path)[0] or 'application/octet-stream'
|
||||
return guess_type(path) or 'application/octet-stream'
|
||||
|
||||
|
||||
@lru_cache(maxsize=1024)
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import contextlib
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
import socket
|
||||
@ -18,6 +17,7 @@ from typing import (
|
||||
Dict, Generator, List, NamedTuple, Optional, Pattern, Tuple, Union
|
||||
)
|
||||
|
||||
from kitty.guess_mime_type import guess_type
|
||||
from kitty.cli import parse_args
|
||||
from kitty.cli_stub import IcatCLIOptions
|
||||
from kitty.constants import appname
|
||||
@ -273,7 +273,7 @@ def process(path: str, args: IcatCLIOptions, parsed_opts: ParsedOpts, is_tempfil
|
||||
def scan(d: str) -> Generator[Tuple[str, str], None, None]:
|
||||
for dirpath, dirnames, filenames in os.walk(d):
|
||||
for f in filenames:
|
||||
mt = mimetypes.guess_type(f)[0]
|
||||
mt = guess_type(f)
|
||||
if mt and mt.startswith('image/'):
|
||||
yield os.path.join(dirpath, f), mt
|
||||
|
||||
|
||||
@ -394,10 +394,10 @@ def complete_files_and_dirs(
|
||||
|
||||
|
||||
def complete_icat_args(ans: Completions, opt: Optional[OptionDict], prefix: str, unknown_args: Delegate) -> None:
|
||||
from mimetypes import guess_type
|
||||
from .guess_mime_type import guess_type
|
||||
|
||||
def icat_file_predicate(filename: str) -> bool:
|
||||
mt = guess_type(filename)[0]
|
||||
mt = guess_type(filename)
|
||||
if mt and mt.startswith('image/'):
|
||||
return True
|
||||
return False
|
||||
|
||||
45
kitty/guess_mime_type.py
Normal file
45
kitty/guess_mime_type.py
Normal file
@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPLv3 Copyright: 2020, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import os
|
||||
from contextlib import suppress
|
||||
from typing import Optional
|
||||
|
||||
known_extensions = {
|
||||
'asciidoc': 'text/asciidoctor',
|
||||
'conf': 'text/config',
|
||||
'md': 'text/markdown',
|
||||
'pyj': 'text/rapydscript-ng',
|
||||
'recipe': 'text/python',
|
||||
'rst': 'text/restructured-text',
|
||||
'toml': 'text/toml',
|
||||
'vim': 'text/vim',
|
||||
'yaml': 'text/yaml',
|
||||
}
|
||||
|
||||
|
||||
def is_rc_file(path: str) -> bool:
|
||||
name = os.path.basename(path)
|
||||
return '.' not in name and name.endswith('rc')
|
||||
|
||||
|
||||
def guess_type(path: str) -> Optional[str]:
|
||||
if not hasattr(guess_type, 'inited'):
|
||||
setattr(guess_type, 'inited', True)
|
||||
from mimetypes import init
|
||||
init(None)
|
||||
from kitty.constants import config_dir
|
||||
local_defs = os.path.join(config_dir, 'mime.types')
|
||||
if os.path.exists(local_defs):
|
||||
init((local_defs,))
|
||||
from mimetypes import guess_type as stdlib_guess_type
|
||||
mt = None
|
||||
with suppress(Exception):
|
||||
mt = stdlib_guess_type(path)[0]
|
||||
if not mt:
|
||||
ext = path.rpartition('.')[-1].lower()
|
||||
mt = known_extensions.get(ext)
|
||||
if not mt and is_rc_file(path):
|
||||
mt = 'text/plain'
|
||||
return mt
|
||||
@ -17,6 +17,7 @@ from .config import KeyAction, parse_key_action
|
||||
from .constants import config_dir
|
||||
from .typing import MatchType
|
||||
from .utils import expandvars, log_error
|
||||
from .guess_mime_type import guess_type
|
||||
|
||||
|
||||
class MatchCriteria(NamedTuple):
|
||||
@ -75,12 +76,8 @@ def url_matches_criterion(purl: 'ParseResult', url: str, unquoted_path: str, mc:
|
||||
|
||||
if mc.type == 'mime':
|
||||
import fnmatch
|
||||
from mimetypes import guess_type
|
||||
try:
|
||||
mt = guess_type(unquoted_path)[0]
|
||||
except Exception:
|
||||
return False
|
||||
if mt is None:
|
||||
mt = guess_type(unquoted_path)
|
||||
if not mt:
|
||||
return False
|
||||
mt = mt.lower()
|
||||
for mpat in mc.value.split(','):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user