improves filetype detection

This commit is contained in:
tjpcc 2023-10-09 08:55:10 -06:00
parent 775c0c1040
commit 0386be537b
3 changed files with 64 additions and 2 deletions

View File

@ -2,7 +2,9 @@ package fs
import (
"mime"
"os"
"strings"
"unicode/utf8"
)
func mediaType(filePath string) string {
@ -21,6 +23,9 @@ func mediaType(filePath string) string {
mtype := mime.TypeByExtension(ext)
if mtype == "" {
if contentsAreText(filePath) {
return "text/plain"
}
return "application/octet-stream"
}
return mtype
@ -34,3 +39,28 @@ func isPrivate(fullpath string) bool {
}
return false
}
func contentsAreText(filepath string) bool {
f, err := os.Open(filepath)
if err != nil {
return false
}
defer func() { _ = f.Close() }()
var buf [1024]byte
n, err := f.Read(buf[:])
if err != nil {
return false
}
for i, c := range string(buf[:n]) {
if i+utf8.UTFMax > n {
// incomplete last char
break
}
if c == 0xFFFD || c < ' ' && c != '\n' && c != '\t' && c != '\f' {
return false
}
}
return true
}

View File

@ -185,7 +185,8 @@ func isFile(path string) (bool, error) {
}
func isMap(path string, settings gophermap.FileSystemSettings) bool {
if strings.HasSuffix(path, ".gophermap") {
base := filepath.Base(path)
if base == "gophermap" || strings.HasSuffix(base, ".gph") || strings.HasSuffix(base, ".gophermap") {
return true
}
return slices.Contains(settings.DirMaps, filepath.Base(path))

View File

@ -5,9 +5,11 @@ import (
"fmt"
"io"
"mime"
"os"
"path"
"strings"
"sync"
"unicode/utf8"
"tildegit.org/tjp/sliderule/internal/types"
)
@ -173,7 +175,7 @@ func GuessItemType(filepath string) types.Status {
case ".txt", ".gmi", ".md":
return TextFileType
case ".gif":
return GifFileType
return GifFileType
case ".png":
return PngImageFileType
case ".jpg", ".jpeg", ".tif", ".tiff":
@ -205,5 +207,34 @@ func GuessItemType(filepath string) types.Status {
return TextFileType
}
if contentsAreText(filepath) {
return TextFileType
}
return BinaryFileType
}
func contentsAreText(filepath string) bool {
f, err := os.Open(filepath)
if err != nil {
return false
}
defer func() { _ = f.Close() }()
var buf [1024]byte
n, err := f.Read(buf[:])
if err != nil {
return false
}
for i, c := range string(buf[:n]) {
if i+utf8.UTFMax > n {
// incomplete last char
break
}
if c == 0xFFFD || c < ' ' && c != '\n' && c != '\t' && c != '\f' {
return false
}
}
return true
}