fileutil

package
v0.0.64 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 15, 2026 License: MPL-2.0 Imports: 20 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultImageMIME = MIMEImagePNG
View Source
const MaxTotalWalkFiles = 256

Variables

View Source
var (
	ErrInvalidPath      = errors.New("invalid path")
	ErrUnknownExtension = errors.New("unknown extension")
)
View Source
var (
	FileFilterAllFiles = FileFilter{
		DisplayName: "All Files",
		Extensions:  nil,
	}

	FileFilterTextMarkdown = FileFilter{
		DisplayName: "Text",
		Extensions:  ModeToExtensions[ExtensionModeText],
	}

	FileFilterDocuments = FileFilter{
		DisplayName: "Documents",
		Extensions:  ModeToExtensions[ExtensionModeDocument],
	}

	FileFilterImages = FileFilter{
		DisplayName: "Images",
		Extensions:  ModeToExtensions[ExtensionModeImage],
	}

	DefaultFileFilters = []FileFilter{
		FileFilterAllFiles,
		FileFilterTextMarkdown,
		FileFilterDocuments,
		FileFilterImages,
	}
)
View Source
var ModeToExtensions = func() map[ExtensionMode][]FileExt {
	m := make(map[ExtensionMode][]FileExt, len(AllExtensionModes))

	for ext, mimeType := range ExtensionToMIMEType {
		if mode, ok := MIMETypeToExtensionMode[mimeType]; ok {
			m[mode] = append(m[mode], ext)
		} else {
			m[ExtensionModeDefault] = append(m[ExtensionModeDefault], ext)
		}
	}
	return m
}()

Functions

func ExtractPDFTextFromBytesSafe

func ExtractPDFTextFromBytesSafe(data []byte, maxBytes int) (text string, err error)

ExtractPDFTextFromBytesSafe extracts text from in-memory PDF bytes with a byte limit and panic recovery. It mirrors extractPDFTextSafe but is backed by an in-memory reader instead of a file on disk.

func ExtractPDFTextSafe

func ExtractPDFTextSafe(path string, maxBytes int) (text string, err error)

ExtractPDFTextSafe extracts text from a local PDF with a byte limit and panic recovery.

func ListDirectory

func ListDirectory(path, pattern string) ([]string, error)

ListDirectory lists files/dirs in path (default "."), pattern is an optional glob filter (filepath.Match).

func MIMEForLocalFile

func MIMEForLocalFile(path string) (mimeType MIMEType, mode ExtensionMode, err error)

MIMEForLocalFile returns a best-effort MIME type, it tries to see if extension based mime can be detected. If not, it tries to sniff mime using magic bits from file.

func ReadFile

func ReadFile(path string, encoding ReadEncoding) (string, error)

ReadFile reads a file and returns its contents. encoding: "text" (default) or "binary" (base64-encoded output).

func SearchFiles

func SearchFiles(root, pattern string, maxResults int) ([]string, error)

SearchFiles walks root (default ".") recursively and returns up to maxResults files whose *path* or UTF-8 text content* match the regexp pattern. If maxResults <= 0, it is treated as "no limit".

func SniffFileMIME

func SniffFileMIME(path string) (mimeType MIMEType, mode ExtensionMode, err error)

SniffFileMIME inspects the first bytes of a file and returns a best-effort MIME type plus a coarse-grained mode (text, image, document, or default).

It uses net/http.DetectContentType and a simple heuristic to decide whether the content is probably text vs binary (NUL bytes, control chars, etc.).

Types

type DirectoryOverflowInfo

type DirectoryOverflowInfo struct {
	DirPath      string `json:"dirPath"`
	RelativePath string `json:"relativePath"`
	FileCount    int    `json:"fileCount"`
	Partial      bool   `json:"partial"`
}

DirectoryOverflowInfo represents a directory that was *not fully walked* because we hit the max-files limit or had an error.

Semantics:

  • DirPath / RelativePath: Absolute / relative-to-root path of that directory.
  • FileCount: For completely unvisited dirs (left in the BFS queue):
  • number of direct entries (files + subdirs) from a single os.ReadDir, no recursion. For the single "partial" dir where we hit the limit mid-scan:
  • number of remaining entries in that directory (files + subdirs) that we did NOT process. This is *approximate UI sugar*, not a full subtree count.
  • Partial: true only for the directory where we stopped in the middle of its entries because maxFiles was reached. For all other overflow dirs it's false.

