89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"slices"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
type fsEntry struct {
|
|
Name string `json:"name"`
|
|
Path string `json:"path"`
|
|
Dir bool `json:"dir"`
|
|
Size int64 `json:"size"`
|
|
Mod int64 `json:"mod"`
|
|
}
|
|
|
|
// handleFSList backs the built-in file browser (used when no native file
|
|
// dialog is available).
|
|
func (a *App) handleFSList(w http.ResponseWriter, r *http.Request) {
|
|
q := r.URL.Query()
|
|
dir := strings.TrimSpace(q.Get("path"))
|
|
showAll := q.Get("all") == "1"
|
|
home, _ := os.UserHomeDir()
|
|
if dir == "" {
|
|
dir = home
|
|
if v := filepath.Join(home, "Videos"); isDir(v) {
|
|
dir = v
|
|
}
|
|
}
|
|
dir, _ = filepath.Abs(dir)
|
|
if st, err := os.Stat(dir); err == nil && !st.IsDir() {
|
|
dir = filepath.Dir(dir)
|
|
}
|
|
des, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
writeError(w, http.StatusBadRequest, "cannot open folder: "+err.Error())
|
|
return
|
|
}
|
|
entries := []fsEntry{}
|
|
for _, de := range des {
|
|
name := de.Name()
|
|
if strings.HasPrefix(name, ".") || strings.Contains(name, ".vibedit-part") {
|
|
continue
|
|
}
|
|
info, err := de.Info()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
isD := info.IsDir()
|
|
if !isD && info.Mode()&os.ModeSymlink != 0 {
|
|
if st, err := os.Stat(filepath.Join(dir, name)); err == nil {
|
|
isD, info = st.IsDir(), st
|
|
}
|
|
}
|
|
if !isD && !showAll {
|
|
ext := strings.ToLower(strings.TrimPrefix(filepath.Ext(name), "."))
|
|
if !slices.Contains(mediaExts, ext) {
|
|
continue
|
|
}
|
|
}
|
|
entries = append(entries, fsEntry{Name: name, Path: filepath.Join(dir, name), Dir: isD, Size: info.Size(), Mod: info.ModTime().Unix()})
|
|
}
|
|
sort.Slice(entries, func(i, j int) bool {
|
|
if entries[i].Dir != entries[j].Dir {
|
|
return entries[i].Dir
|
|
}
|
|
return strings.ToLower(entries[i].Name) < strings.ToLower(entries[j].Name)
|
|
})
|
|
parent := filepath.Dir(dir)
|
|
if parent == dir {
|
|
parent = ""
|
|
}
|
|
writeJSON(w, map[string]any{
|
|
"path": dir,
|
|
"parent": parent,
|
|
"entries": entries,
|
|
"roots": listRoots(),
|
|
"home": home,
|
|
})
|
|
}
|
|
|
|
func isDir(p string) bool {
|
|
st, err := os.Stat(p)
|
|
return err == nil && st.IsDir()
|
|
}
|