Port full MIME type guessing to Go

This commit is contained in:
Kovid Goyal 2023-03-17 11:51:05 +05:30
parent 3c550bcd28
commit bf1f0c00f4
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 46 additions and 9 deletions

View File

@ -4,6 +4,7 @@
import bz2
import io
import json
import kitty.constants as kc
import os
import re
import struct
@ -13,27 +14,24 @@ import tarfile
from contextlib import contextmanager, suppress
from functools import lru_cache
from itertools import chain
from typing import Any, BinaryIO, Dict, Iterator, List, Optional, Sequence, Set, TextIO, Tuple, Union
import kitty.constants as kc
from kittens.tui.operations import Mode
from kittens.tui.spinners import spinners
from kitty.cli import (
CompletionSpec,
GoOption,
go_options_for_seq,
parse_option_spec,
CompletionSpec, GoOption, go_options_for_seq, parse_option_spec,
serialize_as_go_string,
)
from kitty.conf.generate import gen_go_code
from kitty.conf.types import Definition
from kitty.guess_mime_type import text_mimes
from kitty.guess_mime_type import known_extensions, text_mimes
from kitty.key_encoding import config_mod_map
from kitty.key_names import character_key_name_aliases, functional_key_name_aliases
from kitty.options.types import Options
from kitty.rc.base import RemoteCommand, all_command_names, command_for_name
from kitty.remote_control import global_options_spec
from kitty.rgb import color_names
from typing import (
Any, BinaryIO, Dict, Iterator, List, Optional, Sequence, Set, TextIO, Tuple, Union,
)
changed: List[str] = []
@ -673,6 +671,10 @@ def generate_textual_mimetypes() -> str:
for k in text_mimes:
ans.append(f' "{serialize_as_go_string(k)}": true,')
ans.append('}')
ans.append('var KnownExtensions = map[string]string{')
for k, v in known_extensions.items():
ans.append(f' ".{serialize_as_go_string(k)}": "{serialize_as_go_string(v)}",')
ans.append('}')
return '\n'.join(ans)

View File

@ -11,6 +11,8 @@ import (
"os"
"path/filepath"
"strings"
"golang.org/x/sys/unix"
)
var _ = fmt.Print
@ -52,6 +54,11 @@ var UserMimeMap = (&Once[map[string]string]{Run: func() map[string]string {
return ans
}}).Get
func is_rcfile(path string) bool {
name := filepath.Base(path)
return strings.HasSuffix(name, "rc") && !strings.Contains(name, ".")
}
func GuessMimeType(filename string) string {
ext := filepath.Ext(filename)
mime_with_parameters := UserMimeMap()[ext]
@ -62,7 +69,14 @@ func GuessMimeType(filename string) string {
only_once.Do(set_builtins)
mime_with_parameters = builtin_types_map[ext]
if mime_with_parameters == "" {
mime_with_parameters = builtin_types_map[strings.ToLower(ext)]
lext := strings.ToLower(ext)
mime_with_parameters = builtin_types_map[lext]
if mime_with_parameters == "" {
mime_with_parameters = KnownExtensions[lext]
}
if mime_with_parameters == "" && is_rcfile(filename) {
mime_with_parameters = "text/plain"
}
if mime_with_parameters == "" {
return ""
}
@ -74,3 +88,24 @@ func GuessMimeType(filename string) string {
}
return ans
}
func GuessMimeTypeWithFileSystemAccess(filename string) string {
is_dir, is_exe := false, false
s, err := os.Stat(filename)
if err == nil {
is_dir = s.IsDir()
if !is_dir && s.Mode().Perm()&0o111 != 0 && unix.Access(filename, unix.X_OK) == nil {
is_exe = true
}
}
if is_dir {
return "inode/directory"
}
mt := GuessMimeType(filename)
if mt == "" {
if is_exe {
mt = "inode/executable"
}
}
return mt
}