type ExtensionMode

type ExtensionMode string
const (
	ExtensionModeText     ExtensionMode = "text"
	ExtensionModeImage    ExtensionMode = "image"
	ExtensionModeDocument ExtensionMode = "document"
	ExtensionModeDefault  ExtensionMode = "default"
)

type FileExt

type FileExt string
const (
	ExtTxt      FileExt = ".txt"
	ExtMd       FileExt = ".md"
	ExtMarkdown FileExt = ".markdown"
	ExtLog      FileExt = ".log"
	ExtJSON     FileExt = ".json"
	ExtYAML     FileExt = ".yaml"
	ExtYML      FileExt = ".yml"
	ExtTOML     FileExt = ".toml"
	ExtJS       FileExt = ".js"
	ExtTS       FileExt = ".ts"
	ExtTSX      FileExt = ".tsx"
	ExtJSX      FileExt = ".jsx"
	ExtPY       FileExt = ".py"
	ExtGO       FileExt = ".go"
	ExtRS       FileExt = ".rs"
	ExtJAVA     FileExt = ".java"
	ExtC        FileExt = ".c"
	ExtCPP      FileExt = ".cpp"
	ExtH        FileExt = ".h"
	ExtHPP      FileExt = ".hpp"
	ExtCS       FileExt = ".cs"
	ExtRB       FileExt = ".rb"
	ExtPHP      FileExt = ".php"
	ExtHTML     FileExt = ".html"
	ExtHTM      FileExt = ".htm"
	ExtCSS      FileExt = ".css"
	ExtSCSS     FileExt = ".scss"
	ExtLESS     FileExt = ".less"
	ExtSQL      FileExt = ".sql"
	ExtMod      FileExt = ".mod"
	ExtSum      FileExt = ".sum"
	ExtJSONL    FileExt = ".jsonl"
	ExtShell    FileExt = ".sh"
	ExtSWIFT    FileExt = ".swift"
	ExtM        FileExt = ".m"
	ExtKT       FileExt = ".kt"
	ExtPL       FileExt = ".pl"
	ExtSCALA    FileExt = ".scala"
	ExtHS       FileExt = ".hs"
	ExtLUA      FileExt = ".lua"
	ExtDART     FileExt = ".dart"

	ExtJPG  FileExt = ".jpg"
	ExtJPEG FileExt = ".jpeg"
	ExtPNG  FileExt = ".png"
	ExtGIF  FileExt = ".gif"
	ExtWEBP FileExt = ".webp"
	ExtBMP  FileExt = ".bmp"
	ExtSVG  FileExt = ".svg"

	ExtPDF  FileExt = ".pdf"
	ExtDOC  FileExt = ".doc"
	ExtDOCX FileExt = ".docx"
	ExtPPT  FileExt = ".ppt"
	ExtPPTX FileExt = ".pptx"
	ExtXLS  FileExt = ".xls"
	ExtXLSX FileExt = ".xlsx"
	ExtODT  FileExt = ".odt"
	ExtODS  FileExt = ".ods"
)

type FileFilter

type FileFilter struct {
	DisplayName string
	Extensions  []FileExt // normalized, e.g. ".png".
}

FileFilter is used to build file dialog filters (Patterns like "*.png;*.jpg").

func (FileFilter) Pattern

func (f FileFilter) Pattern() string

Pattern converts a FileFilter into a semicolon-separated pattern string. W.g. "*.png;*.jpg".

type ImageData

type ImageData struct {
	ImageInfo

	Base64Data string `json:"base64Data,omitempty"` // optional, if requested
}

ImageData holds metadata (and optionally content) for an image file.

func ReadImage

func ReadImage(
	path string,
	includeBase64Data bool,
) (*ImageData, error)

ReadImage inspects an image file and returns its intrinsic metadata. If includeBase64 is true, Base64Data will contain the base64-encoded file contents. If the file does not exist, Exists == false and err == nil. Returns an error if the path is empty, a directory, or not a supported image.

type ImageInfo

type ImageInfo struct {
	PathInfo

	Width    int      `json:"width,omitempty"`
	Height   int      `json:"height,omitempty"`
	Format   string   `json:"format,omitempty"`   // e.g. "jpeg", "png"
	MIMEType MIMEType `json:"mimeType,omitempty"` // e.g. "image/jpeg"
}

type MIMEType

type MIMEType string
const (
	MIMEEmpty                  MIMEType = ""
	MIMEApplicationOctetStream MIMEType = "application/octet-stream"

	MIMETextPlain       MIMEType = "text/plain; charset=utf-8"
	MIMETextMarkdown    MIMEType = "text/markdown; charset=utf-8"
	MIMETextHTML        MIMEType = "text/html; charset=utf-8"
	MIMETextCSS         MIMEType = "text/css; charset=utf-8"
	MIMEApplicationJSON MIMEType = "application/json"
	MIMEApplicationYAML MIMEType = "application/x-yaml"
	MIMEApplicationTOML MIMEType = "application/toml"
	MIMEApplicationSQL  MIMEType = "application/sql"
	MIMEApplicationJS   MIMEType = "application/javascript"

	MIMEImageJPEG MIMEType = "image/jpeg"
	MIMEImagePNG  MIMEType = "image/png"
	MIMEImageGIF  MIMEType = "image/gif"
	MIMEImageWEBP MIMEType = "image/webp"
	MIMEImageBMP  MIMEType = "image/bmp"
	MIMEImageSVG  MIMEType = "image/svg+xml"

	MIMEApplicationPDF        MIMEType = "application/pdf"
	MIMEApplicationMSWord     MIMEType = "application/msword"
	MIMEApplicationMSPowerPt  MIMEType = "application/vnd.ms-powerpoint"
	MIMEApplicationMSExcel    MIMEType = "application/vnd.ms-excel"
	MIMEApplicationOpenXMLDoc MIMEType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
	MIMEApplicationOpenXMLPPT MIMEType = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
	MIMEApplicationOpenXMLXLS MIMEType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
	MIMEApplicationODT        MIMEType = "application/vnd.oasis.opendocument.text"
	MIMEApplicationODS        MIMEType = "application/vnd.oasis.opendocument.spreadsheet"
)

func MIMEFromExtensionString

func MIMEFromExtensionString(ext string) (mimeType MIMEType, err error)

MIMEFromExtensionString returns the best-known MIME for a given extension string. Lookup order is: internal registry -> mime.TypeByExtension. If the extension cannot be resolved, it returns MIMEApplicationOctetStream and ErrUnknownExtension.

type PathInfo

type PathInfo struct {
	Path    string     `json:"path"`
	Name    string     `json:"name"`
	Exists  bool       `json:"exists"`
	IsDir   bool       `json:"isDir"`
	Size    int64      `json:"size,omitempty"`
	ModTime *time.Time `json:"modTime,omitempty"`
}

func StatPath

func StatPath(path string) (pathInfo *PathInfo, err error)

StatPath returns basic metadata for the supplied path without mutating the filesystem. If the path does not exist, exists == false and err == nil.

type ReadEncoding

type ReadEncoding string
const (
	ReadEncodingText   ReadEncoding = "text"
	ReadEncodingBinary ReadEncoding = "binary"
)

type WalkDirectoryWithFilesResult

type WalkDirectoryWithFilesResult struct {
	DirPath      string                  `json:"dirPath"`
	Files        []PathInfo              `json:"files"`        // included files (flattened)
	OverflowDirs []DirectoryOverflowInfo `json:"overflowDirs"` // directories not fully included
	MaxFiles     int                     `json:"maxFiles"`     // max number of files returned (after clamping)
	TotalSize    int64                   `json:"totalSize"`    // sum of Files[i].Size
	HasMore      bool                    `json:"hasMore"`      // true if not all content included
}

WalkDirectoryWithFilesResult is returned when user selects a directory.

func WalkDirectoryWithFiles

func WalkDirectoryWithFiles(ctx context.Context, dirPath string, maxFiles int) (*WalkDirectoryWithFilesResult, error)

WalkDirectoryWithFiles implements:

  • Pure BFS over the directory tree starting at dirPath.
  • For each directory:
  • process all regular, non-dot files first (highest priority), adding them to Files until maxFiles is reached.
  • then enqueue its subdirectories for BFS.
  • As soon as Files reaches maxFiles, walking stops.
  • Remaining directories in the BFS queue are returned as OverflowDirs, with a shallow os.ReadDir() to get a one-level item count.
  • The directory where we actually hit the limit (if any) is also listed as an overflow entry with Partial = true and a count of remaining items (files + subdirs) in that directory.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL